From 9714e501fb356adb043c77a3180a7f8c16c1484d Mon Sep 17 00:00:00 2001
From: Paul Smith <psmith@gnu.org>
Date: Tue, 21 Sep 2004 05:39:04 +0000
Subject: [PATCH] Add some more unit tests for variable flavors. Allow
 run_make_tests() to be invoked with an undef makefile string, in which case
 it re-uses the previous string.

---
 tests/run_make_tests.pl         | 49 +++++++++++++---------
 tests/scripts/variables/flavors | 73 +++++++++++++++++++++++++++++++++
 tests/test_driver.pl            |  1 +
 3 files changed, 104 insertions(+), 19 deletions(-)

diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl
index 991e7807..5d490146 100755
--- a/tests/run_make_tests.pl
+++ b/tests/run_make_tests.pl
@@ -51,43 +51,54 @@ sub valid_option
 
 # This is an "all-in-one" function.  Arguments are as follows:
 #
-#  [0] (string):  The makefile to be tested.
+#  [0] (string):  The makefile to be tested.  undef means use the last one.
 #  [1] (string):  Arguments to pass to make.
 #  [2] (string):  Answer we should get back.
 #  [3] (integer): Exit code we expect.  A missing code means 0 (success)
 
+$old_makefile = undef;
+
 sub run_make_test
 {
   local ($makestring, $options, $answer, $err_code) = @_;
 
-  if (! defined($makefile)) {
-    $makefile = &get_tmpfile();
+  # If the user specified a makefile string, create a new makefile to contain
+  # it.  If the first value is not defined, use the last one (if there is
+  # one).
+
+  if (! defined $makestring) {
+    defined $old_makefile
+      || die "run_make_test(undef) invoked before run_make_test('...')\n";
+    $makefile = $old_makefile;
+  } else {
+    if (! defined($makefile)) {
+      $makefile = &get_tmpfile();
+    }
+
+    # Make sure it ends in a newline.
+    $makestring =~ /\n$/s or $makestring .= "\n";
+
+    # Replace @MAKEFILE@ with the makefile name and @MAKE@ with the path to
+    # make
+    $makestring =~ s/#MAKEFILE#/$makefile/g;
+    $makestring =~ s/#MAKE#/$make_name/g;
+
+    # Populate the makefile!
+    open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
+    print MAKEFILE $makestring;
+    close(MAKEFILE) || die "Failed to write $makefile: $!\n";
   }
 
-  # If either the makestring or the answer don't end in newlines, add one In
-  # the future should we allow an option to disable this?  For now if you
-  # want to test handling with no newline you have to call the underlying
-  # functions directly.
+  # Do the same processing on $answer as we did on $makestring.
 
-  $makestring =~ /\n$/s or $makestring .= "\n";
   $answer =~ /\n$/s     or $answer .= "\n";
-
-  # Replace @MAKEFILE@ with the makefile name and @MAKE@ with the path to
-  # make in both $makestring and $answer.
-
-  $makestring =~ s/#MAKEFILE#/$makefile/g;
-  $makestring =~ s/#MAKE#/$make_name/g;
-
   $answer =~ s/#MAKEFILE#/$makefile/g;
   $answer =~ s/#MAKE#/$make_name/g;
 
-  open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
-  print MAKEFILE $makestring, "\n";
-  close(MAKEFILE) || die "Failed to write $makefile: $!\n";
-
   &run_make_with_options($makefile, $options, &get_logfile(0), $err_code);
   &compare_output($answer, &get_logfile(1));
 
+  $old_makefile = $makefile;
   $makefile = undef;
 }
 
diff --git a/tests/scripts/variables/flavors b/tests/scripts/variables/flavors
index c9025b2e..88e9ad59 100644
--- a/tests/scripts/variables/flavors
+++ b/tests/scripts/variables/flavors
@@ -81,5 +81,78 @@ $answer = "$makefile:24: *** empty variable name.  Stop.\n";
 $answer = "A = B\n";
 &compare_output($answer, &get_logfile(1));
 
+# Clean up from "old style" testing.  If all the above tests are converted to
+# run_make_test() syntax than this line can be removed.
+$makefile = undef;
+
+# -------------------------
+# Make sure that prefix characters apply properly to define/endef values.
+#
+# There's a bit of oddness here if you try to use a variable to hold the
+# prefix character for a define.  Even though something like this:
+#
+#       define foo
+#       echo bar
+#       endef
+#
+#       all: ; $(V)$(foo)
+#
+# (where V=@) can be seen by the user to be obviously different than this:
+#
+#       define foo
+#       $(V)echo bar
+#       endef
+#
+#       all: ; $(foo)
+#
+# and the user thinks it should behave the same as when the "@" is literal
+# instead of in a variable, that can't happen because by the time make
+# expands the variables for the command line and sees it begins with a "@" it
+# can't know anymore whether the prefix character came before the variable
+# reference or was included in the first line of the variable reference.
+
+# TEST #5
+# -------
+
+run_make_test('
+define FOO
+$(V1)echo hello
+$(V2)echo world
+endef
+all: ; @$(FOO)
+', '', 'hello
+world');
+
+# TEST #6
+# -------
+
+run_make_test(undef, 'V1=@ V2=@', 'hello
+world');
+
+# TEST #7
+# -------
+
+run_make_test('
+define FOO
+$(V1)echo hello
+$(V2)echo world
+endef
+all: ; $(FOO)
+', 'V1=@', 'hello
+echo world
+world');
+
+# TEST #8
+# -------
+
+run_make_test(undef, 'V2=@', 'echo hello
+hello
+world');
+
+# TEST #9
+# -------
+
+run_make_test(undef, 'V1=@ V2=@', 'hello
+world');
 
 1;
diff --git a/tests/test_driver.pl b/tests/test_driver.pl
index 0bca669b..0698d268 100644
--- a/tests/test_driver.pl
+++ b/tests/test_driver.pl
@@ -385,6 +385,7 @@ sub run_each_test
     $num_of_tmpfiles = 0;
     $description = "";
     $details = "";
+    $old_makefile = undef;
     $testname =~ s/^$scriptpath$pathsep//;
     $perl_testname = "$scriptpath$pathsep$testname";
     $testname =~ s/(\.pl|\.perl)$//;