commit 2eb5b83

shrub  ·  2026-05-15 18:03:20 +0000 UTC
parent a0759f6
normalize recipe bodies before emission
1 files changed,  +38, -5
+38, -5
 1@@ -123,6 +123,34 @@ exportenv(const struct Target *t)
 2 	return out;
 3 }
 4 
 5+static char *
 6+normalizebody(const char *s)
 7+{
 8+	size_t i, n, j;
 9+	char *out;
10+
11+	n = strlen(s);
12+	out = xmalloc(n + 1);
13+	j = 0;
14+	for (i = 0; i < n; i++) {
15+		if (s[i] == '\\' && i + 1 < n && s[i + 1] == '\n') {
16+			i++;
17+		} else if (s[i] == '\n') {
18+			while (j > 0 && out[j - 1] == ' ')
19+				j--;
20+			if (j > 0)
21+				out[j++] = ';';
22+			out[j++] = ' ';
23+		} else {
24+			out[j++] = s[i];
25+		}
26+	}
27+	while (j > 0 && (out[j - 1] == ' ' || out[j - 1] == ';'))
28+		j--;
29+	out[j] = 0;
30+	return out;
31+}
32+
33 static char *
34 joinrecipes(const struct Target *t)
35 {
36@@ -132,12 +160,17 @@ joinrecipes(const struct Target *t)
37 
38 	memset(&bodies, 0, sizeof(bodies));
39 	for (i = 0; i < t->recipes.n; i++) {
40-		char *body;
41+		char *normalized, *body;
42 
43-		if (t->recipes.n > 1)
44-			body = cat3("( ", t->recipes.v[i].body, " )");
45-		else
46-			body = xstrdup(t->recipes.v[i].body);
47+		normalized = normalizebody(t->recipes.v[i].body);
48+		if (t->recipes.n > 1) {
49+			char *quoted = shellquote(normalized);
50+			body = cat3("sh -c ", quoted, "");
51+			free(quoted);
52+			free(normalized);
53+		} else {
54+			body = normalized;
55+		}
56 		bodies.v = xrealloc(bodies.v, (bodies.n + 1) * sizeof(bodies.v[0]));
57 		bodies.v[bodies.n++] = body;
58 	}