commit 8840acc818b688a7b373106c0a466fdd56322d0d
parent 0b795256f75466f2b3d58fb7124a75a5e6829a9e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 5 Nov 2024 09:14:28 +0100
make: Deal $$ correctly
We have to preserve $$ in any expansion, because as we
expand recursively then a nested expansion can try to
expand it. If we keep it then we have to unescape before
executing the line in execline().
Diffstat:
3 files changed, 40 insertions(+), 10 deletions(-)
diff --git a/src/cmd/scc-make/parser.c b/src/cmd/scc-make/parser.c
@@ -716,16 +716,20 @@ expandstring(char *line, Target *tp, struct loc *loc)
n = 0;
s = NULL;
while ((c = nextc()) != EOF) {
- if (c == '$') {
- if ((c = nextc()) != '$') {
- back(c);
- expansion(tp);
- continue;
- }
+ if (c != '$') {
+ s = erealloc(s, ++n);
+ s[n-1] = c;
+ continue;
}
- s = erealloc(s, ++n);
- s[n-1] = c;
+ if ((c = nextc()) == '$') {
+ s = erealloc(s, n += 2);
+ s[n-2] = '$';
+ s[n-1] = '$';
+ } else {
+ back(c);
+ expansion(tp);
+ }
}
s = erealloc(s, n+1);
diff --git a/src/cmd/scc-make/rules.c b/src/cmd/scc-make/rules.c
@@ -175,9 +175,9 @@ addrule(char *target, struct action *acts, int n)
static int
execline(Target *tp, char *line, int ignore, int silence)
{
- char *s;
+ char *s, *t;
Target *p, **q;
- int r, at, plus, minus;
+ int r, at, plus, minus, l;
debug("executing '%s'", line);
@@ -199,6 +199,14 @@ execline(Target *tp, char *line, int ignore, int silence)
}
out_loop:
+ /* unescape $$ */
+ for (l = strlen(s)+1, t = s; *t; --l, ++t) {
+ if (t[0] == '$' && t[1] == '$') {
+ memmove(t+1, t+2, l-2);
+ l--;
+ }
+ }
+
if (tflag && !plus)
return 0;
diff --git a/tests/make/execute/0096-escape.sh b/tests/make/execute/0096-escape.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+trap 'rm -f $tmp1 $tmp2' EXIT INT TERM QUIT HUP
+
+tmp1=tmp1.$$
+tmp2=tmp2.$$
+
+cat > $tmp1 <<EOF
+MACRO=hello
+EOF
+
+
+scc-make -f- <<'EOF' > $tmp2 2>&1
+MACRO = $$(echo hello)
+
+all:
+ @echo MACRO=$(MACRO)
+EOF