mirror of
https://github.com/mirror/make.git
synced 2024-12-26 21:00:30 +08:00
Directly handle $\ line endings
Previously we used the fact that this line ending expanded to "$ " which would then expand to the empty string. This has problems if you enable warnings for undefined variables, so directly implement this special (but documented) trick in the GNU Make parser. As a side-effect this also removes all previous whitespace when in GNU Make mode (not in POSIX mode) just as it would without "$". * src/misc.c (collapse_continuations): Check for "$\" and remove it. * tests/scripts/variables/flavors: Add regression tests including with previous whitespace, and escaped/unescaped "$"
This commit is contained in:
parent
5d1fe2b16d
commit
bf7f690202
32
src/misc.c
32
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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user