commit 110cfec

shrub  ·  2026-04-09 11:28:05 +0000 UTC
parent 816afea
better automatic var translation
2 files changed,  +97, -14
+60, -2
 1@@ -36,13 +36,71 @@ joinrecipes(const struct Target *t)
 2 	return s;
 3 }
 4 
 5+static char *
 6+translateauto(const char *s, const struct Target *t)
 7+{
 8+	size_t i, n, cap, len;
 9+	char *out;
10+
11+	n = strlen(s);
12+	cap = n + 1;
13+	len = 0;
14+	out = xmalloc(cap);
15+	for (i = 0; i < n; i++) {
16+		const char *val;
17+		size_t vlen;
18+
19+		if (s[i] != '$' || i + 1 >= n) {
20+			if (len + 2 > cap) {
21+				cap *= 2;
22+				out = xrealloc(out, cap);
23+			}
24+			out[len++] = s[i];
25+			continue;
26+		}
27+
28+		val = 0;
29+		if (s[i + 1] == '$') {
30+			val = "$$";
31+		} else if (s[i + 1] == '@') {
32+			val = "$out";
33+		} else if (s[i + 1] == '<') {
34+			val = t->prereqs.n == 1 ? "$in" : (t->prereqs.n ? t->prereqs.v[0] : "");
35+		} else if (s[i + 1] == '^' || s[i + 1] == '+' || s[i + 1] == '?') {
36+			val = "$in";
37+		}
38+
39+		if (!val) {
40+			if (len + 2 > cap) {
41+				cap *= 2;
42+				out = xrealloc(out, cap);
43+			}
44+			out[len++] = s[i];
45+			continue;
46+		}
47+
48+		vlen = strlen(val);
49+		if (len + vlen + 1 > cap) {
50+			cap = len + vlen + (n - i) + 1;
51+			out = xrealloc(out, cap);
52+		}
53+		memcpy(out + len, val, vlen);
54+		len += vlen;
55+		i++;
56+	}
57+	out[len] = 0;
58+	return out;
59+}
60+
61 static char *
62 rulecmd(const struct Target *t)
63 {
64-	char *cmd;
65+	char *cmd, *xlat;
66 
67 	cmd = joinrecipes(t);
68-	return cmd;
69+	xlat = translateauto(cmd, t);
70+	free(cmd);
71+	return xlat;
72 }
73 
74 static int
+37, -12
 1@@ -182,6 +182,42 @@ joinprereqs(const struct Target *t)
 2 	return joined;
 3 }
 4 
 5+static char *
 6+expandstem(const char *s, const char *stem)
 7+{
 8+	size_t i, n, cap, len;
 9+	char *out;
10+
11+	n = strlen(s);
12+	cap = n + 1;
13+	len = 0;
14+	out = xmalloc(cap);
15+	for (i = 0; i < n; i++) {
16+		if (s[i] == '$' && i + 1 < n && s[i + 1] == '*') {
17+			size_t slen;
18+
19+			slen = stem ? strlen(stem) : 0;
20+			if (len + slen + 1 > cap) {
21+				cap = len + slen + (n - i) + 1;
22+				out = xrealloc(out, cap);
23+			}
24+			if (slen) {
25+				memcpy(out + len, stem, slen);
26+				len += slen;
27+			}
28+			i++;
29+			continue;
30+		}
31+		if (len + 2 > cap) {
32+			cap *= 2;
33+			out = xrealloc(out, cap);
34+		}
35+		out[len++] = s[i];
36+	}
37+	out[len] = 0;
38+	return out;
39+}
40+
41 static void
42 addexprecipes(struct RecipeList *dest, const struct RecipeList *src, struct Env *env)
43 {
44@@ -417,7 +453,7 @@ instantiate(struct GraphState *gs, struct Target *t, struct Pattern *p, const ch
45 
46 		s = applystem(p->recipes.v[i], stem);
47 		vars = expandstr(&env, s);
48-		exp = expandauto(vars, t, stem);
49+		exp = expandstem(vars, stem);
50 		free(vars);
51 		free(s);
52 		t->recipes.v = xrealloc(t->recipes.v, (t->recipes.n + 1) * sizeof(t->recipes.v[0]));
53@@ -513,17 +549,6 @@ buildgraph(const struct Ast *ast, struct Graph *graph)
54 		start = current_n;
55 	}
56 
57-	for (i = 0; i < graph->n; i++) {
58-		struct Target *t = &graph->v[i];
59-		size_t k;
60-
61-		for (k = 0; k < t->recipes.n; k++) {
62-			char *exp = expandauto(t->recipes.v[k], t, 0);
63-			free(t->recipes.v[k]);
64-			t->recipes.v[k] = exp;
65-		}
66-	}
67-
68 	for (i = 0; i < gs.npats; i++) {
69 		free(gs.pats[i].target);
70 		freestrs(&gs.pats[i].prereqs);