mirror of
https://git.savannah.gnu.org/git/make.git
synced 2025-02-05 14:07:46 +00:00
Improve handling for escaped colons in prerequisite lists.
Fixes Savannah bug #12126 and bug #16545
This commit is contained in:
parent
76827d7c10
commit
cf1c79c9a3
5 changed files with 87 additions and 16 deletions
|
@ -1,5 +1,9 @@
|
||||||
2012-03-04 Paul Smith <psmith@gnu.org>
|
2012-03-04 Paul Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
* read.c (unescape_char): New function to remove escapes from a char.
|
||||||
|
(record_files): Call it on the dependency string to unescape ":".
|
||||||
|
Fixes Savannah bug #12126 and bug #16545.
|
||||||
|
|
||||||
* make.h (CSTRLEN): Determine the length of a constant string.
|
* make.h (CSTRLEN): Determine the length of a constant string.
|
||||||
* main.c: Use the new macro.
|
* main.c: Use the new macro.
|
||||||
* read.c: Ditto.
|
* read.c: Ditto.
|
||||||
|
|
55
read.c
55
read.c
|
@ -156,6 +156,7 @@ static enum make_word_type get_next_mword (char *buffer, char *delim,
|
||||||
static void remove_comments (char *line);
|
static void remove_comments (char *line);
|
||||||
static char *find_char_unquote (char *string, int stop1, int stop2,
|
static char *find_char_unquote (char *string, int stop1, int stop2,
|
||||||
int blank, int ignorevars);
|
int blank, int ignorevars);
|
||||||
|
static char *unescape_char (char *string, int c);
|
||||||
|
|
||||||
|
|
||||||
/* Compare a word, both length and contents.
|
/* Compare a word, both length and contents.
|
||||||
|
@ -1872,7 +1873,10 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||||
expansion: if so, snap_deps() will do it. */
|
expansion: if so, snap_deps() will do it. */
|
||||||
if (depstr == 0)
|
if (depstr == 0)
|
||||||
deps = 0;
|
deps = 0;
|
||||||
else if (second_expansion && strchr (depstr, '$'))
|
else
|
||||||
|
{
|
||||||
|
depstr = unescape_char (depstr, ':');
|
||||||
|
if (second_expansion && strchr (depstr, '$'))
|
||||||
{
|
{
|
||||||
deps = alloc_dep ();
|
deps = alloc_dep ();
|
||||||
deps->name = depstr;
|
deps->name = depstr;
|
||||||
|
@ -1884,13 +1888,14 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||||
deps = split_prereqs (depstr);
|
deps = split_prereqs (depstr);
|
||||||
free (depstr);
|
free (depstr);
|
||||||
|
|
||||||
/* We'll enter static pattern prereqs later when we have the stem. We
|
/* We'll enter static pattern prereqs later when we have the stem.
|
||||||
don't want to enter pattern rules at all so that we don't think that
|
We don't want to enter pattern rules at all so that we don't
|
||||||
they ought to exist (make manual "Implicit Rule Search Algorithm",
|
think that they ought to exist (make manual "Implicit Rule Search
|
||||||
item 5c). */
|
Algorithm", item 5c). */
|
||||||
if (! pattern && ! implicit_percent)
|
if (! pattern && ! implicit_percent)
|
||||||
deps = enter_prereqs (deps, NULL);
|
deps = enter_prereqs (deps, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* For implicit rules, _all_ the targets must have a pattern. That means we
|
/* For implicit rules, _all_ the targets must have a pattern. That means we
|
||||||
can test the first one to see if we're working with an implicit rule; if
|
can test the first one to see if we're working with an implicit rule; if
|
||||||
|
@ -2211,6 +2216,46 @@ find_char_unquote (char *string, int stop1, int stop2, int blank,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unescape a character in a string. The string is compressed onto itself. */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
unescape_char (char *string, int c)
|
||||||
|
{
|
||||||
|
char *p = string;
|
||||||
|
char *s = string;
|
||||||
|
|
||||||
|
while (*s != '\0')
|
||||||
|
{
|
||||||
|
if (*s == '\\')
|
||||||
|
{
|
||||||
|
char *e = s;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
/* We found a backslash. See if it's escaping our character. */
|
||||||
|
while (*e == '\\')
|
||||||
|
++e;
|
||||||
|
l = e - s;
|
||||||
|
|
||||||
|
if (*e != c || l%2 == 0)
|
||||||
|
/* It's not; just take it all without unescaping. */
|
||||||
|
memcpy (p, s, l);
|
||||||
|
else if (l > 1)
|
||||||
|
{
|
||||||
|
/* It is, and there's >1 backslash. Take half of them. */
|
||||||
|
l /= 2;
|
||||||
|
memcpy (p, s, l);
|
||||||
|
p += l;
|
||||||
|
}
|
||||||
|
s = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(p++) = *(s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
/* Search PATTERN for an unquoted % and handle quoting. */
|
/* Search PATTERN for an unquoted % and handle quoting. */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
2012-03-04 Paul Smith <psmith@gnu.org>
|
2012-03-04 Paul Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
* scripts/features/se_explicit: Test $(x:%=%) format in secondary
|
||||||
|
expansion prerequisite lists. See Savannah bug #16545.
|
||||||
|
|
||||||
|
* scripts/features/escape: Test escaped ":" in prerequisite lists.
|
||||||
|
See Savannah bug #12126.
|
||||||
|
|
||||||
* scripts/variables/private: Test appending private variables in
|
* scripts/variables/private: Test appending private variables in
|
||||||
pattern-specific target rules. See Savannah bug #35468.
|
pattern-specific target rules. See Savannah bug #35468.
|
||||||
|
|
||||||
|
|
|
@ -54,5 +54,13 @@ run_make_test(undef,
|
||||||
'sharp',
|
'sharp',
|
||||||
'foo#bar.ext = (foo#bar.ext)');
|
'foo#bar.ext = (foo#bar.ext)');
|
||||||
|
|
||||||
|
# Test escaped colons in prerequisites
|
||||||
|
# Quoting of backslashes in q!! is kind of messy.
|
||||||
|
run_make_test(q!
|
||||||
|
foo: foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar
|
||||||
|
foo foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar: ; @echo '$@'
|
||||||
|
!,
|
||||||
|
'', "foo:bar\nfoo\\:bar\nfoo\\\\:bar\nfoo\n");
|
||||||
|
|
||||||
# This tells the test driver that the perl test script executed properly.
|
# This tells the test driver that the perl test script executed properly.
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -152,5 +152,13 @@ a%l: q1x $$+ q2x ; @echo '$+'
|
||||||
'', "q1x bar bar q2x bar bar\n");
|
'', "q1x bar bar q2x bar bar\n");
|
||||||
|
|
||||||
|
|
||||||
# This tells the test driver that the perl test script executed properly.
|
# Allow patsubst shorthand in second expansion context.
|
||||||
|
# Requires the colon to be quoted. Savannah bug #16545
|
||||||
|
run_make_test(q!
|
||||||
|
.PHONY: foo.bar
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
foo: $$(@\\:%=%.bar); @echo '$^'
|
||||||
|
!,
|
||||||
|
'', "foo.bar\n");
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
Loading…
Reference in a new issue