commit 09f3b9c

shrub  ·  2026-04-27 22:10:51 +0000 UTC
parent 69981b3
fix dollar expansion, env leak in pattern rules, and make implicit rules gnuish (cppflags)
3 files changed,  +15, -10
+1, -1
1@@ -546,7 +546,7 @@ expandstr(struct EvalCtx *ctx, const char *s)
2 	bufinit(&out, n + 1);
3 	for (i = 0; i < n; i++) {
4 		if (s[i] == '$' && i + 1 < n && s[i + 1] == '$') {
5-			bufappend(&out, "$$");
6+			bufappendc(&out, '$');
7 			i++;
8 			continue;
9 		}
+9, -5
 1@@ -98,9 +98,12 @@ applytassigns(struct GraphState *gs, struct EvalCtx *ctx, const char *name)
 2 }
 3 
 4 static void
 5-targetenv(struct GraphState *gs, struct EvalCtx *ctx, const char *name)
 6+targetenv(struct GraphState *gs, struct EvalCtx *ctx, const struct Env *base, const char *name)
 7 {
 8-	copyenv(ctx->env, &gs->env);
 9+	if (base && base->n)
10+		copyenv(ctx->env, base);
11+	else
12+		copyenv(ctx->env, &gs->env);
13 	applytassigns(gs, ctx, name);
14 }
15 
16@@ -133,11 +136,10 @@ addrule(struct GraphState *gs, const char *name, const struct RuleNode *rule)
17 	t->dcolon = rule->dcolon;
18 	addwords(&t->prereqs, &rule->prereqs);
19 	addwords(&t->order_only, &rule->order_only);
20-	targetenv(gs, &ctx, name);
21+	targetenv(gs, &ctx, t->env.n ? &t->env : 0, name);
22 	addrecipes(&t->recipes, &rule->recipes);
23 	freeenv(&t->env);
24 	copyenv(&t->env, &env);
25-	freeenv(&env);
26 
27 	for (i = 0; i < rule->prereqs.n; i++) {
28 		if (strchr(rule->prereqs.v[i], '%'))
29@@ -147,8 +149,10 @@ addrule(struct GraphState *gs, const char *name, const struct RuleNode *rule)
30 			t = &gs->graph->v[gs->graph->n++];
31 			memset(t, 0, sizeof(*t));
32 			t->name = xstrdup(rule->prereqs.v[i]);
33+			copyenv(&t->env, &env);
34 		}
35 	}
36+	freeenv(&env);
37 }
38 static void
39 addtassign(struct GraphState *gs, const struct AssignNode *assign)
40@@ -235,7 +239,7 @@ buildgraph(const struct RuleSet *ruleset, struct Graph *graph)
41 
42 				memset(&targetctx, 0, sizeof(targetctx));
43 				targetctx.env = &env;
44-				targetenv(&gs, &targetctx, t->name);
45+				targetenv(&gs, &targetctx, &t->env, t->name);
46 				instpatrule(&gs.patterns, graph, t, &targetctx);
47 				matched = t->recipes.n > 0;
48 				if (!matched) {
+5, -4
 1@@ -243,6 +243,7 @@ seedenv(struct Env *env, int posix, int envoverride)
 2 	envsetvar(env, "YFLAGS", xstrdup(""), 1, ORIGIN_DEFAULT, 0);
 3 	envsetvar(env, "SHELL", xstrdup("/bin/sh"), 1, ORIGIN_DEFAULT, 0);
 4 	envsetvar(env, "MAKE", xstrdup("make"), 1, ORIGIN_DEFAULT, 0);
 5+	envsetvar(env, "RM", xstrdup("rm -f"), 1, ORIGIN_DEFAULT, 0);
 6 	if (posix) {
 7 		envsetvar(env, "CC", xstrdup("c99"), 1, ORIGIN_DEFAULT, 0);
 8 		envsetvar(env, "CFLAGS", xstrdup("-O1"), 1, ORIGIN_DEFAULT, 0);
 9@@ -276,10 +277,10 @@ imprules(struct SufRules *rules, int posix)
10 	    "chmod a+x $@",
11 	};
12 	static const char *const c_o[] = {
13-	    "$(CC) $(CFLAGS) -c -o $@ $<",
14+	    "$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<",
15 	};
16 	static const char *const c_o_posix[] = {
17-	    "$(CC) $(CFLAGS) -c $<",
18+	    "$(CC) $(CPPFLAGS) $(CFLAGS) -c $<",
19 	};
20 	static const char *const f_o[] = {
21 	    "$(FC) $(FFLAGS) -c -o $@ $<",
22@@ -289,13 +290,13 @@ imprules(struct SufRules *rules, int posix)
23 	};
24 	static const char *const y_o[] = {
25 	    "$(YACC) $(YFLAGS) $<",
26-	    "$(CC) $(CFLAGS) -c y.tab.c",
27+	    "$(CC) $(CPPFLAGS) $(CFLAGS) -c y.tab.c",
28 	    "rm -f y.tab.c",
29 	    "mv y.tab.o $@",
30 	};
31 	static const char *const l_o[] = {
32 	    "$(LEX) $(LFLAGS) $<",
33-	    "$(CC) $(CFLAGS) -c lex.yy.c",
34+	    "$(CC) $(CPPFLAGS) $(CFLAGS) -c lex.yy.c",
35 	    "rm -f lex.yy.c",
36 	    "mv lex.yy.o $@",
37 	};