summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2013-07-22 02:19:13 -0400
committerPaul Smith <psmith@gnu.org>2013-07-22 02:23:02 -0400
commit40a49f244da5b417af8bede84ac221cee2318d88 (patch)
tree375c8261aad11579344b11fabba4a74adef327ca
parent87ac68fe79a2e3b0d149135d40d8cbc5500024af (diff)
downloadgunmake-40a49f244da5b417af8bede84ac221cee2318d88.tar.gz
[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.
-rw-r--r--ChangeLog14
-rw-r--r--default.c5
-rw-r--r--dep.h2
-rw-r--r--file.c5
-rw-r--r--implicit.c23
-rw-r--r--main.c2
-rw-r--r--read.c2
-rw-r--r--rule.c2
-rw-r--r--tests/ChangeLog5
-rw-r--r--tests/scripts/features/rule_glob37
10 files changed, 78 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 608f870..f8ab2ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2013-07-22 Paul Smith <psmith@gnu.org>
+
+ * 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 <psmith@gnu.org>
Cleanups detected by cppcheck. Fixes Savannah bug #39158.
diff --git a/default.c b/default.c
index 32b878a..47b7dd3 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 4abfefe..13cefdc 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 25ddde7..c8e19e5 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 6d2e09b..f0bb385 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 801365f..2cfc49b 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 bc78fa5..834c7f8 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 9a9e229..5991c80 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 978349a..587ff64 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2013-07-22 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/rule_glob: Add tests for wildcards in rules.
+ Test for Savannah bug #39310.
+
2013-07-09 Paul Smith <psmith@gnu.org>
* 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 0000000..2d377e7
--- /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;