[SV 20513] Un-escaped # are not comments in function invocations

* NEWS: Document the change, as a backward-incompatible change.
* main.c (main): Add 'nocomment' to the .FEATURES variable.
* read.c (remove_comments): Skip variable references during remove.
(find_char_unquote): Fix comments for new STOPMAP support.
* tests/scripts/features/escape: Test new escape syntax.
* tests/scripts/functions/guile: Ditto.
* tests/scripts/functions/shell: Ditto.
This commit is contained in:
Paul Smith 2016-12-22 18:47:26 -05:00
parent 0029ea8941
commit c6966b3238
6 changed files with 62 additions and 17 deletions

14
NEWS
View File

@ -15,6 +15,20 @@ A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set=custom
* WARNING: Backward-incompatibility!
Number signs (#) appearing inside a macro reference or function invocation
no longer introduce comments and should not be escaped with backslashes:
thus a call such as:
foo := $(shell echo '#')
is legal. Previously the number sign needed to be escaped, for example:
foo := $(shell echo '\#')
Now this latter will resolve to "\#". If you want to write makefiles
portable to both versions, assign the number sign to a variable:
C := \#
foo := $(shell echo '$C')
This was claimed to be fixed in 3.81, but wasn't, for some reason.
To detect this change search for 'nocomment' in the .FEATURES variable.
* The previous limit of 63 jobs under -jN on MS-Windows is now
increased to 4095. That limit includes the subprocess started by
the $(shell) function.

2
main.c
View File

@ -1321,7 +1321,7 @@ main (int argc, char **argv, char **envp)
some compilers (MSVC) don't like conditionals in macros. */
{
const char *features = "target-specific order-only second-expansion"
" else-if shortest-stem undefine oneshell"
" else-if shortest-stem undefine oneshell nocomment"
#ifndef NO_ARCHIVES
" archives"
#endif

25
read.c
View File

@ -1398,14 +1398,15 @@ eval (struct ebuffer *ebuf, int set_default)
/* Remove comments from LINE.
This is done by copying the text at LINE onto itself. */
This will also remove backslashes that escape things.
It ignores comment characters that appear inside variable references. */
static void
remove_comments (char *line)
{
char *comment;
comment = find_char_unquote (line, MAP_COMMENT);
comment = find_char_unquote (line, MAP_COMMENT|MAP_VARIABLE);
if (comment != 0)
/* Cut off the line at the #. */
@ -2224,27 +2225,27 @@ record_files (struct nameseq *filenames, const char *pattern,
}
}
/* Search STRING for an unquoted STOPCHAR or blank (if BLANK is nonzero).
Backslashes quote STOPCHAR, blanks if BLANK is nonzero, and backslash.
Quoting backslashes are removed from STRING by compacting it into
itself. Returns a pointer to the first unquoted STOPCHAR if there is
one, or nil if there are none. STOPCHARs inside variable references are
ignored if IGNOREVARS is true.
/* Search STRING for an unquoted STOPMAP.
Backslashes quote elements from STOPMAP and backslash.
Quoting backslashes are removed from STRING by compacting it into itself.
Returns a pointer to the first unquoted STOPCHAR if there is one, or nil if
there are none.
STOPCHAR _cannot_ be '$' if IGNOREVARS is true. */
If MAP_VARIABLE is set, then the complete contents of variable references
are skipped, even if the contain STOPMAP characters. */
static char *
find_char_unquote (char *string, int map)
find_char_unquote (char *string, int stopmap)
{
unsigned int string_len = 0;
char *p = string;
/* Always stop on NUL. */
map |= MAP_NUL;
stopmap |= MAP_NUL;
while (1)
{
while (! STOP_SET (*p, map))
while (! STOP_SET (*p, stopmap))
++p;
if (*p == '\0')

View File

@ -70,5 +70,23 @@ all: ..\foo
!,
'', ": '..\\foo'\n");
# Test escaped comments in variable assignments
run_make_test(q!
self = $1
foo := $(call self,#foo#)#foo
bar := $(call self,\#bar\#)#bar
all:;@echo '$(foo) $(bar)'
!,
'',"#foo# \\#bar\\#");
# Test escaped comments in variable assignments in a variable
run_make_test(q!
C = \#
self = $1
foo := $(call self,$Cfoo$C)#foo
all:;@echo '$(foo)'
!,
'',"#foo#");
# This tells the test driver that the perl test script executed properly.
1;

View File

@ -36,6 +36,20 @@ x:;@echo '$(guile #f)'; \
!,
'', "\n#t\nc\n1234\nfoo\nbar\na b\na b c d 1 2 3");
# Verify guile functions in variables -- SV 43378
run_make_test(q!
res := $(guile #f) \
$(guile #t) \
$(guile #\c) \
$(guile 1234) \
$(guile 'foo) \
$(guile "bar") \
$(guile (cons 'a 'b)) \
$(guile '(a b (c . d) 1 (2) 3))
x:;@echo '$(res)'
!,
'', " #t c 1234 foo bar a b a b c d 1 2 3");
# Verify the gmk-expand function
run_make_test(q!
VAR = $(guile (gmk-expand "$(shell echo hi)"))

View File

@ -27,13 +27,11 @@ all: ; @echo PRE=$(PRE) OK=$(OK) BAD=$(BAD)
# Test unescaped comment characters in shells. Savannah bug #20513
if ($all_tests) {
run_make_test(q!
run_make_test(q!
FOO := $(shell echo '#')
foo: ; echo '$(FOO)'
!,
'', "#\n");
}
'', "echo '#'\n#\n");
# Test shells inside exported environment variables.
# This is the test that fails if we try to put make exported variables into