From dac7b49de4b935db71d7b4257c6354f16fe41cfa Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Tue, 17 Sep 2002 21:52:45 +0000 Subject: Fix bug #940 (from the Savannah bug tracker): make sure that target- specific variables work correctly in conjunction with double-colon targets. --- ChangeLog | 15 +++++++++++++ read.c | 12 +++++++++-- tests/ChangeLog | 6 ++++++ tests/scripts/features/targetvars | 45 +++++++++++++++++++++++++++++++++++++++ variable.c | 22 +++++++++++++++---- 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 + + 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 * 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 + + * 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 * 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 -- cgit v1.2.3