[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.
diff --git a/NEWS b/NEWS
index d3059ae..0dab2ee 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,20 @@
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.
diff --git a/main.c b/main.c
index 80c17da..aa3d80d 100644
--- a/main.c
+++ b/main.c
@@ -1321,7 +1321,7 @@
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
diff --git a/read.c b/read.c
index e8b505d..26ba6f9 100644
--- a/read.c
+++ b/read.c
@@ -1398,14 +1398,15 @@
/* 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 @@
}
}
-/* 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')
diff --git a/tests/scripts/features/escape b/tests/scripts/features/escape
index bf069df..de0ef48 100644
--- a/tests/scripts/features/escape
+++ b/tests/scripts/features/escape
@@ -70,5 +70,23 @@
!,
'', ": '..\\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;
diff --git a/tests/scripts/functions/guile b/tests/scripts/functions/guile
index c63bec9..415827a 100644
--- a/tests/scripts/functions/guile
+++ b/tests/scripts/functions/guile
@@ -36,6 +36,20 @@
!,
'', "\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)"))
diff --git a/tests/scripts/functions/shell b/tests/scripts/functions/shell
index 809c77f..0a549a7 100644
--- a/tests/scripts/functions/shell
+++ b/tests/scripts/functions/shell
@@ -27,13 +27,11 @@
# 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