From 40a49f244da5b417af8bede84ac221cee2318d88 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Mon, 22 Jul 2013 02:19:13 -0400 Subject: [PATCH] [Bug #39310] Parse simple pattern prereqs for globbing. We tried to get some efficiency by avoiding a parse_file_seq() for simple pattern prerequisites, but this also means no wildcard expansion was happening, so add it back. Add regression tests for wildcards in target and prerequisite lists. --- ChangeLog | 14 ++++++++++++ default.c | 5 ++--- dep.h | 2 ++ file.c | 5 +++-- implicit.c | 23 ++++++++++---------- main.c | 2 +- read.c | 2 +- rule.c | 2 +- tests/ChangeLog | 5 +++++ tests/scripts/features/rule_glob | 37 ++++++++++++++++++++++++++++++++ 10 files changed, 78 insertions(+), 19 deletions(-) create mode 100644 tests/scripts/features/rule_glob diff --git a/ChangeLog b/ChangeLog index 608f8702..f8ab2cac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2013-07-22 Paul Smith + + * implicit.c (pattern_search): Use PARSE_SIMPLE_SEQ() even for + non-second expansion prerequisites, to handle globbing in patterns. + Fixes Savannah bug #39310. + + * dep.h (PARSE_SIMPLE_SEQ): Macro for simple file sequence parsing. + * default.c (set_default_suffixes): Use it. + * file.c (split_prereqs): Ditto. + * main.c (main): Ditto. + * read.c (eval): Ditto. + * rule.c (install_pattern_rule): Ditto. + * file.c (split_prereqs): Use PARSEFS_NONE instead of 0. + 2013-07-21 Paul Smith Cleanups detected by cppcheck. Fixes Savannah bug #39158. diff --git a/default.c b/default.c index 32b878a9..47b7dd34 100644 --- a/default.c +++ b/default.c @@ -547,9 +547,8 @@ set_default_suffixes (void) { struct dep *d; char *p = default_suffixes; - suffix_file->deps = enter_prereqs (PARSE_FILE_SEQ (&p, struct dep, MAP_NUL, - NULL, 0), - NULL); + suffix_file->deps = enter_prereqs (PARSE_SIMPLE_SEQ (&p, struct dep), + NULL); for (d = suffix_file->deps; d; d = d->next) d->file->builtin = 1; diff --git a/dep.h b/dep.h index 4abfefe3..13cefdc5 100644 --- a/dep.h +++ b/dep.h @@ -62,6 +62,8 @@ struct nameseq #define PARSE_FILE_SEQ(_s,_t,_c,_p,_f) \ (_t *)parse_file_seq ((_s),sizeof (_t),(_c),(_p),(_f)) +#define PARSE_SIMPLE_SEQ(_s,_t) \ + (_t *)parse_file_seq ((_s),sizeof (_t),MAP_NUL,NULL,PARSEFS_NONE) #ifdef VMS void *parse_file_seq (); diff --git a/file.c b/file.c index 25ddde7c..c8e19e58 100644 --- a/file.c +++ b/file.c @@ -430,7 +430,8 @@ remove_intermediates (int sig) struct dep * split_prereqs (char *p) { - struct dep *new = PARSE_FILE_SEQ (&p, struct dep, MAP_PIPE, NULL, 0); + struct dep *new = PARSE_FILE_SEQ (&p, struct dep, MAP_PIPE, NULL, + PARSEFS_NONE); if (*p) { @@ -439,7 +440,7 @@ split_prereqs (char *p) struct dep *ood; ++p; - ood = PARSE_FILE_SEQ (&p, struct dep, MAP_NUL, NULL, 0); + ood = PARSE_SIMPLE_SEQ (&p, struct dep); if (! new) new = ood; diff --git a/implicit.c b/implicit.c index 6d2e09b3..f0bb3854 100644 --- a/implicit.c +++ b/implicit.c @@ -249,8 +249,6 @@ pattern_search (struct file *file, int archive, that is not just '%'. */ int specific_rule_matched = 0; - struct dep dep_simple; - unsigned int ri; /* uninit checks OK */ struct rule *rule; @@ -532,11 +530,9 @@ pattern_search (struct file *file, int archive, /* If we don't need a second expansion, just replace the %. */ if (! dep->need_2nd_expansion) { - dep_simple = *dep; - dep_simple.next = 0; p = strchr (nptr, '%'); if (p == 0) - dep_simple.name = nptr; + strcpy (depname, nptr); else { char *o = depname; @@ -550,13 +546,19 @@ pattern_search (struct file *file, int archive, memcpy (o, stem_str, stemlen); o += stemlen; strcpy (o, p + 1); - dep_simple.name = strcache_add (depname); } - dl = &dep_simple; + + /* Parse the expanded string. It might have wildcards. */ + p = depname; + dl = PARSE_SIMPLE_SEQ (&p, struct dep); + for (d = dl; d != NULL; d = d->next) + { + ++deps_found; + d->ignore_mtime = dep->ignore_mtime; + } /* We've used up this dep, so next time get a new one. */ nptr = 0; - ++deps_found; } /* We have to perform second expansion on this prereq. In an @@ -635,7 +637,7 @@ pattern_search (struct file *file, int archive, /* Parse the expanded string. */ dl = PARSE_FILE_SEQ (&p, struct dep, order_only ? MAP_NUL : MAP_PIPE, - add_dir ? dir : NULL, 0); + add_dir ? dir : NULL, PARSEFS_NONE); for (d = dl; d != NULL; d = d->next) { @@ -781,8 +783,7 @@ pattern_search (struct file *file, int archive, } /* Free the ns chain. */ - if (dl != &dep_simple) - free_dep_chain (dl); + free_dep_chain (dl); if (failed) break; diff --git a/main.c b/main.c index 801365fa..2cfc49bf 100644 --- a/main.c +++ b/main.c @@ -2466,7 +2466,7 @@ main (int argc, char **argv, char **envp) { struct nameseq *ns; - ns = PARSE_FILE_SEQ (&p, struct nameseq, MAP_NUL, NULL, 0); + ns = PARSE_SIMPLE_SEQ (&p, struct nameseq); if (ns) { /* .DEFAULT_GOAL should contain one target. */ diff --git a/read.c b/read.c index bc78fa51..834c7f83 100644 --- a/read.c +++ b/read.c @@ -1107,7 +1107,7 @@ eval (struct ebuffer *ebuf, int set_default) /* Make the colon the end-of-string so we know where to stop looking for targets. Start there again once we're done. */ *colonp = '\0'; - filenames = PARSE_FILE_SEQ (&p2, struct nameseq, MAP_NUL, NULL, 0); + filenames = PARSE_SIMPLE_SEQ (&p2, struct nameseq); *colonp = ':'; p2 = colonp; diff --git a/rule.c b/rule.c index 9a9e2294..5991c80f 100644 --- a/rule.c +++ b/rule.c @@ -373,7 +373,7 @@ install_pattern_rule (struct pspec *p, int terminal) ++r->suffixes[0]; ptr = p->dep; - r->deps = PARSE_FILE_SEQ (&ptr, struct dep, MAP_NUL, NULL, 0); + r->deps = PARSE_SIMPLE_SEQ (&ptr, struct dep); if (new_pattern_rule (r, 0)) { diff --git a/tests/ChangeLog b/tests/ChangeLog index 978349ac..587ff647 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2013-07-22 Paul Smith + + * scripts/features/rule_glob: Add tests for wildcards in rules. + Test for Savannah bug #39310. + 2013-07-09 Paul Smith * scripts/features/se_implicit: Add a test for SE rules depending diff --git a/tests/scripts/features/rule_glob b/tests/scripts/features/rule_glob new file mode 100644 index 00000000..2d377e7e --- /dev/null +++ b/tests/scripts/features/rule_glob @@ -0,0 +1,37 @@ +# -*-perl-*- + +$description = "Test globbing in targets and prerequisites."; + +$details = ""; + +touch(qw(a.one a.two a.three)); + +# Test wildcards in regular targets and prerequisites +run_make_test(q{ +.PHONY: all a.one a.two a.three +all: a.one* a.t[a-z0-9]o a.th[!q]ee +a.o[Nn][Ee] a.t*: ; @echo $@ +}, + '', "a.one\na.two\na.three"); + +# Test wildcards in pattern targets and prerequisites +run_make_test(q{ +.PHONY: all +all: a.four +%.four : %.t* ; @echo $@: $(sort $^) +}, + '', "a.four: a.three a.two"); + +# Test wildcards in second expansion targets and prerequisites +run_make_test(q{ +.PHONY: all +all: a.four +.SECONDEXPANSION: +%.four : $$(sort %.t*) ; @echo $@: $(sort $^) +}, + '', "a.four: a.three a.two"); + +unlink(qw(a.one a.two a.three)); + +# This tells the test driver that the perl test script executed properly. +1; -- 2.47.3