mirror of
https://github.com/mirror/make.git
synced 2026-08-12 22:16:11 +00:00
[SV 62278] Only expand the first pattern during secondary expansion
During normal pattern rule expansion only the first pattern (%) is expanded; however during secondary expansion all patterns were expanded. Modify secondary expansion to match the behavior of normal expansion. Implementation tweaked by Paul Smith <psmith@gnu.org> * src/file.c (expand_deps): Don't use subst_expand() which replaces all % with $*: instead replace only the first one, by hand. Fix a memory leak where the dep structure was not always freed. * tests/scripts/features/statipattrules: Use .RECIPEPREFIX not TAB. Add a series of tests verifying that static pattern rules with and without secondary expansion both return the same results.
This commit is contained in:
committed by
Paul Smith
parent
93fd0c0c9a
commit
bb21dd4d2d
71
src/file.c
71
src/file.c
@@ -572,6 +572,7 @@ expand_deps (struct file *f)
|
||||
struct dep *d;
|
||||
struct dep **dp;
|
||||
const char *file_stem = f->stem;
|
||||
const char *fstem;
|
||||
int initialized = 0;
|
||||
|
||||
f->updating = 0;
|
||||
@@ -584,7 +585,6 @@ expand_deps (struct file *f)
|
||||
{
|
||||
char *p;
|
||||
struct dep *new, *next;
|
||||
char *name = (char *)d->name;
|
||||
|
||||
if (! d->name || ! d->need_2nd_expansion)
|
||||
{
|
||||
@@ -594,15 +594,47 @@ expand_deps (struct file *f)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If it's from a static pattern rule, convert the patterns into
|
||||
"$*" so they'll expand properly. */
|
||||
/* If it's from a static pattern rule, convert the initial pattern in
|
||||
each word to "$*" so they'll expand properly. */
|
||||
if (d->staticpattern)
|
||||
{
|
||||
char *o = subst_expand (variable_buffer, name, "%", "$*", 1, 2, 0);
|
||||
*o = '\0';
|
||||
free (name);
|
||||
d->name = name = xstrdup (variable_buffer);
|
||||
d->staticpattern = 0;
|
||||
const char *cs = d->name;
|
||||
size_t nperc = 0;
|
||||
|
||||
/* Count the number of % in the string. */
|
||||
while ((cs = strchr (cs, '%')) != NULL)
|
||||
{
|
||||
++nperc;
|
||||
++cs;
|
||||
}
|
||||
|
||||
if (nperc)
|
||||
{
|
||||
/* Allocate enough space to replace all % with $*. */
|
||||
size_t slen = strlen (d->name) + nperc + 1;
|
||||
const char *pcs = d->name;
|
||||
char *name = xmalloc (slen);
|
||||
char *s = name;
|
||||
|
||||
/* Substitute the first % in each word. */
|
||||
cs = strchr (pcs, '%');
|
||||
|
||||
while (cs)
|
||||
{
|
||||
memcpy (s, pcs, cs - pcs);
|
||||
s += cs - pcs;
|
||||
*(s++) = '$';
|
||||
*(s++) = '*';
|
||||
pcs = ++cs;
|
||||
|
||||
/* Find the first % after the next whitespace. */
|
||||
cs = strchr (end_of_token (cs), '%');
|
||||
}
|
||||
strcpy (s, pcs);
|
||||
|
||||
free ((char*)d->name);
|
||||
d->name = name;
|
||||
}
|
||||
}
|
||||
|
||||
/* We're going to do second expansion so initialize file variables for
|
||||
@@ -621,14 +653,14 @@ expand_deps (struct file *f)
|
||||
|
||||
p = variable_expand_for_file (d->name, f);
|
||||
|
||||
/* Free the un-expanded name. */
|
||||
free ((char*)d->name);
|
||||
|
||||
if (d->stem != 0)
|
||||
f->stem = file_stem;
|
||||
|
||||
/* At this point we don't need the name anymore: free it. */
|
||||
free (name);
|
||||
|
||||
/* Parse the prerequisites and enter them into the file database. */
|
||||
new = enter_prereqs (split_prereqs (p), d->stem);
|
||||
new = split_prereqs (p);
|
||||
|
||||
/* If there were no prereqs here (blank!) then throw this one out. */
|
||||
if (new == 0)
|
||||
@@ -640,10 +672,21 @@ expand_deps (struct file *f)
|
||||
}
|
||||
|
||||
/* Add newly parsed prerequisites. */
|
||||
fstem = d->stem;
|
||||
next = d->next;
|
||||
free_dep (d);
|
||||
*dp = new;
|
||||
for (dp = &new->next, d = new->next; d != 0; dp = &d->next, d = d->next)
|
||||
;
|
||||
for (dp = &new, d = new; d != 0; dp = &d->next, d = d->next)
|
||||
{
|
||||
d->file = lookup_file (d->name);
|
||||
if (d->file == 0)
|
||||
d->file = enter_file (d->name);
|
||||
d->name = 0;
|
||||
d->stem = fstem;
|
||||
if (!fstem)
|
||||
/* This file is explicitly mentioned as a prereq. */
|
||||
d->file->is_explicit = 1;
|
||||
}
|
||||
*dp = next;
|
||||
d = *dp;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user