diff options
author | Boris Kolpackov <boris@kolpackov.net> | 2006-03-17 14:24:20 +0000 |
---|---|---|
committer | Boris Kolpackov <boris@kolpackov.net> | 2006-03-17 14:24:20 +0000 |
commit | 22886f8a74b5925030889fed52af5a8add5617d7 (patch) | |
tree | c28340c4ca8f7956e259f671b3202b6bf0874a35 | |
parent | 50eb3cf5e5a8a68b68e966a6607f668f2c36191e (diff) | |
download | gunmake-22886f8a74b5925030889fed52af5a8add5617d7.tar.gz |
Fixed Savannah bug #16053.
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | dep.h | 6 | ||||
-rw-r--r-- | file.c | 24 | ||||
-rw-r--r-- | implicit.c | 17 | ||||
-rw-r--r-- | main.c | 18 | ||||
-rw-r--r-- | misc.c | 36 | ||||
-rw-r--r-- | read.c | 25 | ||||
-rw-r--r-- | remake.c | 4 | ||||
-rw-r--r-- | rule.c | 9 | ||||
-rw-r--r-- | tests/ChangeLog | 4 | ||||
-rw-r--r-- | tests/scripts/features/statipattrules | 41 |
11 files changed, 138 insertions, 63 deletions
@@ -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. @@ -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)); @@ -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 @@ -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); @@ -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. */ @@ -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) @@ -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. */ @@ -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; @@ -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; } diff --git a/tests/ChangeLog b/tests/ChangeLog index 05dfaec..67cf900 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -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 diff --git a/tests/scripts/features/statipattrules b/tests/scripts/features/statipattrules index 429b56a..3f363de 100644 --- a/tests/scripts/features/statipattrules +++ b/tests/scripts/features/statipattrules @@ -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; |