Skip to content

Commit 2570606

Browse files
committed
Add new me_compile_chunk() and me_variable struct sanitized
1 parent 9cbeaca commit 2570606

25 files changed

Lines changed: 578 additions & 310 deletions

CODE_QUALITY.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Code Quality Tools
2+
3+
## Setup (For Contributors)
4+
5+
After cloning the repository, install the Git hooks:
6+
7+
```bash
8+
./scripts/install-hooks.sh
9+
```
10+
11+
This will install the pre-commit hook that checks for trailing whitespace.
12+
13+
## Trailing Whitespace
14+
15+
Trailing whitespace is automatically prevented by the pre-commit hook and can be checked/fixed using the provided tools.
16+
17+
### Pre-commit Hook
18+
19+
The Git pre-commit hook automatically checks for trailing whitespace before each commit.
20+
21+
**First-time setup:**
22+
```bash
23+
./scripts/install-hooks.sh
24+
```
25+
26+
If trailing whitespace is detected, the commit will be blocked with instructions on how to fix it.
27+
28+
To bypass the check (not recommended):
29+
```bash
30+
git commit --no-verify
31+
```
32+
33+
### Manual Checking
34+
35+
Check for trailing whitespace:
36+
```bash
37+
make check-whitespace
38+
# or
39+
./check-whitespace.sh
40+
```
41+
42+
Fix trailing whitespace:
43+
```bash
44+
make fix-whitespace
45+
# or
46+
./check-whitespace.sh --fix
47+
```
48+
49+
### Files Checked
50+
51+
The tools check these file types:
52+
- `*.c` - C source files
53+
- `*.h` - C header files
54+
- `*.md` - Markdown documentation
55+
56+
Build artifacts in `build/` and `.git/` are excluded.
57+
58+
### CI Integration
59+
60+
Add to your CI pipeline:
61+
```yaml
62+
- name: Check trailing whitespace
63+
run: make check-whitespace
64+
```

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,11 @@ clean:
9898
# Pattern rule for object files (if needed for future extensions)
9999
$(BUILDDIR)/%.o: $(SRCDIR)/%.c $(LIB_HDR) | $(BUILDDIR)
100100
$(CC) $(CFLAGS) -c $< -o $@
101+
102+
# Check for trailing whitespace
103+
check-whitespace:
104+
@./check-whitespace.sh
105+
106+
# Fix trailing whitespace
107+
fix-whitespace:
108+
@./check-whitespace.sh --fix

README.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,39 @@ miniexpr is designed to be embedded directly into larger projects, not distribut
1515

1616
### `me_compile()`
1717
```c
18-
me_expr *me_compile(const char *expression, const me_variable *variables,
19-
int var_count, void *output, int nitems,
18+
me_expr *me_compile(const char *expression, const me_variable *variables,
19+
int var_count, void *output, int nitems,
2020
me_dtype dtype, int *error);
2121
```
2222
Parses an expression string and creates a compiled expression tree. Variables are bound at compile time. Returns `NULL` on error.
2323
24+
### `me_compile_chunk()`
25+
```c
26+
me_expr *me_compile_chunk(const char *expression, const me_variable *variables,
27+
int var_count, me_dtype dtype, int *error);
28+
```
29+
Compiles an expression for chunked evaluation. This variant is optimized for use with `me_eval_chunk()` and `me_eval_chunk_threadsafe()`, where variable and output pointers are provided during evaluation rather than compilation.
30+
31+
**Simple Usage**: Just provide variable names - everything else is optional:
32+
33+
```c
34+
me_variable vars[] = {{"x"}, {"y"}}; // Just the names!
35+
me_expr *expr = me_compile_chunk("x + y", vars, 2, ME_FLOAT64, &err);
36+
37+
// Later, provide data in the same order as vars array
38+
const void *data[] = {x_array, y_array}; // x first, y second
39+
me_eval_chunk(expr, data, 2, output, nitems);
40+
```
41+
42+
For mixed types:
43+
```c
44+
me_variable vars[] = {{"temp", ME_FLOAT64}, {"count", ME_INT32}};
45+
```
46+
47+
Variables are matched by position (order) in the arrays. Unspecified fields (address, type, context) default to NULL/0.
48+
49+
Returns `NULL` on error.
50+
2451
### `me_eval()`
2552
```c
2653
void me_eval(const me_expr *n);
@@ -74,6 +101,18 @@ To use miniexpr in your project, simply include the source files (`miniexpr.c` a
74101

75102
For examples and detailed usage, see the [Getting Started Guide](doc/get-started.md).
76103

104+
## Contributing
105+
106+
After cloning the repository, install the Git hooks:
107+
108+
```bash
109+
./scripts/install-hooks.sh
110+
```
111+
112+
This sets up automatic checks for code quality (e.g., trailing whitespace).
113+
114+
See [CODE_QUALITY.md](CODE_QUALITY.md) for more details on code quality tools.
115+
77116
## License
78117

79118
BSD 3-Clause License. See [LICENSE](LICENSE) for details.

bench/benchmark_all_types.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ int main() {
2929
int32_t *result = malloc(n * sizeof(int32_t));
3030
for (int i = 0; i < n; i++) a[i] = i;
3131

32-
me_variable vars[] = {{"a", a}};
32+
me_variable vars[] = {{"a", ME_INT32, a}};
3333
int err;
3434
me_expr *expr = me_compile("a+5", vars, 1, result, n, ME_INT32, &err);
3535

@@ -51,7 +51,7 @@ int main() {
5151
uint64_t *result = malloc(n * sizeof(uint64_t));
5252
for (int i = 0; i < n; i++) a[i] = i;
5353

54-
me_variable vars[] = {{"a", a}};
54+
me_variable vars[] = {{"a", ME_INT32, a}};
5555
int err;
5656
me_expr *expr = me_compile("a+5", vars, 1, result, n, ME_UINT64, &err);
5757

@@ -73,7 +73,7 @@ int main() {
7373
float *result = malloc(n * sizeof(float));
7474
for (int i = 0; i < n; i++) a[i] = i * 0.1f;
7575

76-
me_variable vars[] = {{"a", a}};
76+
me_variable vars[] = {{"a", ME_INT32, a}};
7777
int err;
7878
me_expr *expr = me_compile("a+5", vars, 1, result, n, ME_FLOAT32, &err);
7979

@@ -95,7 +95,7 @@ int main() {
9595
double *result = malloc(n * sizeof(double));
9696
for (int i = 0; i < n; i++) a[i] = i * 0.1;
9797

98-
me_variable vars[] = {{"a", a}};
98+
me_variable vars[] = {{"a", ME_INT32, a}};
9999
int err;
100100
me_expr *expr = me_compile("a+5", vars, 1, result, n, ME_FLOAT64, &err);
101101

@@ -117,7 +117,7 @@ int main() {
117117
float complex *result = malloc(n * sizeof(float complex));
118118
for (int i = 0; i < n; i++) a[i] = (float) i + (float) i * I;
119119

120-
me_variable vars[] = {{"a", a}};
120+
me_variable vars[] = {{"a", ME_INT32, a}};
121121
int err;
122122
me_expr *expr = me_compile("a+5", vars, 1, result, n, ME_COMPLEX64, &err);
123123

@@ -146,7 +146,7 @@ int main() {
146146
b[i] = n - i;
147147
}
148148

149-
me_variable vars[] = {{"a", a}, {"b", b}};
149+
me_variable vars[] = {{"a", ME_INT32, a}, {"b", ME_INT32, b}};
150150
int err;
151151
me_expr *expr = me_compile("sqrt(a*a+b*b)", vars, 2, result, n, ME_INT32, &err);
152152

@@ -173,7 +173,7 @@ int main() {
173173
b[i] = n - i;
174174
}
175175

176-
me_variable vars[] = {{"a", a}, {"b", b}};
176+
me_variable vars[] = {{"a", ME_UINT64, a}, {"b", ME_UINT64, b}};
177177
int err;
178178
me_expr *expr = me_compile("sqrt(a*a+b*b)", vars, 2, result, n, ME_UINT64, &err);
179179

@@ -200,7 +200,7 @@ int main() {
200200
b[i] = (n - i) * 0.1f;
201201
}
202202

203-
me_variable vars[] = {{"a", a}, {"b", b}};
203+
me_variable vars[] = {{"a", ME_FLOAT32, a}, {"b", ME_FLOAT32, b}};
204204
int err;
205205
me_expr *expr = me_compile("sqrt(a*a+b*b)", vars, 2, result, n, ME_FLOAT32, &err);
206206

@@ -227,7 +227,7 @@ int main() {
227227
b[i] = (n - i) * 0.1;
228228
}
229229

230-
me_variable vars[] = {{"a", a}, {"b", b}};
230+
me_variable vars[] = {{"a", ME_FLOAT64, a}, {"b", ME_FLOAT64, b}};
231231
int err;
232232
me_expr *expr = me_compile("sqrt(a*a+b*b)", vars, 2, result, n, ME_FLOAT64, &err);
233233

@@ -254,7 +254,7 @@ int main() {
254254
b[i] = (float) (n - i) * 0.1f + (float) (n - i) * 0.1f * I;
255255
}
256256

257-
me_variable vars[] = {{"a", a}, {"b", b}};
257+
me_variable vars[] = {{"a", ME_COMPLEX64, a}, {"b", ME_COMPLEX64, b}};
258258
int err;
259259
me_expr *expr = me_compile("sqrt(a*a+b*b)", vars, 2, result, n, ME_COMPLEX64, &err);
260260

bench/benchmark_chunked.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ void benchmark_expression(const char *expr_str, int total_size, int chunk_size)
2828
b[i] = (total_size - i) * 0.05;
2929
}
3030

31-
me_variable vars[] = {{"a", a}, {"b", b}};
31+
// Variables for compilation (just the names)
32+
me_variable vars[] = {{"a"}, {"b"}};
3233
int err;
3334

34-
// Compile expression
35-
me_expr *expr = me_compile(expr_str, vars, 2, result, total_size, ME_FLOAT64, &err);
35+
// Compile expression for chunked evaluation
36+
me_expr *expr = me_compile_chunk(expr_str, vars, 2, ME_FLOAT64, &err);
3637
if (!expr) {
3738
printf("Failed to compile expression\n");
3839
free(a);
@@ -41,11 +42,12 @@ void benchmark_expression(const char *expr_str, int total_size, int chunk_size)
4142
return;
4243
}
4344

44-
// Benchmark 1: Monolithic evaluation
45+
// Benchmark 1: Monolithic evaluation (using me_eval_chunk with full array)
4546
const int iterations = 10;
4647
double start = get_time();
4748
for (int iter = 0; iter < iterations; iter++) {
48-
me_eval(expr);
49+
const void *vars_full[2] = {a, b};
50+
me_eval_chunk(expr, vars_full, 2, result, total_size);
4951
}
5052
double monolithic_time = (get_time() - start) / iterations;
5153

bench/benchmark_mixed_types.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ void benchmark_mixed_types(const char *expr_str, ExprType expr_type, int nitems)
3333

3434
// MiniExpr with type promotion
3535
me_variable vars[] = {
36-
{"a", a_i64, ME_VARIABLE, NULL, ME_INT64},
37-
{"b", b_f32, ME_VARIABLE, NULL, ME_FLOAT32}
36+
{"a", ME_INT64, a_i64},
37+
{"b", ME_FLOAT32, b_f32}
3838
};
3939

4040
int err;

bench/benchmark_threadsafe.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ void benchmark_threads(const char *expr_str, int total_size, int num_threads) {
5353
b[i] = (total_size - i) * 0.05;
5454
}
5555

56-
// Compile
57-
me_variable vars[] = {{"a", a}, {"b", b}};
56+
// Variables for compilation (just the names)
57+
me_variable vars[] = {{"a"}, {"b"}};
5858
int err;
59-
me_expr *expr = me_compile(expr_str, vars, 2, result, total_size, ME_FLOAT64, &err);
59+
me_expr *expr = me_compile_chunk(expr_str, vars, 2, ME_FLOAT64, &err);
6060
if (!expr) {
6161
printf("Failed to compile\n");
6262
free(a);
@@ -70,7 +70,8 @@ void benchmark_threads(const char *expr_str, int total_size, int num_threads) {
7070
// Benchmark serial evaluation
7171
double serial_start = get_time();
7272
for (int iter = 0; iter < iterations; iter++) {
73-
me_eval(expr);
73+
const void *vars_full[2] = {a, b};
74+
me_eval_chunk(expr, vars_full, 2, result, total_size);
7475
}
7576
double serial_time = (get_time() - serial_start) / iterations;
7677

bench/benchmark_types.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ void benchmark_expression(const char *type_name, me_dtype dtype, int use_double,
4646
}
4747
}
4848

49-
me_variable vars[] = {{"a", a}, {"b", b}};
49+
me_variable vars[] = {{"a", dtype, a}, {"b", dtype, b}};
5050
int err;
5151

5252
printf("\n--- Vector size: %d, iterations: %d ---\n", n, iterations);

check-whitespace.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/sh
2+
#
3+
# Script to check for and optionally fix trailing whitespace
4+
# Usage:
5+
# ./check-whitespace.sh # Check only
6+
# ./check-whitespace.sh --fix # Fix trailing whitespace
7+
#
8+
9+
FIX=0
10+
if [ "$1" = "--fix" ] || [ "$1" = "-f" ]; then
11+
FIX=1
12+
fi
13+
14+
# Find files with trailing whitespace
15+
FILES=$(find . -type f \( -name '*.c' -o -name '*.h' -o -name '*.md' \) \
16+
-not -path './build/*' \
17+
-not -path './.git/*' \
18+
-exec grep -l ' $' {} \; 2>/dev/null)
19+
20+
if [ -z "$FILES" ]; then
21+
echo "✅ No trailing whitespace found"
22+
exit 0
23+
fi
24+
25+
if [ $FIX -eq 1 ]; then
26+
echo "🔧 Fixing trailing whitespace in:"
27+
echo "$FILES" | sed 's/^/ /'
28+
find . -type f \( -name '*.c' -o -name '*.h' -o -name '*.md' \) \
29+
-not -path './build/*' \
30+
-not -path './.git/*' \
31+
-exec sed -i '' 's/[[:space:]]*$//' {} \;
32+
echo "✅ Fixed!"
33+
exit 0
34+
else
35+
echo "❌ Trailing whitespace found in:"
36+
echo "$FILES" | sed 's/^/ /'
37+
echo ""
38+
echo "To fix, run:"
39+
echo " $0 --fix"
40+
exit 1
41+
fi

0 commit comments

Comments
 (0)