Improve handling for escaped colons in prerequisite lists.

Fixes Savannah bug #12126 and bug #16545
This commit is contained in:
Paul Smith 2012-03-04 16:53:50 +00:00
parent 76827d7c10
commit cf1c79c9a3
5 changed files with 87 additions and 16 deletions

View File

@ -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
View File

@ -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 *

View File

@ -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.

View File

@ -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;

View File

@ -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;