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);