mirror of
https://github.com/mirror/make.git
synced 2025-01-27 04:40:33 +08: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
@ -1,5 +1,9 @@
|
||||
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.
|
||||
* main.c: Use the new macro.
|
||||
* read.c: Ditto.
|
||||
|
75
read.c
75
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 char *find_char_unquote (char *string, int stop1, int stop2,
|
||||
int blank, int ignorevars);
|
||||
static char *unescape_char (char *string, int c);
|
||||
|
||||
|
||||
/* Compare a word, both length and contents.
|
||||
@ -1872,24 +1873,28 @@ record_files (struct nameseq *filenames, const char *pattern,
|
||||
expansion: if so, snap_deps() will do it. */
|
||||
if (depstr == 0)
|
||||
deps = 0;
|
||||
else if (second_expansion && strchr (depstr, '$'))
|
||||
{
|
||||
deps = alloc_dep ();
|
||||
deps->name = depstr;
|
||||
deps->need_2nd_expansion = 1;
|
||||
deps->staticpattern = pattern != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
deps = split_prereqs (depstr);
|
||||
free (depstr);
|
||||
depstr = unescape_char (depstr, ':');
|
||||
if (second_expansion && strchr (depstr, '$'))
|
||||
{
|
||||
deps = alloc_dep ();
|
||||
deps->name = depstr;
|
||||
deps->need_2nd_expansion = 1;
|
||||
deps->staticpattern = pattern != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
deps = split_prereqs (depstr);
|
||||
free (depstr);
|
||||
|
||||
/* We'll enter static pattern prereqs later when we have the stem. We
|
||||
don't want to enter pattern rules at all so that we don't think that
|
||||
they ought to exist (make manual "Implicit Rule Search Algorithm",
|
||||
item 5c). */
|
||||
if (! pattern && ! implicit_percent)
|
||||
deps = enter_prereqs (deps, NULL);
|
||||
/* We'll enter static pattern prereqs later when we have the stem.
|
||||
We don't want to enter pattern rules at all so that we don't
|
||||
think that they ought to exist (make manual "Implicit Rule Search
|
||||
Algorithm", item 5c). */
|
||||
if (! pattern && ! implicit_percent)
|
||||
deps = enter_prereqs (deps, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* For implicit rules, _all_ the targets must have a pattern. That means we
|
||||
@ -2211,6 +2216,46 @@ find_char_unquote (char *string, int stop1, int stop2, int blank,
|
||||
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. */
|
||||
|
||||
char *
|
||||
|
@ -1,5 +1,11 @@
|
||||
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
|
||||
pattern-specific target rules. See Savannah bug #35468.
|
||||
|
||||
|
@ -54,5 +54,13 @@ run_make_test(undef,
|
||||
'sharp',
|
||||
'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.
|
||||
1;
|
||||
|
@ -152,5 +152,13 @@ a%l: q1x $$+ q2x ; @echo '$+'
|
||||
'', "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;
|
||||
|
Loading…
Reference in New Issue
Block a user