mirror of
https://salsa.debian.org/srivasta/make-dfsg.git
synced 2024-12-29 00:05:59 +00:00
Fixed Savannah bug #16053.
This commit is contained in:
parent
50eb3cf5e5
commit
22886f8a74
11 changed files with 138 additions and 63 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2006-03-17 Boris Kolpackov <boris@kolpackov.net>
|
||||
|
||||
* dep.h (struct dep): Add the stem field.
|
||||
* misc.c (alloc_dep, free_dep): New functions.
|
||||
(copy_dep_chain): Copy stem.
|
||||
(free_dep_chain): Use free_dep.
|
||||
* read.c (record_files): Store stem in the dependency line.
|
||||
* file.c (expand_deps): Use stem stored in the dependency line. Use
|
||||
free_dep_chain instead of free_ns_chain.
|
||||
* implicit.c (pattern_search): Use alloc_dep and free_dep.
|
||||
* read.c (read_all_makefiles, eval_makefile, eval): Ditto.
|
||||
* main.c (main, handle_non_switch_argument): Ditto.
|
||||
* remake.c (check_dep): Ditto.
|
||||
* rule.c (convert_suffix_rule, freerule): Ditto.
|
||||
|
||||
2006-03-14 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* expand.c (variable_append): Instead of appending everything then
|
||||
|
@ -155,7 +170,7 @@
|
|||
|
||||
2006-02-08 Boris Kolpackov <boris@kolpackov.net>
|
||||
|
||||
* job.h (struct child): Add dontcare bitfield.
|
||||
* job.h (struct child): Add the dontcare bitfield.
|
||||
* job.c (new_job): Cache dontcare flag.
|
||||
* job.c (reap_children): Use cached dontcare flag instead of the
|
||||
one in struct file. Fixes Savannah bug #15641.
|
||||
|
|
6
dep.h
6
dep.h
|
@ -28,7 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
|
|||
|
||||
/* Structure representing one dependency of a file.
|
||||
Each struct file's `deps' points to a chain of these,
|
||||
chained through the `next'.
|
||||
chained through the `next'. `stem' is the stem for this
|
||||
dep line of static pattern rule or NULL.
|
||||
|
||||
Note that the first two words of this match a struct nameseq. */
|
||||
|
||||
|
@ -36,6 +37,7 @@ struct dep
|
|||
{
|
||||
struct dep *next;
|
||||
char *name;
|
||||
char *stem;
|
||||
struct file *file;
|
||||
unsigned int changed : 8;
|
||||
unsigned int ignore_mtime : 1;
|
||||
|
@ -72,6 +74,8 @@ extern struct nameseq *ar_glob PARAMS ((char *arname, char *member_pattern, unsi
|
|||
extern char *dep_name ();
|
||||
#endif
|
||||
|
||||
extern struct dep *alloc_dep PARAMS ((void));
|
||||
extern void free_dep PARAMS ((struct dep *d));
|
||||
extern struct dep *copy_dep_chain PARAMS ((const struct dep *d));
|
||||
extern void free_dep_chain PARAMS ((struct dep *d));
|
||||
extern void free_ns_chain PARAMS ((struct nameseq *n));
|
||||
|
|
24
file.c
24
file.c
|
@ -460,6 +460,7 @@ expand_deps (struct file *f)
|
|||
{
|
||||
struct dep *d;
|
||||
struct dep *old = f->deps;
|
||||
char *file_stem = f->stem;
|
||||
unsigned int last_dep_has_cmds = f->updating;
|
||||
int initialized = 0;
|
||||
|
||||
|
@ -491,20 +492,29 @@ expand_deps (struct file *f)
|
|||
|
||||
free (d->name);
|
||||
d->name = savestring (buffer, o - buffer);
|
||||
d->staticpattern = 0;
|
||||
d->staticpattern = 0; /* Clear staticpattern so that we don't
|
||||
re-expand %s below. */
|
||||
}
|
||||
|
||||
/* We are going to do second expansion so initialize file variables
|
||||
for the file. */
|
||||
for the file. Since the stem for static pattern rules comes from
|
||||
individual dep lines, we will temporarily set f->stem to d->stem.
|
||||
*/
|
||||
if (!initialized)
|
||||
{
|
||||
initialize_file_variables (f, 0);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
if (d->stem != 0)
|
||||
f->stem = d->stem;
|
||||
|
||||
set_file_variables (f);
|
||||
|
||||
p = variable_expand_for_file (d->name, f);
|
||||
|
||||
if (d->stem != 0)
|
||||
f->stem = file_stem;
|
||||
}
|
||||
|
||||
/* Parse the prerequisites. */
|
||||
|
@ -527,12 +537,12 @@ expand_deps (struct file *f)
|
|||
/* We have to handle empty stems specially, because that
|
||||
would be equivalent to $(patsubst %,dp->name,) which
|
||||
will always be empty. */
|
||||
if (f->stem[0] == '\0')
|
||||
if (d->stem[0] == '\0')
|
||||
/* This needs memmove() in ISO C. */
|
||||
bcopy (percent+1, percent, strlen (percent));
|
||||
else
|
||||
{
|
||||
char *o = patsubst_expand (buffer, f->stem, pattern,
|
||||
char *o = patsubst_expand (buffer, d->stem, pattern,
|
||||
dp->name, pattern+1,
|
||||
percent+1);
|
||||
if (o == buffer)
|
||||
|
@ -552,7 +562,9 @@ expand_deps (struct file *f)
|
|||
dp = new = new->next;
|
||||
else
|
||||
dp = dl->next = dp->next;
|
||||
free ((char *)df);
|
||||
/* @@ Are we leaking df->name here? */
|
||||
df->name = 0;
|
||||
free_dep (df);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -604,7 +616,7 @@ expand_deps (struct file *f)
|
|||
}
|
||||
}
|
||||
|
||||
free_ns_chain ((struct nameseq *) old);
|
||||
free_dep_chain (old);
|
||||
}
|
||||
|
||||
/* For each dependency of each file, make the `struct dep' point
|
||||
|
|
17
implicit.c
17
implicit.c
|
@ -802,8 +802,7 @@ pattern_search (struct file *file, int archive,
|
|||
while (dep != 0)
|
||||
{
|
||||
struct dep *next = dep->next;
|
||||
free (dep->name);
|
||||
free ((char *)dep);
|
||||
free_dep (dep);
|
||||
dep = next;
|
||||
}
|
||||
file->deps = 0;
|
||||
|
@ -862,15 +861,12 @@ pattern_search (struct file *file, int archive,
|
|||
}
|
||||
}
|
||||
|
||||
dep = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
dep = alloc_dep ();
|
||||
dep->ignore_mtime = d->ignore_mtime;
|
||||
dep->staticpattern = 0;
|
||||
dep->need_2nd_expansion = 0;
|
||||
s = d->name; /* Hijacking the name. */
|
||||
d->name = 0;
|
||||
if (recursions == 0)
|
||||
{
|
||||
dep->name = 0;
|
||||
dep->file = lookup_file (s);
|
||||
if (dep->file == 0)
|
||||
/* enter_file consumes S's storage. */
|
||||
|
@ -883,9 +879,8 @@ pattern_search (struct file *file, int archive,
|
|||
else
|
||||
{
|
||||
dep->name = s;
|
||||
dep->file = 0;
|
||||
dep->changed = 0;
|
||||
}
|
||||
|
||||
if (d->intermediate_file == 0 && tryrules[foundrule]->terminal)
|
||||
{
|
||||
/* If the file actually existed (was not an intermediate file),
|
||||
|
@ -943,11 +938,9 @@ pattern_search (struct file *file, int archive,
|
|||
if (i != matches[foundrule])
|
||||
{
|
||||
struct file *f;
|
||||
struct dep *new = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
struct dep *new = alloc_dep ();
|
||||
|
||||
/* GKM FIMXE: handle '|' here too */
|
||||
new->ignore_mtime = 0;
|
||||
new->staticpattern = 0;
|
||||
new->need_2nd_expansion = 0;
|
||||
new->name = p = (char *) xmalloc (rule->lens[i] + fullstemlen + 1);
|
||||
bcopy (rule->targets[i], p,
|
||||
rule->suffixes[i] - rule->targets[i] - 1);
|
||||
|
|
18
main.c
18
main.c
|
@ -1850,7 +1850,7 @@ main (int argc, char **argv, char **envp)
|
|||
last->next = d->next;
|
||||
|
||||
/* Free the storage. */
|
||||
free ((char *) d);
|
||||
free_dep (d);
|
||||
|
||||
d = last == 0 ? read_makefiles : last->next;
|
||||
|
||||
|
@ -2172,12 +2172,7 @@ main (int argc, char **argv, char **envp)
|
|||
}
|
||||
}
|
||||
|
||||
goals = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
goals->next = 0;
|
||||
goals->name = 0;
|
||||
goals->ignore_mtime = 0;
|
||||
goals->staticpattern = 0;
|
||||
goals->need_2nd_expansion = 0;
|
||||
goals = alloc_dep ();
|
||||
goals->file = default_goal_file;
|
||||
}
|
||||
}
|
||||
|
@ -2333,19 +2328,16 @@ handle_non_switch_argument (char *arg, int env)
|
|||
|
||||
if (goals == 0)
|
||||
{
|
||||
goals = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
goals = alloc_dep ();
|
||||
lastgoal = goals;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastgoal->next = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
lastgoal->next = alloc_dep ();
|
||||
lastgoal = lastgoal->next;
|
||||
}
|
||||
lastgoal->name = 0;
|
||||
|
||||
lastgoal->file = f;
|
||||
lastgoal->ignore_mtime = 0;
|
||||
lastgoal->staticpattern = 0;
|
||||
lastgoal->need_2nd_expansion = 0;
|
||||
|
||||
{
|
||||
/* Add this target name to the MAKECMDGOALS variable. */
|
||||
|
|
36
misc.c
36
misc.c
|
@ -479,6 +479,32 @@ find_next_token (char **ptr, unsigned int *lengthptr)
|
|||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a new `struct dep' with all fields initialized to 0. */
|
||||
|
||||
struct dep *
|
||||
alloc_dep ()
|
||||
{
|
||||
struct dep *d = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
bzero ((char *) d, sizeof (struct dep));
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
/* Free `struct dep' along with `name' and `stem'. */
|
||||
|
||||
void
|
||||
free_dep (struct dep *d)
|
||||
{
|
||||
if (d->name != 0)
|
||||
free (d->name);
|
||||
|
||||
if (d->stem != 0)
|
||||
free (d->stem);
|
||||
|
||||
free ((char *)d);
|
||||
}
|
||||
|
||||
/* Copy a chain of `struct dep', making a new chain
|
||||
with the same contents as the old one. */
|
||||
|
||||
|
@ -493,8 +519,12 @@ copy_dep_chain (const struct dep *d)
|
|||
{
|
||||
c = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
bcopy ((char *) d, (char *) c, sizeof (struct dep));
|
||||
|
||||
if (c->name != 0)
|
||||
c->name = xstrdup (c->name);
|
||||
if (c->stem != 0)
|
||||
c->stem = xstrdup (c->stem);
|
||||
|
||||
c->next = 0;
|
||||
if (firstnew == 0)
|
||||
firstnew = lastnew = c;
|
||||
|
@ -516,14 +546,12 @@ free_dep_chain (struct dep *d)
|
|||
{
|
||||
struct dep *df = d;
|
||||
d = d->next;
|
||||
|
||||
free (df->name);
|
||||
free ((char *)df);
|
||||
free_dep (df);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free a chain of `struct nameseq'. Each nameseq->name is freed
|
||||
as well. Can be used on `struct dep' chains.*/
|
||||
as well. For `struct dep' chains use free_dep_chain. */
|
||||
|
||||
void
|
||||
free_ns_chain (struct nameseq *n)
|
||||
|
|
25
read.c
25
read.c
|
@ -248,13 +248,9 @@ read_all_makefiles (char **makefiles)
|
|||
tail = tail->next;
|
||||
for (p = default_makefiles; *p != 0; ++p)
|
||||
{
|
||||
struct dep *d = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
d->name = 0;
|
||||
struct dep *d = alloc_dep ();
|
||||
d->file = enter_file (*p);
|
||||
d->file->dontcare = 1;
|
||||
d->ignore_mtime = 0;
|
||||
d->staticpattern = 0;
|
||||
d->need_2nd_expansion = 0;
|
||||
/* Tell update_goal_chain to bail out as soon as this file is
|
||||
made, and main not to die if we can't make this file. */
|
||||
d->changed = RM_DONTCARE;
|
||||
|
@ -366,18 +362,14 @@ eval_makefile (char *filename, int flags)
|
|||
}
|
||||
|
||||
/* Add FILENAME to the chain of read makefiles. */
|
||||
deps = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
deps = alloc_dep ();
|
||||
deps->next = read_makefiles;
|
||||
read_makefiles = deps;
|
||||
deps->name = 0;
|
||||
deps->file = lookup_file (filename);
|
||||
if (deps->file == 0)
|
||||
deps->file = enter_file (xstrdup (filename));
|
||||
filename = deps->file->name;
|
||||
deps->changed = flags;
|
||||
deps->ignore_mtime = 0;
|
||||
deps->staticpattern = 0;
|
||||
deps->need_2nd_expansion = 0;
|
||||
if (flags & RM_DONTCARE)
|
||||
deps->file->dontcare = 1;
|
||||
|
||||
|
@ -1177,14 +1169,8 @@ eval (struct ebuffer *ebuf, int set_default)
|
|||
if (beg <= end && *beg != '\0')
|
||||
{
|
||||
/* Put all the prerequisites here; they'll be parsed later. */
|
||||
deps = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
deps->next = 0;
|
||||
deps = alloc_dep ();
|
||||
deps->name = savestring (beg, end - beg + 1);
|
||||
deps->file = 0;
|
||||
deps->changed = 0;
|
||||
deps->ignore_mtime = 0;
|
||||
deps->staticpattern = 0;
|
||||
deps->need_2nd_expansion = 0;
|
||||
}
|
||||
else
|
||||
deps = 0;
|
||||
|
@ -2111,7 +2097,10 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
|
|||
pattern_percent+1, percent+1);
|
||||
f->stem = savestring (buffer, o - buffer);
|
||||
if (this)
|
||||
this->staticpattern = 1;
|
||||
{
|
||||
this->staticpattern = 1;
|
||||
this->stem = xstrdup (f->stem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free name if not needed further. */
|
||||
|
|
4
remake.c
4
remake.c
|
@ -994,13 +994,13 @@ check_dep (struct file *file, unsigned int depth,
|
|||
if (lastd == 0)
|
||||
{
|
||||
file->deps = d->next;
|
||||
free ((char *) d);
|
||||
free_dep (d);
|
||||
d = file->deps;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastd->next = d->next;
|
||||
free ((char *) d);
|
||||
free_dep (d);
|
||||
d = lastd->next;
|
||||
}
|
||||
continue;
|
||||
|
|
9
rule.c
9
rule.c
|
@ -201,12 +201,8 @@ convert_suffix_rule (char *target, char *source, struct commands *cmds)
|
|||
depname = xmalloc (1 + len + 1);
|
||||
depname[0] = '%';
|
||||
bcopy (source, depname + 1, len + 1);
|
||||
deps = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
deps->next = 0;
|
||||
deps = alloc_dep ();
|
||||
deps->name = depname;
|
||||
deps->ignore_mtime = 0;
|
||||
deps->staticpattern = 0;
|
||||
deps->need_2nd_expansion = 0;
|
||||
}
|
||||
|
||||
create_pattern_rule (names, percents, 0, deps, cmds, 0);
|
||||
|
@ -428,7 +424,8 @@ freerule (struct rule *rule, struct rule *lastrule)
|
|||
t = dep->next;
|
||||
/* We might leak dep->name here, but I'm not sure how to fix this: I
|
||||
think that pointer might be shared (e.g., in the file hash?) */
|
||||
free ((char *) dep);
|
||||
dep->name = 0; /* Make sure free_dep does not free name. */
|
||||
free_dep (dep);
|
||||
dep = t;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2006-03-17 Boris Kolpackov <boris@kolpackov.net>
|
||||
|
||||
* scripts/features/statipattrules: Add tests for bug #16053.
|
||||
|
||||
2006-03-09 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/escape: Use "pre:" not "p:" to avoid conflicts
|
||||
|
|
|
@ -67,4 +67,45 @@ foo.baz: ;@:
|
|||
',
|
||||
'', '');
|
||||
|
||||
|
||||
# TEST #6: make sure the second stem does not overwrite the first
|
||||
# perprerequisite's stem (Savannah bug #16053).
|
||||
#
|
||||
run_make_test('
|
||||
all.foo.bar: %.foo.bar: %.one
|
||||
|
||||
all.foo.bar: %.bar: %.two
|
||||
|
||||
all.foo.bar:
|
||||
@echo $*
|
||||
@echo $^
|
||||
|
||||
.DEFAULT:;@:
|
||||
',
|
||||
'',
|
||||
'all.foo
|
||||
all.one all.foo.two');
|
||||
|
||||
|
||||
# TEST #7: make sure the second stem does not overwrite the first
|
||||
# perprerequisite's stem when second expansion is enabled
|
||||
# (Savannah bug #16053).
|
||||
#
|
||||
run_make_test('
|
||||
.SECONDEXPANSION:
|
||||
|
||||
all.foo.bar: %.foo.bar: %.one $$*-one
|
||||
|
||||
all.foo.bar: %.bar: %.two $$*-two
|
||||
|
||||
all.foo.bar:
|
||||
@echo $*
|
||||
@echo $^
|
||||
|
||||
.DEFAULT:;@:
|
||||
',
|
||||
'',
|
||||
'all.foo
|
||||
all.one all-one all.foo.two all.foo-two');
|
||||
|
||||
1;
|
||||
|
|
Loading…
Reference in a new issue