Extend .SECONDEXPANSION to implicit rules. Final fix for bug #13781.
authorPaul Smith <psmith@gnu.org>
Sun, 11 Dec 2005 15:41:17 +0000 (15:41 +0000)
committerPaul Smith <psmith@gnu.org>
Sun, 11 Dec 2005 15:41:17 +0000 (15:41 +0000)
ChangeLog
implicit.c
read.c
tests/ChangeLog
tests/scripts/features/se_implicit
tests/scripts/misc/general4

index 917a304e2197a617f83daf24496b30b521088571..eb226633705063fe124997349c3a7073b918cbb3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-12-11  Paul D. Smith  <psmith@gnu.org>
+
+       * implicit.c (pattern_search): If 2nd expansion is not set for
+       this implicit rule, replace the pattern with the stem directly,
+       and don't re-expand the variable list.  Along with the other
+       .SECONDEXPANSION changes below, fixes bug #13781.
+
 2005-12-09  Boris Kolpackov  <boris@kolpackov.net>
 
        * implicit.c (pattern_search): Mark other files that this rule
index cfd6629044681d5f09ee0579c2b2e187e98520e9..6754a849f670133542ad589b78a435c58a94e1a1 100644 (file)
@@ -502,41 +502,71 @@ pattern_search (struct file *file, int archive,
                   if (p == 0)
                     break; /* No more words */
 
-                  /* If the dependency name has %, substitute the stem.
-                     Watch out, we are going to do something tricky here. If
-                     we just replace % with the stem value, later, when we do
-                     the second expansion, we will re-expand this stem value
-                     once again. This is not good especially if you have
-                     certain characters in your stem (like $).
-
-                     Instead, we will replace % with $* and allow the second
-                     expansion to take care of it for us. This way (since $*
-                     is a simple variable) there won't be additional
-                     re-expansion of the stem.  */
+                  /* Is there a pattern in this prerequisite?  */
 
                   for (p2 = p; p2 < p + len && *p2 != '%'; ++p2)
                     ;
 
-                  if (p2 < p + len)
+                  if (dep->need_2nd_expansion)
                     {
-                      register unsigned int i = p2 - p;
-                      bcopy (p, depname, i);
-                      bcopy ("$*", depname + i, 2);
-                      bcopy (p2 + 1, depname + i + 2, len - i - 1);
-                      depname[len + 2 - 1] = '\0';
+                      /* If the dependency name has %, substitute the stem.
 
-                      if (check_lastslash)
-                        add_dir = 1;
+                         Watch out, we are going to do something tricky
+                         here. If we just replace % with the stem value,
+                         later, when we do the second expansion, we will
+                         re-expand this stem value once again. This is not
+                         good especially if you have certain characters in
+                         your stem (like $).
 
-                      had_stem = 1;
+                         Instead, we will replace % with $* and allow the
+                         second expansion to take care of it for us. This way
+                         (since $* is a simple variable) there won't be
+                         additional re-expansion of the stem.  */
+
+                      if (p2 < p + len)
+                        {
+                          register unsigned int i = p2 - p;
+                          bcopy (p, depname, i);
+                          bcopy ("$*", depname + i, 2);
+                          bcopy (p2 + 1, depname + i + 2, len - i - 1);
+                          depname[len + 2 - 1] = '\0';
+
+                          if (check_lastslash)
+                            add_dir = 1;
+
+                          had_stem = 1;
+                        }
+                      else
+                        {
+                          bcopy (p, depname, len);
+                          depname[len] = '\0';
+                        }
+
+                      p2 = variable_expand_for_file (depname, file);
                     }
                   else
                     {
-                      bcopy (p, depname, len);
-                      depname[len] = '\0';
-                    }
+                       if (p2 < p + len)
+                        {
+                          register unsigned int i = p2 - p;
+                          bcopy (p, depname, i);
+                          bcopy (stem_str, depname + i, stemlen);
+                          bcopy (p2 + 1, depname + i + stemlen, len - i - 1);
+                          depname[len + stemlen - 1] = '\0';
+
+                          if (check_lastslash)
+                            add_dir = 1;
+
+                          had_stem = 1;
+                        }
+                      else
+                        {
+                          bcopy (p, depname, len);
+                          depname[len] = '\0';
+                        }
 
-                  p2 = variable_expand_for_file (depname, file);
+                       p2 = depname;
+                    }
 
                   /* Parse the dependencies. */
 
diff --git a/read.c b/read.c
index 894bf6fce9a8c46b4747e3e79da95f0923b41ae3..660b11ae4ee5fc9964c8583afb4b6b0b3b4a3136 100644 (file)
--- a/read.c
+++ b/read.c
@@ -2131,11 +2131,7 @@ record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
       targets[target_idx] = 0;
       target_percents[target_idx] = 0;
       if (deps)
-       {
-         deps->need_2nd_expansion = second_expansion;
-         /* We set this to indicate the prereq string hasn't been parsed.  */
-         deps->staticpattern = 1;
-       }
+        deps->need_2nd_expansion = second_expansion;
       create_pattern_rule (targets, target_percents, two_colon, deps, cmds, 1);
       free ((char *) target_percents);
     }
index e222ef1e5fd862d8a826f0248142948ce49f7713..932059724aa57fbc4b765d692b226ceb5234b957 100644 (file)
@@ -1,3 +1,9 @@
+2005-12-11  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/misc/general4: Test implicit rules with '$' in the
+       prereq list & prereq patterns.
+       * scripts/features/se_implicit: Add in .SECONDEXPANSION settings.
+
 2005-12-09  Boris Kolpackov  <boris@kolpackov.net>
 
        * scripts/features/patternrules: Add a test for bug #13022.
index 0c38c17dab883a53a24c49b5bafa44a38ae3c6f2..c2ae64870e3846342384a49a62b6e856e62bd132 100644 (file)
@@ -12,6 +12,7 @@ $dir =~ s,.*/([^/]+)$,../$1,;
 # Test #1: automatic variables.
 #
 run_make_test('
+.SECONDEXPANSION:
 .DEFAULT: ; @echo $@
 
 foo.a: bar baz
@@ -60,6 +61,7 @@ buz
 # Test #2: target/pattern -specific variables.
 #
 run_make_test('
+.SECONDEXPANSION:
 foo.x:
 
 foo.%: $$(%_a) $$(%_b) bar
@@ -81,6 +83,7 @@ baz
 # Test #3: order of prerequisites.
 #
 run_make_test('
+.SECONDEXPANSION:
 .DEFAULT: ; @echo $@
 
 all: foo bar baz
@@ -132,6 +135,7 @@ baz.2
 # Test #4: stem splitting logic.
 #
 run_make_test('
+.SECONDEXPANSION:
 $(dir)/tmp/bar.o:
 
 $(dir)/tmp/foo/bar.c: ; @echo $@
@@ -153,6 +157,7 @@ $dir/tmp/bar.o: {$dir/tmp/foo/bar.c} $dir/tmp/foo/bar.c $dir/tmp/bar/bar.c foo.h
 # Test #5: stem splitting logic and order-only prerequisites.
 #
 run_make_test('
+.SECONDEXPANSION:
 $(dir)/tmp/foo.o: $(dir)/tmp/foo.c
 $(dir)/tmp/foo.c: ; @echo $@
 bar.h: ; @echo $@
@@ -171,6 +176,7 @@ $dir/tmp/foo.o: {$dir/tmp/foo.c} {bar.h} $dir/tmp/foo.c
 # Test #6: lack of implicit prerequisites.
 #
 run_make_test('
+.SECONDEXPANSION:
 foo.o: foo.c
 foo.c: ; @echo $@
 
@@ -186,6 +192,7 @@ foo.o: {foo.c} foo.c
 # Test #7: Test stem from the middle of the name.
 #
 run_make_test('
+.SECONDEXPANSION:
 foobarbaz:
 
 foo%baz: % $$*.1
@@ -204,6 +211,7 @@ bar
 # Test #8: Make sure stem triple-expansion does not happen.
 #
 run_make_test('
+.SECONDEXPANSION:
 foo$$bar:
 
 f%r: % $$*.1
index bce4a30c898ac1b2a4206c84b744216165b90cfe..ccccf886346cf0ec730ce9ad39058bf1499c02bc 100644 (file)
@@ -53,4 +53,31 @@ baz$$bar bar$$baz: ; @echo '$@'
               '',
               "baz\$bar\ndone baz\$bar");
 
+
+# Test implicit rules with '$' in the name (see se_implicit)
+# Use the '$' in the pattern.
+
+run_make_test(q!
+%.foo : %$$bar ; @echo 'done $<'
+test.foo:
+test$$bar: ; @echo '$@'
+!,
+              '',
+              "test\$bar\ndone test\$bar");
+
+# Make sure that subdirectories built as prerequisites are actually handled
+# properly... this time with '$'
+
+run_make_test(q!
+
+all: dir/subdir/file.$$a
+
+dir/subdir: ; @echo mkdir -p '$@'
+
+dir/subdir/file.$$b: dir/subdir ; @echo touch '$@'
+
+dir/subdir/%.$$a: dir/subdir/%.$$b ; @echo 'cp $< $@'
+!,
+              '', "mkdir -p dir/subdir\ntouch dir/subdir/file.\$b\ncp dir/subdir/file.\$b dir/subdir/file.\$a\n");
+
 1;