commit dd4e574

shrub  ·  2026-04-16 17:01:45 +0000 UTC
parent 427bbfc
stop handling @-+ in the backend and store metadata for them instead of just stripping
10 files changed,  +87, -44
+1, -21
 1@@ -19,23 +19,6 @@ emitrule(FILE *fp, const char *cmd, int id)
 2 	fprintf(fp, "  command = %s\n\n", cmd);
 3 }
 4 
 5-static char *
 6-cleanrecipe(const char *s)
 7-{
 8-	size_t n;
 9-
10-	while (*s == ' ' || *s == '\t')
11-		s++;
12-	while (*s == '@' || *s == '+' || *s == '-')
13-		s++;
14-	while (*s == ' ' || *s == '\t')
15-		s++;
16-	n = strlen(s);
17-	while (n > 0 && (s[n - 1] == ' ' || s[n - 1] == '\t'))
18-		n--;
19-	return xstrndup(s, n);
20-}
21-
22 static char *
23 joinrecipes(const struct Target *t)
24 {
25@@ -44,12 +27,9 @@ joinrecipes(const struct Target *t)
26 
27 	s = xstrdup("");
28 	for (i = 0; i < t->recipes.n; i++) {
29-		char *clean;
30 		char *next;
31 
32-		clean = cleanrecipe(t->recipes.v[i]);
33-		next = s[0] ? cat3(s, " && ", clean) : xstrdup(clean);
34-		free(clean);
35+		next = s[0] ? cat3(s, " && ", t->recipes.v[i].body) : xstrdup(t->recipes.v[i].body);
36 		free(s);
37 		s = next;
38 	}
+7, -1
 1@@ -141,7 +141,13 @@ dumprecipes(const struct RecipeList *list, int depth)
 2 	printf("recipes (%zu):\n", list->n);
 3 	for (i = 0; i < list->n; i++) {
 4 		printindent(depth + 1);
 5-		printf("%s\n", list->v[i]);
 6+		if (list->v[i].silent)
 7+			putchar('@');
 8+		if (list->v[i].ignore)
 9+			putchar('-');
10+		if (list->v[i].recursive)
11+			putchar('+');
12+		printf("%s\n", list->v[i].body);
13 	}
14 }
15 
+5, -1
 1@@ -140,7 +140,11 @@ copyrecipes(struct RecipeList *out, const struct RecipeList *in)
 2 	memset(out, 0, sizeof(*out));
 3 	for (i = 0; i < in->n; i++) {
 4 		out->v = xrealloc(out->v, (out->n + 1) * sizeof(out->v[0]));
 5-		out->v[out->n++] = xstrdup(in->v[i]);
 6+		out->v[out->n].body = xstrdup(in->v[i].body);
 7+		out->v[out->n].silent = in->v[i].silent;
 8+		out->v[out->n].ignore = in->v[i].ignore;
 9+		out->v[out->n].recursive = in->v[i].recursive;
10+		out->n++;
11 	}
12 }
13 
+6, -2
 1@@ -194,7 +194,7 @@ instpatrule(const struct PatRules *rules, const struct Graph *graph, struct Targ
 2 		for (j = 0; j < rules->v[i].recipes.n; j++) {
 3 			char *s, *vars, *exp;
 4 
 5-			s = applystem(rules->v[i].recipes.v[j], stem);
 6+			s = applystem(rules->v[i].recipes.v[j].body, stem);
 7 			vars = expandstr(ctx, s);
 8 			exp = expandstem(vars, stem);
 9 			free(vars);
10@@ -204,7 +204,11 @@ instpatrule(const struct PatRules *rules, const struct Graph *graph, struct Targ
11 				continue;
12 			}
13 			t->recipes.v = xrealloc(t->recipes.v, (t->recipes.n + 1) * sizeof(t->recipes.v[0]));
14-			t->recipes.v[t->recipes.n++] = exp;
15+			t->recipes.v[t->recipes.n].body = exp;
16+			t->recipes.v[t->recipes.n].silent = rules->v[i].recipes.v[j].silent;
17+			t->recipes.v[t->recipes.n].ignore = rules->v[i].recipes.v[j].ignore;
18+			t->recipes.v[t->recipes.n].recursive = rules->v[i].recipes.v[j].recursive;
19+			t->recipes.n++;
20 		}
21 		free(stem);
22 		return 1;
+6, -2
 1@@ -104,13 +104,17 @@ addexprecipes(struct RecipeList *dest, const struct RecipeList *src, struct Eval
 2 	for (i = 0; i < src->n; i++) {
 3 		char *exp;
 4 
 5-		exp = expandstr(ctx, src->v[i]);
 6+		exp = expandstr(ctx, src->v[i].body);
 7 		if (!exp[0]) {
 8 			free(exp);
 9 			continue;
10 		}
11 		dest->v = xrealloc(dest->v, (dest->n + 1) * sizeof(dest->v[0]));
12-		dest->v[dest->n++] = exp;
13+		dest->v[dest->n].body = exp;
14+		dest->v[dest->n].silent = src->v[i].silent;
15+		dest->v[dest->n].ignore = src->v[i].ignore;
16+		dest->v[dest->n].recursive = src->v[i].recursive;
17+		dest->n++;
18 	}
19 }
20 
+1, -0
1@@ -27,6 +27,7 @@ void addnode(struct NodeList *list, struct Node node);
2 void splitwords(struct StrList *out, const char *s, size_t n);
3 char *cat3(const char *a, const char *b, const char *c);
4 void addwords(struct StrList *dest, const struct StrList *src);
5+void addrecipe(struct RecipeList *dest, const char *raw);
6 void addrecipes(struct RecipeList *dest, const struct RecipeList *src);
7 void freestrs(struct StrList *list);
8 void freerecipes(struct RecipeList *list);
+3, -8
 1@@ -622,10 +622,8 @@ parserule(const struct PreLine *line, const char *s, size_t n, size_t colon, int
 2 	if (semi != (size_t)-1) {
 3 		recipe = trimdup(rhs + semi + 1, rhsn - semi - 1);
 4 		if (recipe[0]) {
 5-			state.data.rule.recipes.v =
 6-			    xrealloc(state.data.rule.recipes.v,
 7-			             (state.data.rule.recipes.n + 1) * sizeof(state.data.rule.recipes.v[0]));
 8-			state.data.rule.recipes.v[state.data.rule.recipes.n++] = recipe;
 9+			addrecipe(&state.data.rule.recipes, recipe);
10+			free(recipe);
11 		} else {
12 			free(recipe);
13 		}
14@@ -781,10 +779,7 @@ parseblock(const struct Pre *pre, size_t *i, struct NodeList *out)
15 		line = &pre->v[*i];
16 		if (line->isrecipe) {
17 			if (last_rule) {
18-				last_rule->data.rule.recipes.v = xrealloc(last_rule->data.rule.recipes.v,
19-				                                          (last_rule->data.rule.recipes.n + 1) * sizeof(last_rule->data.rule.recipes.v[0]));
20-				last_rule->data.rule.recipes.v[last_rule->data.rule.recipes.n++] =
21-				    xstrndup(line->text + 1, strlen(line->text + 1));
22+				addrecipe(&last_rule->data.rule.recipes, line->text + 1);
23 				last_rule->loc.line1 = line->line1;
24 				(*i)++;
25 				continue;
+13, -6
 1@@ -31,8 +31,7 @@ sufactive(const struct SuffixList *list, const char *suf)
 2 static void
 3 addimprecipe(struct RecipeList *recipes, const char *line)
 4 {
 5-	recipes->v = xrealloc(recipes->v, (recipes->n + 1) * sizeof(recipes->v[0]));
 6-	recipes->v[recipes->n++] = xstrdup(line);
 7+	addrecipe(recipes, line);
 8 }
 9 
10 static void
11@@ -436,7 +435,7 @@ instsufrule(const struct SufRules *rules,
12 				for (k = 0; k < rules->sufs[r].recipes.n; k++) {
13 					char *vars, *exp;
14 
15-					vars = expandstr(ctx, rules->sufs[r].recipes.v[k]);
16+					vars = expandstr(ctx, rules->sufs[r].recipes.v[k].body);
17 					exp = expandauto(vars, t, stem);
18 					free(vars);
19 					if (!exp[0]) {
20@@ -444,7 +443,11 @@ instsufrule(const struct SufRules *rules,
21 						continue;
22 					}
23 					t->recipes.v = xrealloc(t->recipes.v, (t->recipes.n + 1) * sizeof(t->recipes.v[0]));
24-					t->recipes.v[t->recipes.n++] = exp;
25+					t->recipes.v[t->recipes.n].body = exp;
26+					t->recipes.v[t->recipes.n].silent = rules->sufs[r].recipes.v[k].silent;
27+					t->recipes.v[t->recipes.n].ignore = rules->sufs[r].recipes.v[k].ignore;
28+					t->recipes.v[t->recipes.n].recursive = rules->sufs[r].recipes.v[k].recursive;
29+					t->recipes.n++;
30 				}
31 				free(stem);
32 				return 1;
33@@ -474,7 +477,7 @@ instsufrule(const struct SufRules *rules,
34 			for (k = 0; k < rules->singlesuf[j].recipes.n; k++) {
35 				char *vars, *exp;
36 
37-				vars = expandstr(ctx, rules->singlesuf[j].recipes.v[k]);
38+				vars = expandstr(ctx, rules->singlesuf[j].recipes.v[k].body);
39 				exp = expandauto(vars, t, t->name);
40 				free(vars);
41 				if (!exp[0]) {
42@@ -482,7 +485,11 @@ instsufrule(const struct SufRules *rules,
43 					continue;
44 				}
45 				t->recipes.v = xrealloc(t->recipes.v, (t->recipes.n + 1) * sizeof(t->recipes.v[0]));
46-				t->recipes.v[t->recipes.n++] = exp;
47+				t->recipes.v[t->recipes.n].body = exp;
48+				t->recipes.v[t->recipes.n].silent = rules->singlesuf[j].recipes.v[k].silent;
49+				t->recipes.v[t->recipes.n].ignore = rules->singlesuf[j].recipes.v[k].ignore;
50+				t->recipes.v[t->recipes.n].recursive = rules->singlesuf[j].recipes.v[k].recursive;
51+				t->recipes.n++;
52 			}
53 			return 1;
54 		}
+8, -1
 1@@ -61,8 +61,15 @@ struct StrList {
 2 	size_t n;
 3 };
 4 
 5+struct Recipe {
 6+	char *body;
 7+	int silent;
 8+	int ignore;
 9+	int recursive;
10+};
11+
12 struct RecipeList {
13-	char **v;
14+	struct Recipe *v;
15 	size_t n;
16 };
17 
+37, -2
 1@@ -3,6 +3,7 @@
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5+#include <ctype.h>
 6 
 7 /* shared utility functions */
 8 
 9@@ -84,6 +85,36 @@ addwords(struct StrList *dest, const struct StrList *src)
10 	}
11 }
12 
13+void
14+addrecipe(struct RecipeList *dest, const char *raw)
15+{
16+	struct Recipe *r;
17+	const char *s;
18+	size_t n;
19+
20+	s = raw;
21+	while (*s == ' ' || *s == '\t')
22+		s++;
23+	dest->v = xrealloc(dest->v, (dest->n + 1) * sizeof(dest->v[0]));
24+	r = &dest->v[dest->n++];
25+	memset(r, 0, sizeof(*r));
26+	while (*s == '@' || *s == '+' || *s == '-') {
27+		if (*s == '@')
28+			r->silent = 1;
29+		else if (*s == '+')
30+			r->recursive = 1;
31+		else if (*s == '-')
32+			r->ignore = 1;
33+		s++;
34+		while (*s == ' ' || *s == '\t')
35+			s++;
36+	}
37+	n = strlen(s);
38+	while (n > 0 && isspace((unsigned char)s[n - 1]))
39+		n--;
40+	r->body = xstrndup(s, n);
41+}
42+
43 void
44 addrecipes(struct RecipeList *dest, const struct RecipeList *src)
45 {
46@@ -91,7 +122,11 @@ addrecipes(struct RecipeList *dest, const struct RecipeList *src)
47 
48 	for (i = 0; i < src->n; i++) {
49 		dest->v = xrealloc(dest->v, (dest->n + 1) * sizeof(dest->v[0]));
50-		dest->v[dest->n++] = xstrdup(src->v[i]);
51+		dest->v[dest->n].body = xstrdup(src->v[i].body);
52+		dest->v[dest->n].silent = src->v[i].silent;
53+		dest->v[dest->n].ignore = src->v[i].ignore;
54+		dest->v[dest->n].recursive = src->v[i].recursive;
55+		dest->n++;
56 	}
57 }
58 
59@@ -141,7 +176,7 @@ freerecipes(struct RecipeList *list)
60 	if (!list)
61 		return;
62 	for (i = 0; i < list->n; i++)
63-		free(list->v[i]);
64+		free(list->v[i].body);
65 	free(list->v);
66 	list->v = 0;
67 	list->n = 0;