diff --git a/src/misc.c b/src/misc.c index c362e87e..80fd63ac 100644 --- a/src/misc.c +++ b/src/misc.c @@ -131,7 +131,7 @@ collapse_continuations (char *line) char *q; q = strchr(in, '\n'); - if (q == 0) + if (!q) return; do @@ -162,17 +162,33 @@ collapse_continuations (char *line) if (i & 1) { - /* Backslash/newline handling: - In traditional GNU Make all trailing whitespace, consecutive - backslash/newlines, and any leading non-newline whitespace on the - next line is reduced to a single space. - In POSIX, each backslash/newline and is replaced by a space. */ + unsigned int dollar; + + /* Backslash/newline handling: out points to the final "\". + In POSIX, each backslash/newline is replaced by a space. + In GNU Make all trailing whitespace, consecutive backslash + + newlines, and any leading non-newline whitespace on the next line + is reduced to a single space. + As a special case, replace "$\" with the empty string. */ while (ISBLANK (*in)) ++in; - if (! posix_pedantic) + + { + const char *dp = out; + while (dp > line && dp[-1] == '$') + --dp; + dollar = (out - dp) % 2; + } + + if (dollar) + --out; + + if (!posix_pedantic) while (out > line && ISBLANK (out[-1])) --out; - *out++ = ' '; + + if (!dollar) + *out++ = ' '; } else { diff --git a/tests/scripts/variables/flavors b/tests/scripts/variables/flavors index 627672f8..ff375b2b 100644 --- a/tests/scripts/variables/flavors +++ b/tests/scripts/variables/flavors @@ -115,13 +115,15 @@ all: ; @: $(info recur=/$(recur)/ simple=/$(simple)/ recure=/$(recur_empty)/ sim # TEST 9: Line continuation run_make_test(q! recur = $\ - one$\ - two$\ + zero $\ + one$$\ + two$$$\ three simple := $\ - four$\ - five$\ - six + four $\ + five$$\ + six$$$\ + seven all: d$\ e$\ @@ -130,19 +132,21 @@ all: d$\ .PHONY: dep dep: ; @: $(info recur=/$(recur)/ simple=/$(simple)/) !, - '', "recur=/onetwothree/ simple=/fourfivesix/\n"); + '', "recur=/zeroone\$ two\$three/ simple=/fourfive\$ six\$seven/\n"); -# TEST 9: Line continuation +# TEST 9: Line continuation with POSIX run_make_test(q! .POSIX: recur = $\ - one$\ - two$\ + zero $\ + one$$\ + two$$$\ three simple := $\ - four$\ - five$\ - six + four $\ + five$$\ + six$$$\ + seven all: d$\ e$\ @@ -151,7 +155,7 @@ all: d$\ .PHONY: dep dep: ; @: $(info recur=/$(recur)/ simple=/$(simple)/) !, - '', "recur=/onetwothree/ simple=/fourfivesix/\n"); + '', "recur=/zero one\$ two\$three/ simple=/four five\$ six\$seven/\n"); # Test POSIX :::= # This creates a recursive variable, but it expands the RHS first. Any diff --git a/tests/scripts/variables/negative b/tests/scripts/variables/negative index 5cb600a8..a49bbef7 100644 --- a/tests/scripts/variables/negative +++ b/tests/scripts/variables/negative @@ -2,6 +2,8 @@ $description = "Run some negative tests (things that should fail)."; +my $unterm = '*** unterminated variable reference. Stop.'; + # TEST #0 # Check that non-terminated variable references are detected (and # reported using the best filename/lineno info @@ -12,15 +14,12 @@ y = $x all: ; @echo $y ', - '', '#MAKEFILE#:3: *** unterminated variable reference. Stop.', + '', "#MAKEFILE#:3: $unterm", 512); # TEST #1 # Bogus variable value passed on the command line. -run_make_test(undef, - ['x=$(other'], - '#MAKEFILE#:4: *** unterminated variable reference. Stop.', - 512); +run_make_test(undef, ['x=$(other'], "#MAKEFILE#:4: $unterm", 512); # TEST #2 # Again, but this time while reading the makefile. @@ -33,28 +32,23 @@ z := $y all: ; @echo $y ', - '', '#MAKEFILE#:3: *** unterminated variable reference. Stop.', - 512); + '', "#MAKEFILE#:3: $unterm", 512); # TEST #3 # Bogus variable value passed on the command line. -run_make_test(undef, - ['x=$(other'], - '#MAKEFILE#:4: *** unterminated variable reference. Stop.', - 512); +run_make_test(undef, ['x=$(other'], "#MAKEFILE#:4: $unterm", 512); + +my $nosep = '*** missing separator. Stop.'; # Whitespace not allowed in variable names -run_make_test('x y =', '', - '#MAKEFILE#:1: *** missing separator. Stop.', 512); +run_make_test('x y =', '', "#MAKEFILE#:1: $nosep", 512); -run_make_test('x y=', '', - '#MAKEFILE#:1: *** missing separator. Stop.', 512); +run_make_test('x y=', '', "#MAKEFILE#:1: $nosep", 512); # In theory an empty variable should be ignored, but during parsing it's a # real token and so this fails. I'm not 100% sure if this is right or not. -run_make_test('x $X=', '', - '#MAKEFILE#:1: *** missing separator. Stop.', 512); +run_make_test('x $X=', '', "#MAKEFILE#:1: $nosep", 512); 1;