summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2002-09-17 21:52:45 +0000
committerPaul Smith <psmith@gnu.org>2002-09-17 21:52:45 +0000
commitdac7b49de4b935db71d7b4257c6354f16fe41cfa (patch)
treef82cb34b108309d38903bd4d1695942e0b79e951
parentd7ebcadadbfc100af64cc4c18580a6373bd52738 (diff)
downloadgunmake-dac7b49de4b935db71d7b4257c6354f16fe41cfa.tar.gz
Fix bug #940 (from the Savannah bug tracker): make sure that target-
specific variables work correctly in conjunction with double-colon targets.
-rw-r--r--ChangeLog15
-rw-r--r--read.c12
-rw-r--r--tests/ChangeLog6
-rw-r--r--tests/scripts/features/targetvars45
-rw-r--r--variable.c22
5 files changed, 94 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 9637eb1..e67c819 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2002-09-17 Paul D. Smith <psmith@gnu.org>
+
+ Fix Bug #940 (plus another bug I found while looking at this):
+
+ * read.c (record_target_var): enter_file() will add a new entry if
+ it's a double-colon target: we don't want to do that in this
+ situation. Invoke lookup_file() and only enter_file() if it does
+ not already exist. If the file we get back is a double-colon then
+ add this variable to the "root" double-colon target.
+
+ * variable.c (initialize_file_variables): If this file is a
+ double-colon target but is not the "root" target, then initialize
+ the root and make the root's variable list the parent of our
+ variable list.
+
2002-09-12 Paul D. Smith <psmith@gnu.org>
* Makefile.am (loadavg_SOURCES, loadavg.c): Tiptoe around automake
diff --git a/read.c b/read.c
index dd930f7..3488524 100644
--- a/read.c
+++ b/read.c
@@ -1671,8 +1671,16 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
{
struct file *f;
- /* Get a file reference for this file, and initialize it. */
- f = enter_file (name);
+ /* Get a file reference for this file, and initialize it.
+ We don't want to just call enter_file() because that allocates a
+ new entry if the file is a double-colon, which we don't want in
+ this situation. */
+ f = lookup_file (name);
+ if (!f)
+ f = enter_file (name);
+ else if (f->double_colon)
+ f = f->double_colon;
+
initialize_file_variables (f, 1);
vlist = f->variables;
fname = f->name;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index fd6ef2a..a2edc50 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2002-09-17 Paul D. Smith <psmith@gnu.org>
+
+ * scripts/features/targetvars: Tests for Bug #940: test
+ target-specific and pattern-specific variables in conjunction with
+ double-colon targets.
+
2002-09-10 Paul D. Smith <psmith@gnu.org>
* test_driver.pl (compare_output): Match the new format for time
diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars
index a70d3ab..06328c2 100644
--- a/tests/scripts/features/targetvars
+++ b/tests/scripts/features/targetvars
@@ -194,5 +194,50 @@ close(MAKEFILE);
$answer = "bar snafu bar\n";
&compare_output($answer, &get_logfile(1));
+# Test #13
+# Test double-colon rules with target-specific variable values
+
+$makefile6 = &get_tmpfile;
+
+open(MAKEFILE, "> $makefile6");
+print MAKEFILE <<'EOF';
+W = bad
+X = bad
+foo: W = ok
+foo:: ; @echo $(W) $(X) $(Y) $(Z)
+foo:: ; @echo $(W) $(X) $(Y) $(Z)
+foo: X = ok
+
+Y = foo
+bar: foo
+bar: Y = bar
+
+Z = nopat
+ifdef PATTERN
+ fo% : Z = pat
+endif
+
+EOF
+close(MAKEFILE);
+
+&run_make_with_options("$makefile6", "foo", &get_logfile);
+$answer = "ok ok foo nopat\nok ok foo nopat\n";
+&compare_output($answer, &get_logfile(1));
+
+# Test #14
+# Test double-colon rules with target-specific variable values and
+# inheritance
+
+&run_make_with_options("$makefile6", "bar", &get_logfile);
+$answer = "ok ok bar nopat\nok ok bar nopat\n";
+&compare_output($answer, &get_logfile(1));
+
+# Test #15
+# Test double-colon rules with pattern-specific variable values
+
+&run_make_with_options("$makefile6", "foo PATTERN=yes", &get_logfile);
+$answer = "ok ok foo pat\nok ok foo pat\n";
+&compare_output($answer, &get_logfile(1));
+
1;
diff --git a/variable.c b/variable.c
index 27a38e2..308ad75 100644
--- a/variable.c
+++ b/variable.c
@@ -372,9 +372,12 @@ lookup_variable_in_set (name, length, set)
/* Initialize FILE's variable set list. If FILE already has a variable set
list, the topmost variable set is left intact, but the the rest of the
- chain is replaced with FILE->parent's setlist. If we're READing a
- makefile, don't do the pattern variable search now, since the pattern
- variable might not have been defined yet. */
+ chain is replaced with FILE->parent's setlist. If FILE is a double-colon
+ rule, then we will use the "root" double-colon target's variable set as the
+ parent of FILE's variable set.
+
+ If we're READing a makefile, don't do the pattern variable search now,
+ since the pattern variable might not have been defined yet. */
void
initialize_file_variables (file, reading)
@@ -389,10 +392,21 @@ initialize_file_variables (file, reading)
xmalloc (sizeof (struct variable_set_list));
l->set = (struct variable_set *) xmalloc (sizeof (struct variable_set));
hash_init (&l->set->table, PERFILE_VARIABLE_BUCKETS,
- variable_hash_1, variable_hash_2, variable_hash_cmp);
+ variable_hash_1, variable_hash_2, variable_hash_cmp);
file->variables = l;
}
+ /* If this is a double-colon, then our "parent" is the "root" target for
+ this double-colon rule. Since that rule has the same name, parent,
+ etc. we can just use its variables as the "next" for ours. */
+
+ if (file->double_colon && file->double_colon != file)
+ {
+ initialize_file_variables (file->double_colon, reading);
+ l->next = file->double_colon->variables;
+ return;
+ }
+
if (file->parent == 0)
l->next = &global_setlist;
else