commit 3ff2026
shrub
·
2026-04-12 09:11:15 +0000 UTC
parent 3165e81
make filter-out tests pass
3 files changed,
+45,
-19
+10,
-10
1@@ -320,20 +320,20 @@ expandstr(struct Env *env, const char *s)
2 memcpy(out + len, val, k);
3 len += k;
4 free(val);
5- } else if (j - i - 3 >= 6 &&
6- memcmp(s + i + 2, "filter", 6) == 0) {
7+ } else if (j - i - 3 >= 10 &&
8+ memcmp(s + i + 2, "filter-out", 10) == 0) {
9 char *args_raw, *pat_raw, *text_raw;
10 char *pat_exp, *text_exp, *val;
11 size_t astart;
12 ptrdiff_t comma;
13
14- astart = i + 8;
15+ astart = i + 12;
16 while (astart < j - 1 && isspace((unsigned char)s[astart]))
17 astart++;
18 args_raw = xstrndup(s + astart, j - 1 - astart);
19 comma = findargcomma(args_raw, strlen(args_raw));
20 if (comma < 0) {
21- evalerr("malformed function arguments", "$(filter)");
22+ evalerr("malformed function arguments", "$(filter-out)");
23 free(args_raw);
24 val = xstrdup("");
25 } else {
26@@ -344,7 +344,7 @@ expandstr(struct Env *env, const char *s)
27 text_exp = expandstr(env, text_raw);
28 free(pat_raw);
29 free(text_raw);
30- val = fnfilter(pat_exp, text_exp);
31+ val = fnfilterout(pat_exp, text_exp);
32 free(pat_exp);
33 free(text_exp);
34 }
35@@ -356,20 +356,20 @@ expandstr(struct Env *env, const char *s)
36 memcpy(out + len, val, k);
37 len += k;
38 free(val);
39- } else if (j - i - 3 >= 10 &&
40- memcmp(s + i + 2, "filter-out", 10) == 0) {
41+ } else if (j - i - 3 >= 6 &&
42+ memcmp(s + i + 2, "filter", 6) == 0) {
43 char *args_raw, *pat_raw, *text_raw;
44 char *pat_exp, *text_exp, *val;
45 size_t astart;
46 ptrdiff_t comma;
47
48- astart = i + 12;
49+ astart = i + 8;
50 while (astart < j - 1 && isspace((unsigned char)s[astart]))
51 astart++;
52 args_raw = xstrndup(s + astart, j - 1 - astart);
53 comma = findargcomma(args_raw, strlen(args_raw));
54 if (comma < 0) {
55- evalerr("malformed function arguments", "$(filter-out)");
56+ evalerr("malformed function arguments", "$(filter)");
57 free(args_raw);
58 val = xstrdup("");
59 } else {
60@@ -380,7 +380,7 @@ expandstr(struct Env *env, const char *s)
61 text_exp = expandstr(env, text_raw);
62 free(pat_raw);
63 free(text_raw);
64- val = fnfilterout(pat_exp, text_exp);
65+ val = fnfilter(pat_exp, text_exp);
66 free(pat_exp);
67 free(text_exp);
68 }
+33,
-9
1@@ -15,8 +15,10 @@ matchword(const char *patterns, const char *word, size_t nword)
2 size_t p0, p1;
3
4 for (p0 = 0; patterns[p0];) {
5- const char *pat, *pct;
6- size_t npat, pre, suf;
7+ const char *pat;
8+ char *cooked;
9+ size_t npat, i, n, pct, pre, suf;
10+ int haspct;
11
12 while (patterns[p0] && isspace((unsigned char)patterns[p0]))
13 p0++;
14@@ -27,19 +29,41 @@ matchword(const char *patterns, const char *word, size_t nword)
15 p1++;
16 pat = patterns + p0;
17 npat = p1 - p0;
18- pct = memchr(pat, '%', npat);
19- if (!pct) {
20- if (npat == nword && memcmp(pat, word, npat) == 0)
21+ cooked = xmalloc(npat + 1);
22+ n = 0;
23+ pct = 0;
24+ haspct = 0;
25+ for (i = 0; i < npat; i++) {
26+ if (pat[i] == '\\' && i + 1 < npat && (pat[i + 1] == '\\' || pat[i + 1] == '%')) {
27+ cooked[n++] = pat[++i];
28+ continue;
29+ }
30+ if (pat[i] == '%' && !haspct) {
31+ pct = n;
32+ haspct = 1;
33+ continue;
34+ }
35+ cooked[n++] = pat[i];
36+ }
37+ cooked[n] = 0;
38+ if (!haspct) {
39+ if (n == nword && memcmp(cooked, word, n) == 0) {
40+ free(cooked);
41 return 1;
42+ }
43+ free(cooked);
44 p0 = p1;
45 continue;
46 }
47- pre = (size_t)(pct - pat);
48- suf = npat - pre - 1;
49+ pre = pct;
50+ suf = n - pre;
51 if (nword >= pre + suf &&
52- memcmp(pat, word, pre) == 0 &&
53- memcmp(pct + 1, word + nword - suf, suf) == 0)
54+ memcmp(cooked, word, pre) == 0 &&
55+ memcmp(cooked + pre, word + nword - suf, suf) == 0) {
56+ free(cooked);
57 return 1;
58+ }
59+ free(cooked);
60 p0 = p1;
61 }
62 return 0;
+2,
-0
1@@ -1,2 +1,4 @@
2 .test-result
3 work
4+*/build.ninja
5+*/.ninja_*