]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[Bug #39310] Parse simple pattern prereqs for globbing.
authorPaul Smith <psmith@gnu.org>
Mon, 22 Jul 2013 06:19:13 +0000 (02:19 -0400)
committerPaul Smith <psmith@gnu.org>
Mon, 22 Jul 2013 06:23:02 +0000 (02:23 -0400)
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
default.c
dep.h
file.c
implicit.c
main.c
read.c
rule.c
tests/ChangeLog
tests/scripts/features/rule_glob [new file with mode: 0644]

index 608f8702921bacc6addf3590fd2a2229f4e74b77..f8ab2cac91efc77f388883e20ad914ce1d93ecaf 100644 (file)
--- 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.
index 32b878a9baf71972b57327577836eea15d2e9b2e..47b7dd3471925df79bd2ea3e06a15e3d3ca5de68 100644 (file)
--- 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 4abfefe38258595af2d47f9621842e697f72af29..13cefdc59dc46b3b19cbe842974fad8b94ae9739 100644 (file)
--- 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 25ddde7cca8f4f7d660e91a9c29f383d6eaa3765..c8e19e580651dc151e15644abf8b4652aaf86f2b 100644 (file)
--- 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;
index 6d2e09b3208e529cca5ec062555407439d9a519d..f0bb38546fee73c85d387873a58acd1cbaa97b3a 100644 (file)
@@ -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 801365fa6e92ee04d34a7ad1eacfa0cbf0db0b5f..2cfc49bf168cce52a067af870ddf8dbc29c920cc 100644 (file)
--- 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 bc78fa5197e35b435226b4305dce7078876dd2fa..834c7f83f1c10a6f16a2820566a205df27e4bcaf 100644 (file)
--- 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 9a9e2294a4a34cf075c5aa23a5ff9324ef5a4dc6..5991c80f1a14a578b481a83e02d1a914d760d8ec 100644 (file)
--- 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))
     {
index 978349aca96daab8eda938d706be06c40a5151a3..587ff647feb69f901aa8cd826bc234496d486e9d 100644 (file)
@@ -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 (file)
index 0000000..2d377e7
--- /dev/null
@@ -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;