summaryrefslogtreecommitdiff
path: root/tests/scripts/features
diff options
context:
space:
mode:
Diffstat (limited to 'tests/scripts/features')
-rw-r--r--tests/scripts/features/comments35
-rw-r--r--tests/scripts/features/conditionals146
-rw-r--r--tests/scripts/features/default_names41
-rw-r--r--tests/scripts/features/double_colon155
-rw-r--r--tests/scripts/features/echoing64
-rw-r--r--tests/scripts/features/errors92
-rw-r--r--tests/scripts/features/escape58
-rw-r--r--tests/scripts/features/export186
-rw-r--r--tests/scripts/features/include179
-rw-r--r--tests/scripts/features/mult_rules78
-rw-r--r--tests/scripts/features/mult_targets46
-rw-r--r--tests/scripts/features/order_only118
-rw-r--r--tests/scripts/features/override45
-rw-r--r--tests/scripts/features/parallelism254
-rw-r--r--tests/scripts/features/patspecific_vars148
-rw-r--r--tests/scripts/features/patternrules224
-rw-r--r--tests/scripts/features/quoting32
-rw-r--r--tests/scripts/features/recursion55
-rw-r--r--tests/scripts/features/reinvoke65
-rw-r--r--tests/scripts/features/se_explicit156
-rw-r--r--tests/scripts/features/se_implicit226
-rw-r--r--tests/scripts/features/se_statpat107
-rw-r--r--tests/scripts/features/statipattrules111
-rw-r--r--tests/scripts/features/targetvars263
-rw-r--r--tests/scripts/features/varnesting34
-rw-r--r--tests/scripts/features/vpath81
-rw-r--r--tests/scripts/features/vpath245
-rw-r--r--tests/scripts/features/vpath350
-rw-r--r--tests/scripts/features/vpathgpath66
-rw-r--r--tests/scripts/features/vpathplus128
30 files changed, 3288 insertions, 0 deletions
diff --git a/tests/scripts/features/comments b/tests/scripts/features/comments
new file mode 100644
index 0000000..9257955
--- /dev/null
+++ b/tests/scripts/features/comments
@@ -0,0 +1,35 @@
+$description = "The following test creates a makefile to test comments\n"
+ ."and comment continuation to the next line using a \n"
+ ."backslash within makefiles.";
+
+$details = "To test comments within a makefile, a semi-colon was placed \n"
+ ."after a comment was started. This should not be reported as\n"
+ ."an error since it is within a comment. We then continue the \n"
+ ."comment to the next line using a backslash. To test whether\n"
+ ."the comment really continued, we place an echo command with some\n"
+ ."text on the line which should never execute since it should be \n"
+ ."within a comment\n";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE <<\EOF;
+# Test comment vs semicolon parsing and line continuation
+target: # this ; is just a comment \
+ @echo This is within a comment.
+ @echo There should be no errors for this makefile.
+EOF
+
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+&run_make_with_options($makefile,"",&get_logfile);
+
+# Create the answer to what should be produced by this Makefile
+$answer = "There should be no errors for this makefile.\n";
+
+# COMPARE RESULTS
+
+&compare_output($answer,&get_logfile(1))
diff --git a/tests/scripts/features/conditionals b/tests/scripts/features/conditionals
new file mode 100644
index 0000000..2ece60b
--- /dev/null
+++ b/tests/scripts/features/conditionals
@@ -0,0 +1,146 @@
+# -*-perl-*-
+$description = "Check GNU make conditionals.";
+
+$details = "Attempt various different flavors of GNU make conditionals.";
+
+run_make_test('
+arg1 = first
+arg2 = second
+arg3 = third
+arg4 = cc
+arg5 = second
+
+all:
+ifeq ($(arg1),$(arg2))
+ @echo arg1 equals arg2
+else
+ @echo arg1 NOT equal arg2
+endif
+
+ifeq \'$(arg2)\' "$(arg5)"
+ @echo arg2 equals arg5
+else
+ @echo arg2 NOT equal arg5
+endif
+
+ifneq \'$(arg3)\' \'$(arg4)\'
+ @echo arg3 NOT equal arg4
+else
+ @echo arg3 equal arg4
+endif
+
+ifndef undefined
+ @echo variable is undefined
+else
+ @echo variable undefined is defined
+endif
+ifdef arg4
+ @echo arg4 is defined
+else
+ @echo arg4 is NOT defined
+endif',
+ '',
+ 'arg1 NOT equal arg2
+arg2 equals arg5
+arg3 NOT equal arg4
+variable is undefined
+arg4 is defined');
+
+
+# Test expansion of variables inside ifdef.
+
+run_make_test('
+foo = 1
+
+FOO = foo
+F = f
+
+DEF = no
+DEF2 = no
+
+ifdef $(FOO)
+DEF = yes
+endif
+
+ifdef $(F)oo
+DEF2 = yes
+endif
+
+
+DEF3 = no
+FUNC = $1
+ifdef $(call FUNC,DEF)3
+ DEF3 = yes
+endif
+
+all:; @echo DEF=$(DEF) DEF2=$(DEF2) DEF3=$(DEF3)',
+ '',
+ 'DEF=yes DEF2=yes DEF3=yes');
+
+
+# Test all the different "else if..." constructs
+
+run_make_test('
+arg1 = first
+arg2 = second
+arg3 = third
+arg4 = cc
+arg5 = fifth
+
+result =
+
+ifeq ($(arg1),$(arg2))
+ result += arg1 equals arg2
+else ifeq \'$(arg2)\' "$(arg5)"
+ result += arg2 equals arg5
+else ifneq \'$(arg3)\' \'$(arg3)\'
+ result += arg3 NOT equal arg4
+else ifndef arg5
+ result += variable is undefined
+else ifdef undefined
+ result += arg4 is defined
+else
+ result += success
+endif
+
+
+all: ; @echo $(result)',
+ '',
+ 'success');
+
+
+# Test some random "else if..." construct nesting
+
+run_make_test('
+arg1 = first
+arg2 = second
+arg3 = third
+arg4 = cc
+arg5 = second
+
+ifeq ($(arg1),$(arg2))
+ $(info failed 1)
+else ifeq \'$(arg2)\' "$(arg2)"
+ ifdef undefined
+ $(info failed 2)
+ else
+ $(info success)
+ endif
+else ifneq \'$(arg3)\' \'$(arg3)\'
+ $(info failed 3)
+else ifdef arg5
+ $(info failed 4)
+else ifdef undefined
+ $(info failed 5)
+else
+ $(info failed 6)
+endif
+
+.PHONY: all
+all: ; @:',
+ '',
+ 'success');
+
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/default_names b/tests/scripts/features/default_names
new file mode 100644
index 0000000..e53127e
--- /dev/null
+++ b/tests/scripts/features/default_names
@@ -0,0 +1,41 @@
+# -*-perl-*-
+
+$description = "This script tests to make sure that Make looks for
+default makefiles in the correct order (GNUmakefile,makefile,Makefile)";
+
+# Create a makefile called "GNUmakefile"
+$makefile = "GNUmakefile";
+
+open(MAKEFILE,"> $makefile");
+print MAKEFILE "FIRST: ; \@echo It chose GNUmakefile\n";
+close(MAKEFILE);
+
+# DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile.
+# Just test what we can here (avoid Makefile versus makefile test).
+
+if ($port_type eq 'UNIX') {
+ # Create another makefile called "makefile"
+ open(MAKEFILE,"> makefile");
+ print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
+ close(MAKEFILE);
+}
+
+# Create another makefile called "Makefile"
+open(MAKEFILE,"> Makefile");
+print MAKEFILE "THIRD: ; \@echo It chose Makefile\n";
+close(MAKEFILE);
+
+
+&run_make_with_options("","",&get_logfile);
+&compare_output("It chose GNUmakefile\n",&get_logfile(1));
+unlink $makefile;
+
+if ($port_type eq 'UNIX') {
+ &run_make_with_options("","",&get_logfile);
+ &compare_output("It chose makefile\n",&get_logfile(1));
+ unlink "makefile";
+}
+
+&run_make_with_options("","",&get_logfile);
+&compare_output("It chose Makefile\n",&get_logfile(1));
+unlink "Makefile";
diff --git a/tests/scripts/features/double_colon b/tests/scripts/features/double_colon
new file mode 100644
index 0000000..cad605d
--- /dev/null
+++ b/tests/scripts/features/double_colon
@@ -0,0 +1,155 @@
+# -*-perl-*-
+$description = "Test handling of double-colon rules.";
+
+$details = "\
+We test these features:
+
+ - Multiple commands for the same (double-colon) target
+ - Different prerequisites for targets: only out-of-date
+ ones are rebuilt.
+ - Double-colon targets that aren't the goal target.
+
+Then we do the same thing for parallel builds: double-colon
+targets should always be built serially.";
+
+# The Contents of the MAKEFILE ...
+
+open(MAKEFILE,"> $makefile");
+
+print MAKEFILE <<'EOF';
+
+all: baz
+
+foo:: f1.h ; @echo foo FIRST
+foo:: f2.h ; @echo foo SECOND
+
+bar:: ; @echo aaa; sleep 1; echo aaa done
+bar:: ; @echo bbb
+
+baz:: ; @echo aaa
+baz:: ; @echo bbb
+
+biz:: ; @echo aaa
+biz:: two ; @echo bbb
+
+two: ; @echo two
+
+f1.h f2.h: ; @echo $@
+
+d :: ; @echo ok
+d :: d ; @echo oops
+
+EOF
+
+close(MAKEFILE);
+
+# TEST 0: A simple double-colon rule that isn't the goal target.
+
+&run_make_with_options($makefile, "all", &get_logfile, 0);
+$answer = "aaa\nbbb\n";
+&compare_output($answer, &get_logfile(1));
+
+# TEST 1: As above, in parallel
+
+if ($parallel_jobs) {
+ &run_make_with_options($makefile, "-j10 all", &get_logfile, 0);
+ $answer = "aaa\nbbb\n";
+ &compare_output($answer, &get_logfile(1));
+}
+
+# TEST 2: A simple double-colon rule that is the goal target
+
+&run_make_with_options($makefile, "bar", &get_logfile, 0);
+$answer = "aaa\naaa done\nbbb\n";
+&compare_output($answer, &get_logfile(1));
+
+# TEST 3: As above, in parallel
+
+if ($parallel_jobs) {
+ &run_make_with_options($makefile, "-j10 bar", &get_logfile, 0);
+ $answer = "aaa\naaa done\nbbb\n";
+ &compare_output($answer, &get_logfile(1));
+}
+
+# TEST 4: Each double-colon rule is supposed to be run individually
+
+&utouch(-5, 'f2.h');
+&touch('foo');
+
+&run_make_with_options($makefile, "foo", &get_logfile, 0);
+$answer = "f1.h\nfoo FIRST\n";
+&compare_output($answer, &get_logfile(1));
+
+# TEST 5: Again, in parallel.
+
+if ($parallel_jobs) {
+ &run_make_with_options($makefile, "-j10 foo", &get_logfile, 0);
+ $answer = "f1.h\nfoo FIRST\n";
+ &compare_output($answer, &get_logfile(1));
+}
+
+# TEST 6: Each double-colon rule is supposed to be run individually
+
+&utouch(-5, 'f1.h');
+unlink('f2.h');
+&touch('foo');
+
+&run_make_with_options($makefile, "foo", &get_logfile, 0);
+$answer = "f2.h\nfoo SECOND\n";
+&compare_output($answer, &get_logfile(1));
+
+# TEST 7: Again, in parallel.
+
+if ($parallel_jobs) {
+ &run_make_with_options($makefile, "-j10 foo", &get_logfile, 0);
+ $answer = "f2.h\nfoo SECOND\n";
+ &compare_output($answer, &get_logfile(1));
+}
+
+# TEST 8: Test circular dependency check; PR/1671
+
+&run_make_with_options($makefile, "d", &get_logfile, 0);
+$answer = "ok\n$make_name: Circular d <- d dependency dropped.\noops\n";
+&compare_output($answer, &get_logfile(1));
+
+# TEST 8: I don't grok why this is different than the above, but it is...
+#
+# Hmm... further testing indicates this might be timing-dependent?
+#
+#if ($parallel_jobs) {
+# &run_make_with_options($makefile, "-j10 biz", &get_logfile, 0);
+# $answer = "aaa\ntwo\nbbb\n";
+# &compare_output($answer, &get_logfile(1));
+#}
+
+unlink('foo','f1.h','f2.h');
+
+
+# TEST 9: make sure all rules in s double colon family get executed
+# (Savannah bug #14334).
+#
+
+&touch('one');
+&touch('two');
+
+run_make_test('
+.PHONY: all
+all: result
+
+result:: one
+ @echo $^ >>$@
+ @echo $^
+
+result:: two
+ @echo $^ >>$@
+ @echo $^
+
+',
+'',
+'one
+two');
+
+unlink('result','one','two');
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/echoing b/tests/scripts/features/echoing
new file mode 100644
index 0000000..40debf5
--- /dev/null
+++ b/tests/scripts/features/echoing
@@ -0,0 +1,64 @@
+# -*-perl-*-
+$description = "The following test creates a makefile to test command
+echoing. It tests that when a command line starts with
+a '\@', the echoing of that line is suppressed. It also
+tests the -n option which tells make to ONLY echo the
+commands and no execution happens. In this case, even
+the commands with '\@' are printed. Lastly, it tests the
+-s flag which tells make to prevent all echoing, as if
+all commands started with a '\@'.";
+
+$details = "This test is similar to the 'clean' test except that a '\@' has
+been placed in front of the delete command line. Four tests
+are run here. First, make is run normally and the first echo
+command should be executed. In this case there is no '\@' so
+we should expect make to display the command AND display the
+echoed message. Secondly, make is run with the clean target,
+but since there is a '\@' at the beginning of the command, we
+expect no output; just the deletion of a file which we check
+for. Third, we give the clean target again except this time
+we give make the -n option. We now expect the command to be
+displayed but not to be executed. In this case we need only
+to check the output since an error message would be displayed
+if it actually tried to run the delete command again and the
+file didn't exist. Lastly, we run the first test again with
+the -s option and check that make did not echo the echo
+command before printing the message.\n";
+
+$example = "EXAMPLE_FILE";
+
+touch($example);
+
+# TEST #1
+# -------
+
+run_make_test("
+all:
+\techo This makefile did not clean the dir... good
+clean:
+\t\@$delete_command $example\n",
+ '', 'echo This makefile did not clean the dir... good
+This makefile did not clean the dir... good');
+
+# TEST #2
+# -------
+
+run_make_test(undef, 'clean', '');
+if (-f $example) {
+ $test_passed = 0;
+ unlink($example);
+}
+
+# TEST #3
+# -------
+
+run_make_test(undef, '-n clean', "$delete_command $example\n");
+
+
+# TEST #4
+# -------
+
+run_make_test(undef, '-s', "This makefile did not clean the dir... good\n");
+
+
+1;
diff --git a/tests/scripts/features/errors b/tests/scripts/features/errors
new file mode 100644
index 0000000..e372fe0
--- /dev/null
+++ b/tests/scripts/features/errors
@@ -0,0 +1,92 @@
+# -*-perl-*-
+
+$description = "The following tests the -i option and the '-' in front of \n"
+ ."commands to test that make ignores errors in these commands\n"
+ ."and continues processing.";
+
+$details = "This test runs two makes. The first runs on a target with a \n"
+ ."command that has a '-' in front of it (and a command that is \n"
+ ."intended to fail) and then a delete command after that is \n"
+ ."intended to succeed. If make ignores the failure of the first\n"
+ ."command as it is supposed to, then the second command should \n"
+ ."delete a file and this is what we check for. The second make\n"
+ ."that is run in this test is identical except that the make \n"
+ ."command is given with the -i option instead of the '-' in \n"
+ ."front of the command. They should run the same. ";
+
+if ($vos)
+{
+ $rm_command = "delete_file";
+}
+else
+{
+ $rm_command = "rm";
+}
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE "clean:\n"
+ ."\t-$rm_command cleanit\n"
+ ."\t$rm_command foo\n"
+ ."clean2: \n"
+ ."\t$rm_command cleanit\n"
+ ."\t$rm_command foo\n";
+
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+&touch("foo");
+
+unlink("cleanit");
+$cleanit_error = `sh -c "$rm_command cleanit 2>&1"`;
+$delete_error_code = $? >> 8;
+
+# TEST #1
+# -------
+
+$answer = "$rm_command cleanit\n"
+ . $cleanit_error
+ ."$make_name: [clean] Error $delete_error_code (ignored)\n"
+ ."$rm_command foo\n";
+
+&run_make_with_options($makefile,"",&get_logfile);
+
+# If make acted as planned, it should ignore the error from the first
+# command in the target and execute the second which deletes the file "foo"
+# This file, therefore, should not exist if the test PASSES.
+if (-f "foo") {
+ $test_passed = 0;
+}
+
+# The output for this on VOS is too hard to replicate, so we only check it
+# on unix.
+if (!$vos)
+{
+ &compare_output($answer,&get_logfile(1));
+}
+
+
+&touch("foo");
+
+# TEST #2
+# -------
+
+$answer = "$rm_command cleanit\n"
+ . $cleanit_error
+ ."$make_name: [clean2] Error $delete_error_code (ignored)\n"
+ ."$rm_command foo\n";
+
+&run_make_with_options($makefile,"clean2 -i",&get_logfile);
+
+if (-f "foo") {
+ $test_passed = 0;
+}
+
+if (!$vos) {
+ &compare_output($answer,&get_logfile(1));
+}
+
+1;
diff --git a/tests/scripts/features/escape b/tests/scripts/features/escape
new file mode 100644
index 0000000..97a2994
--- /dev/null
+++ b/tests/scripts/features/escape
@@ -0,0 +1,58 @@
+# -*-perl-*-
+$description = "Test various types of escaping in makefiles.";
+
+$details = "\
+Make sure that escaping of `:' works in target names.
+Make sure escaping of whitespace works in target names.
+Make sure that escaping of '#' works.";
+
+
+close(MAKEFILE);
+
+
+# TEST 1
+
+run_make_test('
+$(path)foo : ; @echo "touch ($@)"
+
+foo\ bar: ; @echo "touch ($@)"
+
+sharp: foo\#bar.ext
+foo\#bar.ext: ; @echo "foo#bar.ext = ($@)"',
+ '',
+ 'touch (foo)');
+
+# TEST 2: This one should fail, since the ":" is unquoted.
+
+run_make_test(undef,
+ 'path=pre:',
+ "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.",
+ 512);
+
+# TEST 3: This one should work, since we escape the ":".
+
+run_make_test(undef,
+ "'path=pre\\:'",
+ 'touch (pre:foo)');
+
+# TEST 4: This one should fail, since the escape char is escaped.
+
+run_make_test(undef,
+ "'path=pre\\\\:'",
+ "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.",
+ 512);
+
+# TEST 5: This one should work
+
+run_make_test(undef,
+ "'foo bar'",
+ 'touch (foo bar)');
+
+# TEST 6: Test escaped comments
+
+run_make_test(undef,
+ 'sharp',
+ 'foo#bar.ext = (foo#bar.ext)');
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/export b/tests/scripts/features/export
new file mode 100644
index 0000000..81bff0c
--- /dev/null
+++ b/tests/scripts/features/export
@@ -0,0 +1,186 @@
+# -*-perl-*-
+$description = "Check GNU make export/unexport commands.";
+
+$details = "";
+
+# The test driver cleans out our environment for us so we don't have to worry
+# about that here.
+
+&run_make_test('
+FOO = foo
+BAR = bar
+BOZ = boz
+
+export BAZ = baz
+export BOZ
+
+BITZ = bitz
+BOTZ = botz
+
+export BITZ BOTZ
+unexport BOTZ
+
+ifdef EXPORT_ALL
+export
+endif
+
+ifdef UNEXPORT_ALL
+unexport
+endif
+
+ifdef EXPORT_ALL_PSEUDO
+.EXPORT_ALL_VARIABLES:
+endif
+
+all:
+ @echo "FOO=$(FOO) BAR=$(BAR) BAZ=$(BAZ) BOZ=$(BOZ) BITZ=$(BITZ) BOTZ=$(BOTZ)"
+ @echo "FOO=$$FOO BAR=$$BAR BAZ=$$BAZ BOZ=$$BOZ BITZ=$$BITZ BOTZ=$$BOTZ"
+',
+ '', "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
+
+# TEST 1: make sure vars inherited from the parent are exported
+
+$extraENV{FOO} = 1;
+
+&run_make_test(undef, '', "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO=foo BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
+
+# TEST 2: global export. Explicit unexport takes precedence.
+
+run_make_test(undef, "EXPORT_ALL=1" ,
+ "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
+
+# TEST 3: global unexport. Explicit export takes precedence.
+
+&run_make_test(undef, "UNEXPORT_ALL=1",
+ "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
+
+# TEST 4: both: in the above makefile the unexport comes last so that rules.
+
+&run_make_test(undef, "EXPORT_ALL=1 UNEXPORT_ALL=1",
+ "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
+
+# TEST 5: test the pseudo target.
+
+&run_make_test(undef, "EXPORT_ALL_PSEUDO=1",
+ "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz
+FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n");
+
+# TEST 6: Test the expansion of variables inside export
+
+&run_make_test('
+foo = f-ok
+bar = b-ok
+
+FOO = foo
+F = f
+
+BAR = bar
+B = b
+
+export $(FOO)
+export $(B)ar
+
+all:
+ @echo foo=$(foo) bar=$(bar)
+ @echo foo=$$foo bar=$$bar
+',
+ "", "foo=f-ok bar=b-ok\nfoo=f-ok bar=b-ok\n");
+
+# TEST 7: Test the expansion of variables inside unexport
+
+&run_make_test('
+foo = f-ok
+bar = b-ok
+
+FOO = foo
+F = f
+
+BAR = bar
+B = b
+
+export foo bar
+
+unexport $(FOO)
+unexport $(B)ar
+
+all:
+ @echo foo=$(foo) bar=$(bar)
+ @echo foo=$$foo bar=$$bar
+',
+ '', "foo=f-ok bar=b-ok\nfoo= bar=\n");
+
+# TEST 7: Test exporting multiple variables on the same line
+
+&run_make_test('
+A = a
+B = b
+C = c
+D = d
+E = e
+F = f
+G = g
+H = h
+I = i
+J = j
+
+SOME = A B C
+
+export F G H I J
+
+export D E $(SOME)
+
+all: ; @echo A=$$A B=$$B C=$$C D=$$D E=$$E F=$$F G=$$G H=$$H I=$$I J=$$J
+',
+ '', "A=a B=b C=c D=d E=e F=f G=g H=h I=i J=j\n");
+
+# TEST 8: Test unexporting multiple variables on the same line
+
+@extraENV{qw(A B C D E F G H I J)} = qw(1 2 3 4 5 6 7 8 9 10);
+
+&run_make_test('
+A = a
+B = b
+C = c
+D = d
+E = e
+F = f
+G = g
+H = h
+I = i
+J = j
+
+SOME = A B C
+
+unexport F G H I J
+
+unexport D E $(SOME)
+
+all: ; @echo A=$$A B=$$B C=$$C D=$$D E=$$E F=$$F G=$$G H=$$H I=$$I J=$$J
+',
+ '', "A= B= C= D= E= F= G= H= I= J=\n");
+
+# TEST 9: Check setting a variable named "export"
+
+&run_make_test('
+export = 123
+export export
+export export = 456
+a: ; @echo "\$$(export)=$(export) / \$$export=$$export"
+',
+ '', "\$(export)=456 / \$export=456\n");
+
+# TEST 9: Check "export" as a target
+
+&run_make_test('
+a: export
+export: ; @echo "$@"
+',
+ '', "export\n");
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/include b/tests/scripts/features/include
new file mode 100644
index 0000000..ba8908c
--- /dev/null
+++ b/tests/scripts/features/include
@@ -0,0 +1,179 @@
+# -*-mode: perl; rm-trailing-spaces: nil-*-
+
+$description = "Test various forms of the GNU make `include' command.";
+
+$details = "\
+Test include, -include, sinclude and various regressions involving them.
+Test extra whitespace at the end of the include, multiple -includes and
+sincludes (should not give an error) and make sure that errors are reported
+for targets that were also -included.";
+
+$makefile2 = &get_tmpfile;
+
+open(MAKEFILE,"> $makefile");
+
+# The contents of the Makefile ...
+
+print MAKEFILE <<EOF;
+\#Extra space at the end of the following file name
+include $makefile2
+all: ; \@echo There should be no errors for this makefile.
+
+-include nonexistent.mk
+-include nonexistent.mk
+sinclude nonexistent.mk
+sinclude nonexistent-2.mk
+-include makeit.mk
+sinclude makeit.mk
+
+error: makeit.mk
+EOF
+
+close(MAKEFILE);
+
+
+open(MAKEFILE,"> $makefile2");
+
+print MAKEFILE "ANOTHER: ; \@echo This is another included makefile\n";
+
+close(MAKEFILE);
+
+# Create the answer to what should be produced by this Makefile
+&run_make_with_options($makefile, "all", &get_logfile);
+$answer = "There should be no errors for this makefile.\n";
+&compare_output($answer, &get_logfile(1));
+
+&run_make_with_options($makefile, "ANOTHER", &get_logfile);
+$answer = "This is another included makefile\n";
+&compare_output($answer, &get_logfile(1));
+
+$makefile = undef;
+
+# Try to build the "error" target; this will fail since we don't know
+# how to create makeit.mk, but we should also get a message (even though
+# the -include suppressed it during the makefile read phase, we should
+# see one during the makefile run phase).
+
+run_make_test
+ ('
+-include foo.mk
+error: foo.mk ; @echo $@
+',
+ '',
+ "#MAKE#: *** No rule to make target `foo.mk', needed by `error'. Stop.\n",
+ 512
+ );
+
+# Make sure that target-specific variables don't impact things. This could
+# happen because a file record is created when a target-specific variable is
+# set.
+
+run_make_test
+ ('
+bar.mk: foo := baz
+-include bar.mk
+hello: ; @echo hello
+',
+ '',
+ "hello\n"
+ );
+
+
+# Test inheritance of dontcare flag when rebuilding makefiles.
+#
+run_make_test('
+.PHONY: all
+all: ; @:
+
+-include foo
+
+foo: bar; @:
+', '', '');
+
+
+# Make sure that we don't die when the command fails but we dontcare.
+# (Savannah bug #13216).
+#
+run_make_test('
+.PHONY: all
+all:; @:
+
+-include foo
+
+foo: bar; @:
+
+bar:; @exit 1
+', '', '');
+
+# Check include, sinclude, -include with no filenames.
+# (Savannah bug #1761).
+
+run_make_test('
+.PHONY: all
+all:; @:
+include
+-include
+sinclude', '', '');
+
+
+# Test that the diagnostics is issued even if the target has been
+# tried before with the dontcare flag (direct dependency case).
+#
+run_make_test('
+-include foo
+
+all: bar
+
+foo: baz
+bar: baz
+',
+'',
+"#MAKE#: *** No rule to make target `baz', needed by `bar'. Stop.\n",
+512);
+
+# Test that the diagnostics is issued even if the target has been
+# tried before with the dontcare flag (indirect dependency case).
+#
+run_make_test('
+-include foo
+
+all: bar
+
+foo: baz
+bar: baz
+baz: end
+',
+'',
+"#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n",
+512);
+
+# Test that the diagnostics is issued even if the target has been
+# tried before with the dontcare flag (include/-include case).
+#
+run_make_test('
+include bar
+-include foo
+
+all:
+
+foo: baz
+bar: baz
+baz: end
+',
+'',
+"#MAKEFILE#:2: bar: No such file or directory
+#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n",
+512);
+
+if ($all_tests) {
+ # Test that include of a rebuild-able file doesn't show a warning
+ # Savannah bug #102
+ run_make_test(q!
+include foo
+foo: ; @echo foo = bar > $@
+!,
+ '', "#MAKE#: `foo' is up to date.\n");
+ rmfiles('foo');
+}
+
+1;
diff --git a/tests/scripts/features/mult_rules b/tests/scripts/features/mult_rules
new file mode 100644
index 0000000..6f120f1
--- /dev/null
+++ b/tests/scripts/features/mult_rules
@@ -0,0 +1,78 @@
+$description = "\
+The following test creates a makefile to test the presence
+of multiple rules for one target. One file can be the
+target of several rules if at most one rule has commands;
+the other rules can only have dependencies.";
+
+$details = "\
+The makefile created in this test contains two hardcoded rules
+for foo.o and bar.o. It then gives another multiple target rule
+with the same names as above but adding more dependencies.
+Additionally, another variable extradeps is listed as a
+dependency but is defined to be null. It can however be defined
+on the make command line as extradeps=extra.h which adds yet
+another dependency to the targets.";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE <<EOF;
+objects = foo.o bar.o
+foo.o : defs.h
+bar.o : defs.h test.h
+extradeps =
+\$(objects) : config.h \$(extradeps)
+\t\@echo EXTRA EXTRA
+EOF
+
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+&touch("defs.h","test.h","config.h");
+
+if ($vos)
+{
+ $error_code = 3307;
+}
+else
+{
+ $error_code = 512;
+}
+
+&run_make_with_options($makefile,
+ "extradeps=extra.h",
+ &get_logfile,
+ $error_code);
+
+# Create the answer to what should be produced by this Makefile
+$answer = "$make_name: *** No rule to make target `extra.h', needed by `foo.o'. Stop.\n";
+
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST #2
+# -------
+
+&touch("extra.h");
+
+&run_make_with_options($makefile,
+ "extradeps=extra.h",
+ &get_logfile,
+ 0);
+
+# Create the answer to what should be produced by this Makefile
+$answer = "EXTRA EXTRA\n";
+
+&compare_output($answer,&get_logfile(1));
+
+unlink("defs.h","test.h","config.h","extra.h");
+
+1;
+
+
+
+
+
+
diff --git a/tests/scripts/features/mult_targets b/tests/scripts/features/mult_targets
new file mode 100644
index 0000000..c8ff418
--- /dev/null
+++ b/tests/scripts/features/mult_targets
@@ -0,0 +1,46 @@
+$description = "The following test creates a makefile to test that a \n "
+ ."rule with multiple targets is equivalent to writing \n"
+ ."many rules, each with one target, and all identical aside\n"
+ ."from that.";
+
+$details = "A makefile is created with one rule and two targets. Make \n"
+ ."is called twice, once for each target, and the output which \n"
+ ."contains the target name with \$@ is looked at for the changes.\n"
+ ."This test also tests the substitute function by replacing \n"
+ ."the word output with nothing in the target name giving either\n"
+ ."an output of \"I am little\" or \"I am big\"";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE "bigoutput littleoutput: test.h\n";
+print MAKEFILE "\t\@echo I am \$(subst output,,\$@)\n";
+
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+&touch("test.h");
+
+&run_make_with_options($makefile,"bigoutput",&get_logfile);
+
+
+# Create the answer to what should be produced by this Makefile
+$answer = "I am big\n";
+
+&compare_output($answer,&get_logfile(1));
+
+&run_make_with_options($makefile,"littleoutput",&get_logfile);
+$answer = "I am little\n";
+&compare_output($answer,&get_logfile(1));
+
+unlink "test.h";
+
+1;
+
+
+
+
+
+
diff --git a/tests/scripts/features/order_only b/tests/scripts/features/order_only
new file mode 100644
index 0000000..4ebdc2b
--- /dev/null
+++ b/tests/scripts/features/order_only
@@ -0,0 +1,118 @@
+# -*-perl-*-
+$description = "Test order-only prerequisites.";
+
+$details = "\
+Create makefiles with various combinations of normal and order-only
+prerequisites and ensure they behave properly. Test the \$| variable.";
+
+# TEST #0 -- Basics
+
+run_make_test('
+%r: | baz ; @echo $< $^ $|
+bar: foo
+foo:;@:
+baz:;@:',
+ '', "foo foo baz\n");
+
+# TEST #1 -- First try: the order-only prereqs need to be built.
+
+run_make_test(q!
+foo: bar | baz
+ @echo '$$^ = $^'
+ @echo '$$| = $|'
+ touch $@
+
+.PHONY: baz
+
+bar baz:
+ touch $@!,
+ '', "touch bar\ntouch baz\n\$^ = bar\n\$| = baz\ntouch foo\n");
+
+
+# TEST #2 -- now we do it again: baz is PHONY but foo should _NOT_ be updated
+
+run_make_test(undef, '', "touch baz\n");
+
+unlink(qw(foo bar baz));
+
+# TEST #3 -- Make sure the order-only prereq was promoted to normal.
+
+run_make_test(q!
+foo: bar | baz
+ @echo '$$^ = $^'
+ @echo '$$| = $|'
+ touch $@
+
+foo: baz
+
+.PHONY: baz
+
+bar baz:
+ touch $@!,
+ '', "touch bar\ntouch baz\n\$^ = bar baz\n\$| = \ntouch foo\n");
+
+
+# TEST #4 -- now we do it again
+
+run_make_test(undef, '', "touch baz\n\$^ = bar baz\n\$| = \ntouch foo\n");
+
+unlink(qw(foo bar baz));
+
+# Test empty normal prereqs
+
+# TEST #5 -- make sure the parser was correct.
+
+run_make_test(q!
+foo:| baz
+ @echo '$$^ = $^'
+ @echo '$$| = $|'
+ touch $@
+
+.PHONY: baz
+
+baz:
+ touch $@!,
+ '', "touch baz\n\$^ = \n\$| = baz\ntouch foo\n");
+
+# TEST #6 -- now we do it again: this time foo won't be built
+
+run_make_test(undef, '', "touch baz\n");
+
+unlink(qw(foo baz));
+
+# Test order-only in pattern rules
+
+# TEST #7 -- make sure the parser was correct.
+
+run_make_test(q!
+%.w : %.x | baz
+ @echo '$$^ = $^'
+ @echo '$$| = $|'
+ touch $@
+
+all: foo.w
+
+.PHONY: baz
+foo.x baz:
+ touch $@!,
+ '',
+ "touch foo.x\ntouch baz\n\$^ = foo.x\n\$| = baz\ntouch foo.w\n");
+
+# TEST #8 -- now we do it again: this time foo.w won't be built
+
+run_make_test(undef, '', "touch baz\n");
+
+unlink(qw(foo.w foo.x baz));
+
+# TEST #9 -- make sure that $< is set correctly in the face of order-only
+# prerequisites in pattern rules.
+
+run_make_test('
+%r: | baz ; @echo $< $^ $|
+bar: foo
+foo:;@:
+baz:;@:',
+ '', "foo foo baz\n");
+
+
+1;
diff --git a/tests/scripts/features/override b/tests/scripts/features/override
new file mode 100644
index 0000000..fff6c4e
--- /dev/null
+++ b/tests/scripts/features/override
@@ -0,0 +1,45 @@
+# -*-perl-*-
+
+$description = "Test the override directive on variable assignments.";
+
+$details = "";
+
+# TEST 0: Basic override
+
+run_make_test('
+X = start
+override recur = $(X)
+override simple := $(X)
+X = end
+all: ; @echo "$(recur) $(simple)"
+',
+ 'recur=I simple=J', "end start\n");
+
+# TEST 1: Override with append
+
+run_make_test('
+X += X1
+override X += X2
+override Y += Y1
+Y += Y2
+all: ; @echo "$(X) $(Y)"
+',
+ '', "X1 X2 Y1\n");
+
+# TEST 2: Override with append to the command line
+
+run_make_test(undef, 'X=C Y=C', "C X2 C Y1\n");
+
+# Test override of define/endef
+
+run_make_test('
+override define foo
+@echo First comes the definition.
+@echo Then comes the override.
+endef
+all: ; $(foo)
+',
+ 'foo=Hello', "First comes the definition.\nThen comes the override.\n");
+
+
+1;
diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism
new file mode 100644
index 0000000..cc0f84f
--- /dev/null
+++ b/tests/scripts/features/parallelism
@@ -0,0 +1,254 @@
+# -*-perl-*-
+
+$description = "Test parallelism (-j) option.";
+
+
+$details = "This test creates a makefile with two double-colon default
+rules. The first rule has a series of sleep and echo commands
+intended to run in series. The second and third have just an
+echo statement. When make is called in this test, it is given
+the -j option with a value of 4. This tells make that it may
+start up to four jobs simultaneously. In this case, since the
+first command is a sleep command, the output of the second
+and third commands will appear before the first if indeed
+make is running all of these commands in parallel.";
+
+if (!$parallel_jobs) {
+ return -1;
+}
+
+if ($vos) {
+ $sleep_command = "sleep -seconds";
+}
+else {
+ $sleep_command = "sleep";
+}
+
+
+run_make_test("
+all : def_1 def_2 def_3
+def_1 : ; \@echo ONE; $sleep_command 3 ; echo TWO
+def_2 : ; \@$sleep_command 2 ; echo THREE
+def_3 : ; \@$sleep_command 1 ; echo FOUR",
+ '-j4', "ONE\nFOUR\nTHREE\nTWO");
+
+# Test parallelism with included files. Here we sleep/echo while
+# building the included files, to test that they are being built in
+# parallel.
+run_make_test("
+all: 1 2; \@echo success
+-include 1.inc 2.inc
+1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@
+2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@",
+ "-j4",
+ "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n");
+
+rmfiles(qw(1.inc 2.inc));
+
+
+# Test parallelism with included files--this time recurse first and make
+# sure the jobserver works.
+run_make_test("
+recurse: ; \@\$(MAKE) --no-print-directory -f #MAKEFILE# INC=yes all
+all: 1 2; \@echo success
+
+INC = no
+ifeq (\$(INC),yes)
+-include 1.inc 2.inc
+endif
+
+1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@
+2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@",
+ "-j4",
+ "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n");
+
+rmfiles(qw(1.inc 2.inc));
+
+# Grant Taylor reports a problem where tokens can be lost (not written back
+# to the pipe when they should be): this happened when there is a $(shell ...)
+# function in an exported recursive variable. I added some code to check
+# for this situation and print a message if it occurred. This test used
+# to trigger this code when I added it but no longer does after the fix.
+# We have to increase the timeout from the default (5s) on this test.
+
+run_make_test("
+export HI = \$(shell \$(\$\@.CMD))
+first.CMD = echo hi
+second.CMD = $sleep_command 4; echo hi
+
+.PHONY: all first second
+all: first second
+
+first second: ; \@echo \$\@; $sleep_command 1; echo \$\@",
+ '-j2', "first\nfirst\nsecond\nsecond", 0, 7);
+
+# Michael Matz <matz@suse.de> reported a bug where if make is running in
+# parallel without -k and two jobs die in a row, but not too close to each
+# other, then make will quit without waiting for the rest of the jobs to die.
+
+run_make_test("
+.PHONY: all fail.1 fail.2 fail.3 ok
+all: fail.1 ok fail.2 fail.3
+
+fail.1 fail.2 fail.3:
+ \@sleep \$(patsubst fail.%,%,\$\@)
+ \@echo Fail
+ \@exit 1
+
+ok:
+ \@sleep 4
+ \@echo Ok done",
+ '-rR -j5', 'Fail
+#MAKE#: *** [fail.1] Error 1
+#MAKE#: *** Waiting for unfinished jobs....
+Fail
+#MAKE#: *** [fail.2] Error 1
+Fail
+#MAKE#: *** [fail.3] Error 1
+Ok done',
+ 512);
+
+
+# Test for Savannah bug #15641.
+#
+run_make_test('
+.PHONY: all
+all:; @:
+
+-include foo.d
+
+foo.d: comp
+ @echo building $@
+
+comp: mod_a.o mod_b.o; @:
+
+mod_a.o mod_b.o:
+ @exit 1
+', '-j2', '');
+
+
+# TEST #9 -- Savannah bugs 3330 and 15919
+# In earlier versions of make this will either give the wrong answer, or hang.
+
+utouch(-10, 'target');
+run_make_test('target: intermed ; touch $@
+
+.INTERMEDIATE: intermed
+intermed: | phony ; touch $@
+
+.PHONY: phony
+phony: ; : phony', '-rR -j', ': phony');
+rmfiles('target');
+
+# TEST #10: Don't put --jobserver-fds into a re-exec'd MAKEFLAGS.
+# We can't test this directly because there's no way a makefile can
+# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it
+# by looking for "disabling jobserver mode" warnings; we should only
+# get one from the original invocation and none from the re-exec.
+# See Savannah bug #18124
+
+run_make_test(q!
+-include inc.mk
+recur:
+# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+ @rm -f inc.mk
+ @$(MAKE) -j2 -f #MAKEFILE# all
+all:
+# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+ @echo $@
+inc.mk:
+# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+ @echo 'FOO = bar' > $@
+!,
+ '--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
+
+rmfiles('inc.mk');
+
+if ($all_tests) {
+ # Implicit files aren't properly recreated during parallel builds
+ # Savannah bug #26864
+
+ # The first run works fine
+ run_make_test(q!
+%.bar: %.x foo.y ; cat $^ > $@
+%.x: ; touch $@
+foo.y: foo.y.in ; cp $< $@
+foo.y.in: ; touch $@
+!,
+ '-j2 main.bar',
+ "touch foo.y.in
+touch main.x
+cp foo.y.in foo.y
+cat main.x foo.y > main.bar
+rm main.x");
+
+ # Now we touch the .in file and make sure it still works
+ touch('foo.y.in');
+
+ run_make_test(undef, '-j2 main.bar', "cp foo.y.in foo.y
+touch main.x
+cat main.x foo.y > main.bar
+rm main.x");
+
+ # Clean up
+ rmfiles(qw(foo.y foo.y.in main.bar));
+}
+
+if ($all_tests) {
+ # Jobserver FD handling is messed up in some way.
+ # Savannah bug #28189
+ # It doesn't look like that bug anymore but this is the code it runs
+
+ run_make_test(q!
+ifdef EXTRA
+vpath %.dst /
+xxx.dst: ; true
+yyy.dst: ; true
+endif
+
+M := $(MAKE)
+xx: ; $M --no-print-directory -j2 -f $(MAKEFILE_LIST) xxx.dst yyy.dst EXTRA=1
+!,
+ '-j2',
+ '#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.
+true
+true
+');
+}
+
+# Make sure that all jobserver FDs are closed if we need to re-exec the
+# master copy.
+#
+# First, find the "default" file descriptors we normally use
+# Then make sure they're still used.
+#
+# Right now we don't have a way to run a makefile and capture the output
+# without checking it, so we can't really write this test.
+
+# run_make_test('
+# submake: ; @$(MAKE) --no-print-directory -f #MAKEFILE# fdprint 5>output
+
+# dependfile: ; @echo FOO=bar > $@
+
+# INCL := true
+
+# FOO=foo
+# ifeq ($(INCL),true)
+# -include dependfile
+# endif
+
+# fdprint: ; @echo $(filter --jobserver%,$(MAKEFLAGS))
+
+# recurse: ; @$(MAKE) --no-print-directory -f #MAKEFILE# submake INCL=true',
+# '-j2 INCL=false fdprint',
+# 'bar');
+
+# rmfiles(qw(dependfile output));
+
+
+# # Do it again, this time where the include is done by the non-master make.
+# run_make_test(undef, '-j2 recurse INCL=false', 'bar');
+
+# rmfiles(qw(dependfile output));
+
+1;
diff --git a/tests/scripts/features/patspecific_vars b/tests/scripts/features/patspecific_vars
new file mode 100644
index 0000000..8ca228d
--- /dev/null
+++ b/tests/scripts/features/patspecific_vars
@@ -0,0 +1,148 @@
+# -*-perl-*-
+$description = "Test pattern-specific variable settings.";
+
+$details = "\
+Create a makefile containing various flavors of pattern-specific variable
+settings, override and non-override, and using various variable expansion
+rules, semicolon interference, etc.";
+
+open(MAKEFILE,"> $makefile");
+
+print MAKEFILE <<'EOF';
+all: one.x two.x three.x
+FOO = foo
+BAR = bar
+BAZ = baz
+one.x: override FOO = one
+%.x: BAR = two
+t%.x: BAR = four
+thr% : override BAZ = three
+one.x two.x three.x: ; @echo $@: $(FOO) $(BAR) $(BAZ)
+four.x: baz ; @echo $@: $(FOO) $(BAR) $(BAZ)
+baz: ; @echo $@: $(FOO) $(BAR) $(BAZ)
+
+# test matching multiple patterns
+a%: AAA = aaa
+%b: BBB = ccc
+a%: BBB += ddd
+%b: AAA ?= xxx
+%b: AAA += bbb
+.PHONY: ab
+ab: ; @echo $(AAA); echo $(BBB)
+EOF
+
+close(MAKEFILE);
+
+
+# TEST #1 -- basics
+
+&run_make_with_options($makefile, "", &get_logfile);
+$answer = "one.x: one two baz\ntwo.x: foo four baz\nthree.x: foo four three\n";
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST #2 -- try the override feature
+
+&run_make_with_options($makefile, "BAZ=five", &get_logfile);
+$answer = "one.x: one two five\ntwo.x: foo four five\nthree.x: foo four three\n";
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST #3 -- make sure patterns are inherited properly
+
+&run_make_with_options($makefile, "four.x", &get_logfile);
+$answer = "baz: foo two baz\nfour.x: foo two baz\n";
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST #4 -- test multiple patterns matching the same target
+
+&run_make_with_options($makefile, "ab", &get_logfile);
+$answer = "aaa bbb\nccc ddd\n";
+&compare_output($answer,&get_logfile(1));
+
+# TEST #5 -- test pattern-specific exported variables
+#
+run_make_test('
+/%: export foo := foo
+
+/bar:
+ @echo $(foo) $$foo
+', '', 'foo foo');
+
+
+# TEST #6 -- test expansion of pattern-specific simple variables
+#
+run_make_test('
+.PHONY: all
+
+all: inherit := good $$t
+all: bar baz
+
+b%: pattern := good $$t
+
+global := orginal $$t
+
+
+# normal target
+#
+ifdef rec
+bar: a = global: $(global) pattern: $(pattern) inherit: $(inherit)
+else
+bar: a := global: $(global) pattern: $(pattern) inherit: $(inherit)
+endif
+
+bar: ; @echo \'normal: $a;\'
+
+
+# pattern target
+#
+ifdef rec
+%z: a = global: $(global) pattern: $(pattern) inherit: $(inherit)
+else
+%z: a := global: $(global) pattern: $(pattern) inherit: $(inherit)
+endif
+
+%z: ; @echo \'pattrn: $a;\'
+
+
+global := new $$t
+',
+'',
+'normal: global: orginal $t pattern: inherit: ;
+pattrn: global: orginal $t pattern: inherit: ;');
+
+
+# TEST #7 -- test expansion of pattern-specific recursive variables
+#
+run_make_test(undef, # reuse previous makefile
+'rec=1',
+'normal: global: new $t pattern: good $t inherit: good $t;
+pattrn: global: new $t pattern: good $t inherit: good $t;');
+
+# TEST #8: override in pattern-specific variables
+
+run_make_test('
+a%: override FOO += f1
+a%: FOO += f2
+ab: ; @echo "$(FOO)"
+',
+ '', "f1\n");
+
+run_make_test(undef, 'FOO=C', "C f1\n");
+
+# TEST #9: Test shortest stem selection in pattern-specific variables.
+
+run_make_test('
+%-mt.x: x := two
+%.x: x := one
+
+all: foo.x foo-mt.x
+
+foo.x: ;@echo $x
+foo-mt.x: ;@echo $x
+',
+'',
+"one\ntwo");
+
+1;
diff --git a/tests/scripts/features/patternrules b/tests/scripts/features/patternrules
new file mode 100644
index 0000000..eebe7c0
--- /dev/null
+++ b/tests/scripts/features/patternrules
@@ -0,0 +1,224 @@
+# -*-perl-*-
+
+$description = "Test pattern rules.";
+
+$details = "";
+
+use Cwd;
+
+$dir = cwd;
+$dir =~ s,.*/([^/]+)$,../$1,;
+
+
+# TEST #0: Make sure that multiple patterns where the same target
+# can be built are searched even if the first one fails
+# to match properly.
+#
+
+run_make_test(q!
+.PHONY: all
+
+all: case.1 case.2 case.3
+
+# We can't have this, due to "Implicit Rule Search Algorithm" step 5c
+#xxx: void
+
+# 1 - existing file
+%.1: void
+ @exit 1
+%.1: #MAKEFILE#
+ @exit 0
+
+# 2 - phony
+%.2: void
+ @exit 1
+%.2: 2.phony
+ @exit 0
+.PHONY: 2.phony
+
+# 3 - implicit-phony
+%.3: void
+ @exit 1
+%.3: 3.implicit-phony
+ @exit 0
+
+3.implicit-phony:
+!, '', '');
+
+# TEST #1: make sure files that are built via implicit rules are marked
+# as targets (Savannah bug #12202).
+#
+run_make_test('
+TARGETS := foo foo.out
+
+.PHONY: all foo.in
+
+all: $(TARGETS)
+
+%: %.in
+ @echo $@
+
+%.out: %
+ @echo $@
+
+foo.in: ; @:
+
+',
+'',
+'foo
+foo.out');
+
+
+# TEST #2: make sure intermediate files that also happened to be
+# prerequisites are not removed (Savannah bug #12267).
+#
+run_make_test('
+$(dir)/foo.o:
+
+$(dir)/foo.y:
+ @echo $@
+
+%.c: %.y
+ touch $@
+
+%.o: %.c
+ @echo $@
+
+.PHONY: install
+install: $(dir)/foo.c
+
+',
+"dir=$dir",
+"$dir/foo.y
+touch $dir/foo.c
+$dir/foo.o");
+
+unlink("$dir/foo.c");
+
+
+# TEST #3: make sure precious flag is set properly for targets
+# that are built via implicit rules (Savannah bug #13218).
+#
+run_make_test('
+.DELETE_ON_ERROR:
+
+.PRECIOUS: %.bar
+
+%.bar:; @touch $@ && exit 1
+
+$(dir)/foo.bar:
+
+',
+"dir=$dir",
+"#MAKE#: *** [$dir/foo.bar] Error 1",
+512);
+
+unlink("$dir/foo.bar");
+
+
+# TEST #4: make sure targets of a matched implicit pattern rule are
+# never considered intermediate (Savannah bug #13022).
+#
+run_make_test('
+.PHONY: all
+all: foo.c foo.o
+
+%.h %.c: %.in
+ touch $*.h
+ touch $*.c
+
+%.o: %.c %.h
+ echo $+ >$@
+
+%.o: %.c
+ @echo wrong rule
+
+foo.in:
+ touch $@
+
+',
+'',
+'touch foo.in
+touch foo.h
+touch foo.c
+echo foo.c foo.h >foo.o');
+
+unlink('foo.in', 'foo.h', 'foo.c', 'foo.o');
+
+# TEST #5: make sure both prefix and suffix patterns work with multiple
+# target patterns (Savannah bug #26593).
+#
+run_make_test('
+all: foo.s1 foo.s2 p1.foo p2.foo
+
+p1.% p2.%: %.orig
+ @echo $@
+%.s1 %.s2: %.orig
+ @echo $@
+
+.PHONY: foo.orig
+',
+ '', "foo.s1\np1.foo\n");
+
+# TEST 6: Make sure that non-target files are still eligible to be created
+# as part of implicit rule chaining. Savannah bug #17752.
+
+run_make_test(q!
+BIN = xyz
+COPY = $(BIN).cp
+SRC = $(BIN).c
+allbroken: $(COPY) $(BIN) ; @echo ok
+$(SRC): ; @echo 'main(){}' > $@
+%.cp: % ; @cp $< $@
+% : %.c ; @cp $< $@
+clean: ; @rm -rf $(SRC) $(COPY) $(BIN)
+!,
+ '', "ok\n");
+
+unlink(qw(xyz xyz.cp xyz.c));
+
+# TEST 7: Make sure that all prereqs of all "also_make" targets get created
+# before any of the things that depend on any of them. Savannah bug #19108.
+
+run_make_test(q!
+final: x ; @echo $@
+x: x.t1 x.t2 ; @echo $@
+x.t2: dep
+dep: ; @echo $@
+%.t1 %.t2: ; @echo $*.t1 ; echo $*.t2
+!,
+ '', "dep\nx.t1\nx.t2\nx\nfinal\n");
+
+
+# TEST 8: Verify we can remove pattern rules. Savannah bug #18622.
+
+my @f = (qw(foo.w foo.ch));
+touch(@f);
+
+run_make_test(q!
+CWEAVE := :
+
+# Disable builtin rules
+%.tex : %.w
+%.tex : %.w %.ch
+!,
+ 'foo.tex',
+ "#MAKE#: *** No rule to make target `foo.tex'. Stop.", 512);
+
+unlink(@f);
+
+# TEST #9: Test shortest stem selection in pattern rules.
+
+run_make_test('
+%.x: ;@echo one
+%-mt.x: ;@echo two
+
+all: foo.x foo-mt.x
+',
+'',
+"one\ntwo");
+
+1;
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/quoting b/tests/scripts/features/quoting
new file mode 100644
index 0000000..916681c
--- /dev/null
+++ b/tests/scripts/features/quoting
@@ -0,0 +1,32 @@
+# -*-perl-*-
+
+$description = "The following test creates a makefile to test using \n" .
+ "quotes within makefiles.";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE <<'EOM';
+SHELL = /bin/sh
+TEXFONTS = NICEFONT
+DEFINES = -DDEFAULT_TFM_PATH=\".:$(TEXFONTS)\"
+test: ; @"echo" 'DEFINES = $(DEFINES)'
+EOM
+
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+
+&run_make_with_options($makefile,"",&get_logfile);
+
+
+# Create the answer to what should be produced by this Makefile
+$answer = 'DEFINES = -DDEFAULT_TFM_PATH=\".:NICEFONT\"' . "\n";
+
+# COMPARE RESULTS
+
+&compare_output($answer,&get_logfile(1));
+
+1;
diff --git a/tests/scripts/features/recursion b/tests/scripts/features/recursion
new file mode 100644
index 0000000..a6b8f90
--- /dev/null
+++ b/tests/scripts/features/recursion
@@ -0,0 +1,55 @@
+# -*-perl-*-
+$description = "Test recursion.";
+
+$details = "DETAILS";
+
+# Test some basic recursion.
+run_make_test('
+all:
+ $(MAKE) -f #MAKEFILE# foo
+foo:
+ @echo $(MAKE)
+ @echo MAKELEVEL = $(MAKELEVEL)
+ $(MAKE) -f #MAKEFILE# last
+last:
+ @echo $(MAKE)
+ @echo MAKELEVEL = $(MAKELEVEL)
+ @echo THE END
+',
+ ('CFLAGS=-O -w' . ($parallel_jobs ? ' -j 2' : '')),
+ ($vos
+ ? "#MAKE#: Entering directory `#PWD#'
+make 'CFLAGS=-O' -f #MAKEFILE# foo
+make CFLAGS=-O
+MAKELEVEL = 0
+make 'CFLAGS=-O' -f #MAKEFILE# last
+make CFLAGS=-O
+MAKELEVEL = 0
+THE END
+#MAKE#: Leaving directory `#PWD#'"
+ : "#MAKE#: Entering directory `#PWD#'
+#MAKEPATH# -f #MAKEFILE# foo
+#MAKE#[1]: Entering directory `#PWD#'
+#MAKEPATH#
+MAKELEVEL = 1
+#MAKEPATH# -f #MAKEFILE# last
+#MAKE#[2]: Entering directory `#PWD#'
+#MAKEPATH#
+MAKELEVEL = 2
+THE END
+#MAKE#[2]: Leaving directory `#PWD#'
+#MAKE#[1]: Leaving directory `#PWD#'
+#MAKE#: Leaving directory `#PWD#'"));
+
+
+# Test command line overrides.
+run_make_test('
+recur: all ; @$(MAKE) --no-print-directory -f #MAKEFILE# a=AA all
+all: ; @echo "MAKEOVERRIDES = $(MAKEOVERRIDES)"
+',
+ 'a=ZZ',
+ 'MAKEOVERRIDES = a=ZZ
+MAKEOVERRIDES = a=AA
+');
+
+1;
diff --git a/tests/scripts/features/reinvoke b/tests/scripts/features/reinvoke
new file mode 100644
index 0000000..9952ced
--- /dev/null
+++ b/tests/scripts/features/reinvoke
@@ -0,0 +1,65 @@
+# -*-mode: perl-*-
+
+$description = "Test GNU make's auto-reinvocation feature.";
+
+$details = "\
+If the makefile or one it includes can be rebuilt then it is, and make
+is reinvoked. We create a rule to rebuild the makefile from a temp
+file, then touch the temp file to make it newer than the makefile.";
+
+$omkfile = $makefile;
+
+&utouch(-600, 'incl.mk');
+# For some reason if we don't do this then the test fails for systems
+# with sub-second timestamps, maybe + NFS? Not sure.
+&utouch(-1, 'incl-1.mk');
+
+run_make_test('
+all: ; @echo running rules.
+
+#MAKEFILE# incl.mk: incl-1.mk
+ @echo rebuilding $@
+ @echo >> $@
+
+include incl.mk',
+ '', "rebuilding incl.mk\nrunning rules.\n");
+
+# Make sure updating the makefile itself also works
+
+&utouch(-600, $omkfile);
+
+run_make_test(undef, '', "rebuilding #MAKEFILE#\nrunning rules.\n");
+
+&rmfiles('incl.mk', 'incl-1.mk');
+
+
+# In this test we create an included file that's out-of-date, but then
+# the rule doesn't update it. Make shouldn't re-exec.
+
+&utouch(-600, 'b','a');
+#&utouch(-10, 'a');
+&touch('c');
+
+run_make_test('
+SHELL = /bin/sh
+
+all: ; @echo hello
+
+a : b ; echo >> $@
+
+b : c ; [ -f $@ ] || echo >> $@
+
+c: ; echo >> $@
+
+include $(F)',
+ 'F=a', "[ -f b ] || echo >> b\nhello\n");
+
+# Now try with the file we're not updating being the actual file we're
+# including: this and the previous one test different parts of the code.
+
+run_make_test(undef, "F=b", "[ -f b ] || echo >> b\nhello\n")
+
+&rmfiles('a','b','c');
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/se_explicit b/tests/scripts/features/se_explicit
new file mode 100644
index 0000000..79e0a36
--- /dev/null
+++ b/tests/scripts/features/se_explicit
@@ -0,0 +1,156 @@
+# -*-perl-*-
+$description = "Test second expansion in ordinary rules.";
+
+$details = "";
+
+# TEST #0: Test handing of '$' in prerequisites with and without second
+# expansion.
+
+run_make_test(q!
+ifdef SE
+ .SECONDEXPANSION:
+endif
+foo$$bar: bar$$baz bar$$biz ; @echo '$@ : $^'
+PRE = one two
+bar$$baz: $$(PRE)
+baraz: $$(PRE)
+PRE = three four
+.DEFAULT: ; @echo '$@'
+!,
+ '',
+ "\$\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
+
+run_make_test(undef, 'SE=1', "three\nfour\nbariz\nfoo\$bar : baraz bariz");
+
+# TEST #1: automatic variables.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+.DEFAULT: ; @echo '$@'
+
+foo: bar baz
+
+foo: biz | buz
+
+foo: $$@.1 \
+ $$<.2 \
+ $$(addsuffix .3,$$^) \
+ $$(addsuffix .4,$$+) \
+ $$|.5 \
+ $$*.6
+
+!,
+'',
+'bar
+baz
+biz
+buz
+foo.1
+bar.2
+bar.3
+baz.3
+biz.3
+bar.4
+baz.4
+biz.4
+buz.5
+.6
+');
+
+
+# Test #2: target/pattern -specific variables.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+.DEFAULT: ; @echo '$@'
+
+foo.x: $$a $$b
+
+foo.x: a := bar
+
+%.x: b := baz
+!,
+'',
+'bar
+baz
+');
+
+
+# Test #3: order of prerequisites.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+.DEFAULT: ; @echo '$@'
+
+all: foo bar baz
+
+# Subtest #1
+foo: foo.1; @:
+foo: foo.2
+foo: foo.3
+
+# Subtest #2
+bar: bar.2
+bar: bar.1; @:
+bar: bar.3
+
+# Subtest #3
+baz: baz.1
+baz: baz.2
+baz: ; @:
+!,
+'',
+'foo.1
+foo.2
+foo.3
+bar.1
+bar.2
+bar.3
+baz.1
+baz.2
+');
+
+# TEST #4: eval in a context where there is no reading_file
+run_make_test(q!
+.SECONDEXPANSION:
+all : $$(eval $$(info test))
+!,
+ '', "test\n#MAKE#: Nothing to be done for `all'.\n");
+
+# TEST #5: (NEGATIVE) catch eval in a prereq list trying to create new
+# target/prereq relationships.
+
+run_make_test(q!
+.SECONDEXPANSION:
+proj1.exe : proj1.o $$(eval $$(test))
+define test
+proj1.o : proj1.c
+proj1.c: proj1.h
+endef
+!,
+ '', "#MAKE#: *** prerequisites cannot be defined in recipes. Stop.\n", 512);
+
+
+# Automatic $$+ variable expansion issue. Savannah bug #25780
+run_make_test(q!
+all : foo foo
+.SECONDEXPANSION:
+all : $$+ ; @echo '$+'
+foo : ;
+!,
+ '', "foo foo foo foo\n");
+
+
+# Automatic $$+ variable expansion issue. Savannah bug #25780
+run_make_test(q!
+all : bar bar
+bar : ;
+q%x : ;
+.SECONDEXPANSION:
+a%l: q1x $$+ q2x ; @echo '$+'
+!,
+ '', "q1x bar bar q2x bar bar\n");
+
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/se_implicit b/tests/scripts/features/se_implicit
new file mode 100644
index 0000000..e9acb2f
--- /dev/null
+++ b/tests/scripts/features/se_implicit
@@ -0,0 +1,226 @@
+# -*-perl-*-
+$description = "Test second expansion in ordinary rules.";
+
+$details = "";
+
+use Cwd;
+
+$dir = cwd;
+$dir =~ s,.*/([^/]+)$,../$1,;
+
+
+# Test #1: automatic variables.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+.DEFAULT: ; @echo '$@'
+
+foo.a: bar baz
+
+foo.a: biz | buz
+
+foo.%: 1.$$@ \
+ 2.$$< \
+ $$(addprefix 3.,$$^) \
+ $$(addprefix 4.,$$+) \
+ 5.$$| \
+ 6.$$*
+ @:
+
+1.foo.a \
+2.bar \
+3.bar \
+3.baz \
+3.biz \
+4.bar \
+4.baz \
+4.biz \
+5.buz \
+6.a:
+ @echo '$@'
+
+!,
+'',
+'1.foo.a
+2.bar
+3.bar
+3.baz
+3.biz
+4.bar
+4.baz
+4.biz
+5.buz
+6.a
+bar
+baz
+biz
+buz
+');
+
+
+# Test #2: target/pattern -specific variables.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+foo.x:
+
+foo.%: $$(%_a) $$(%_b) bar
+ @:
+
+foo.x: x_a := bar
+
+%.x: x_b := baz
+
+bar baz: ; @echo '$@'
+!,
+ '', "bar\nbaz\n");
+
+
+# Test #3: order of prerequisites.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+.DEFAULT: ; @echo '$@'
+
+all: foo bar baz
+
+
+# Subtest #1
+#
+%oo: %oo.1; @:
+
+foo: foo.2
+
+foo: foo.3
+
+foo.1: ; @echo '$@'
+
+
+# Subtest #2
+#
+bar: bar.2
+
+%ar: %ar.1; @:
+
+bar: bar.3
+
+bar.1: ; @echo '$@'
+
+
+# Subtest #3
+#
+baz: baz.1
+
+baz: baz.2
+
+%az: ; @:
+!,
+ '',
+'foo.1
+foo.2
+foo.3
+bar.1
+bar.2
+bar.3
+baz.1
+baz.2
+');
+
+
+# Test #4: stem splitting logic.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+$(dir)/tmp/bar.o:
+
+$(dir)/tmp/foo/bar.c: ; @echo '$@'
+$(dir)/tmp/bar/bar.c: ; @echo '$@'
+foo.h: ; @echo '$@'
+
+%.o: $$(addsuffix /%.c,foo bar) foo.h
+ @echo '$@: {$<} $^'
+!,
+ "dir=$dir", "$dir/tmp/foo/bar.c
+$dir/tmp/bar/bar.c
+foo.h
+$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(q!
+.SECONDEXPANSION:
+$(dir)/tmp/foo.o: $(dir)/tmp/foo.c
+$(dir)/tmp/foo.c: ; @echo '$@'
+bar.h: ; @echo '$@'
+
+%.o: %.c|bar.h
+ @echo '$@: {$<} {$|} $^'
+
+!,
+ "dir=$dir", "$dir/tmp/foo.c
+bar.h
+$dir/tmp/foo.o: {$dir/tmp/foo.c} {bar.h} $dir/tmp/foo.c
+");
+
+
+# Test #6: lack of implicit prerequisites.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+foo.o: foo.c
+foo.c: ; @echo '$@'
+
+%.o:
+ @echo '$@: {$<} $^'
+!,
+ '', "foo.c\nfoo.o: {foo.c} foo.c\n");
+
+
+# Test #7: Test stem from the middle of the name.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+foobarbaz:
+
+foo%baz: % $$*.1
+ @echo '$*'
+
+bar bar.1:
+ @echo '$@'
+!,
+ '', "bar\nbar.1\nbar\n");
+
+
+# Test #8: Make sure stem triple-expansion does not happen.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+foo$$bar:
+
+f%r: % $$*.1
+ @echo '$*'
+
+oo$$ba oo$$ba.1:
+ @echo '$@'
+!,
+ '', 'oo$ba
+oo$ba.1
+oo$ba
+');
+
+# Test #9: Check the value of $^
+run_make_test(q!
+.SECONDEXPANSION:
+
+%.so: | $$(extra) ; @echo $^
+
+foo.so: extra := foo.o
+foo.so:
+foo.o:
+!,
+ '', "\n");
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/se_statpat b/tests/scripts/features/se_statpat
new file mode 100644
index 0000000..b1e59e1
--- /dev/null
+++ b/tests/scripts/features/se_statpat
@@ -0,0 +1,107 @@
+# -*-perl-*-
+$description = "Test second expansion in static pattern rules.";
+
+$details = "";
+
+# Test #1: automatic variables.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+.DEFAULT: ; @echo '$@'
+
+foo.a foo.b: foo.%: bar.% baz.%
+foo.a foo.b: foo.%: biz.% | buz.%
+
+foo.a foo.b: foo.%: $$@.1 \
+ $$<.2 \
+ $$(addsuffix .3,$$^) \
+ $$(addsuffix .4,$$+) \
+ $$|.5 \
+ $$*.6
+!,
+ '', 'bar.a
+baz.a
+biz.a
+buz.a
+foo.a.1
+bar.a.2
+bar.a.3
+baz.a.3
+biz.a.3
+bar.a.4
+baz.a.4
+biz.a.4
+buz.a.5
+a.6
+');
+
+
+# Test #2: target/pattern -specific variables.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+.DEFAULT: ; @echo '$@'
+
+foo.x foo.y: foo.%: $$(%_a) $$($$*_b)
+
+foo.x: x_a := bar
+
+%.x: x_b := baz
+!,
+ '', "bar\nbaz\n");
+
+
+# Test #3: order of prerequisites.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+.DEFAULT: ; @echo '$@'
+
+all: foo.a bar.a baz.a
+
+# Subtest #1
+foo.a foo.b: foo.%: foo.%.1; @:
+foo.a foo.b: foo.%: foo.%.2
+foo.a foo.b: foo.%: foo.%.3
+
+
+# Subtest #2
+bar.a bar.b: bar.%: bar.%.2
+bar.a bar.b: bar.%: bar.%.1; @:
+bar.a bar.b: bar.%: bar.%.3
+
+
+# Subtest #3
+baz.a baz.b: baz.%: baz.%.1
+baz.a baz.b: baz.%: baz.%.2
+baz.a baz.b: ; @:
+!,
+ '', 'foo.a.1
+foo.a.2
+foo.a.3
+bar.a.1
+bar.a.2
+bar.a.3
+baz.a.1
+baz.a.2
+');
+
+
+# Test #4: Make sure stem triple-expansion does not happen.
+#
+run_make_test(q!
+.SECONDEXPANSION:
+foo$$bar: f%r: % $$*.1
+ @echo '$*'
+
+oo$$ba oo$$ba.1:
+ @echo '$@'
+!,
+ '', 'oo$ba
+oo$ba.1
+oo$ba
+');
+
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/statipattrules b/tests/scripts/features/statipattrules
new file mode 100644
index 0000000..3f363de
--- /dev/null
+++ b/tests/scripts/features/statipattrules
@@ -0,0 +1,111 @@
+# -*-perl-*-
+$description = "Test handling of static pattern rules.";
+
+$details = "\
+The makefile created in this test has three targets. The
+filter command is used to get those target names ending in
+.o and statically creates a compile command with the target
+name and the target name with .c. It also does the same thing
+for another target filtered with .elc and creates a command
+to emacs a .el file";
+
+&touch('bar.c', 'lose.c');
+
+# TEST #0
+# -------
+
+run_make_test('
+files = foo.elc bar.o lose.o
+
+$(filter %.o,$(files)): %.o: %.c ; @echo CC -c $(CFLAGS) $< -o $@
+
+$(filter %.elc,$(files)): %.elc: %.el ; @echo emacs $<
+',
+ '',
+ 'CC -c bar.c -o bar.o');
+
+# TEST #1
+# -------
+
+run_make_test(undef, 'lose.o', 'CC -c lose.c -o lose.o');
+
+
+# TEST #2
+# -------
+&touch("foo.el");
+
+run_make_test(undef, 'foo.elc', 'emacs foo.el');
+
+# Clean up after the first tests.
+unlink('foo.el', 'bar.c', 'lose.c');
+
+
+# TEST #3 -- PR/1670: don't core dump on invalid static pattern rules
+# -------
+
+run_make_test('
+.DEFAULT: ; @echo $@
+foo: foo%: % %.x % % % y.% % ; @echo $@
+',
+ '', ".x\ny.\nfoo");
+
+
+# TEST #4 -- bug #12180: core dump on a stat pattern rule with an empty
+# prerequisite list.
+run_make_test('
+foo.x bar.x: %.x : ; @echo $@
+
+',
+ '', 'foo.x');
+
+
+# TEST #5 -- bug #13881: double colon static pattern rule does not
+# substitute %.
+run_make_test('
+foo.bar:: %.bar: %.baz
+foo.baz: ;@:
+',
+ '', '');
+
+
+# TEST #6: make sure the second stem does not overwrite the first
+# perprerequisite's stem (Savannah bug #16053).
+#
+run_make_test('
+all.foo.bar: %.foo.bar: %.one
+
+all.foo.bar: %.bar: %.two
+
+all.foo.bar:
+ @echo $*
+ @echo $^
+
+.DEFAULT:;@:
+',
+'',
+'all.foo
+all.one all.foo.two');
+
+
+# TEST #7: make sure the second stem does not overwrite the first
+# perprerequisite's stem when second expansion is enabled
+# (Savannah bug #16053).
+#
+run_make_test('
+.SECONDEXPANSION:
+
+all.foo.bar: %.foo.bar: %.one $$*-one
+
+all.foo.bar: %.bar: %.two $$*-two
+
+all.foo.bar:
+ @echo $*
+ @echo $^
+
+.DEFAULT:;@:
+',
+'',
+'all.foo
+all.one all-one all.foo.two all.foo-two');
+
+1;
diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars
new file mode 100644
index 0000000..ddd6c1f
--- /dev/null
+++ b/tests/scripts/features/targetvars
@@ -0,0 +1,263 @@
+# -*-perl-*-
+$description = "Test target-specific variable settings.";
+
+$details = "\
+Create a makefile containing various flavors of target-specific variable
+values, override and non-override, and using various variable expansion
+rules, semicolon interference, etc.";
+
+run_make_test('
+SHELL = /bin/sh
+export FOO = foo
+export BAR = bar
+one: override FOO = one
+one two: ; @echo $(FOO) $(BAR)
+two: BAR = two
+three: ; BAR=1000
+ @echo $(FOO) $(BAR)
+# Some things that shouldn not be target vars
+funk : override
+funk : override adelic
+adelic override : ; echo $@
+# Test per-target recursive variables
+four:FOO=x
+four:VAR$(FOO)=ok
+four: ; @echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx)"
+five:FOO=x
+five six : VAR$(FOO)=good
+five six: ;@echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx) $(VARfoo)"
+# Test per-target variable inheritance
+seven: eight
+seven eight: ; @echo $@: $(FOO) $(BAR)
+seven: BAR = seven
+seven: FOO = seven
+eight: BAR = eight
+# Test the export keyword with per-target variables
+nine: ; @echo $(FOO) $(BAR) $$FOO $$BAR
+nine: FOO = wallace
+nine-a: export BAZ = baz
+nine-a: ; @echo $$BAZ
+# Test = escaping
+EQ = =
+ten: one$(EQ)two
+ten: one $(EQ) two
+ten one$(EQ)two $(EQ):;@echo $@
+.PHONY: one two three four five six seven eight nine ten $(EQ) one$(EQ)two
+# Test target-specific vars with pattern/suffix rules
+QVAR = qvar
+RVAR = =
+%.q : ; @echo $(QVAR) $(RVAR)
+foo.q : RVAR += rvar
+# Target-specific vars with multiple LHS pattern rules
+%.r %.s %.t: ; @echo $(QVAR) $(RVAR) $(SVAR) $(TVAR)
+foo.r : RVAR += rvar
+foo.t : TVAR := $(QVAR)
+',
+ "one two three", "one bar\nfoo two\nBAR=1000\nfoo bar\n");
+
+# TEST #2
+
+run_make_test(undef, "one two FOO=1 BAR=2", "one 2\n1 2\n");
+
+# TEST #3
+
+run_make_test(undef, "four", "x ok ok\n");
+
+# TEST #4
+
+run_make_test(undef, "seven", "eight: seven eight\nseven: seven seven\n");
+
+# TEST #5
+
+run_make_test(undef, "nine", "wallace bar wallace bar\n");
+
+# TEST #5-a
+
+run_make_test(undef, "nine-a", "baz\n");
+
+# TEST #6
+
+run_make_test(undef, "ten", "one=two\none bar\n=\nfoo two\nten\n");
+
+# TEST #6
+
+run_make_test(undef, "foo.q bar.q", "qvar = rvar\nqvar =\n");
+
+# TEST #7
+
+run_make_test(undef, "foo.t bar.s", "qvar = qvar\nqvar =\n");
+
+
+# TEST #8
+# For PR/1378: Target-specific vars don't inherit correctly
+
+run_make_test('
+foo: FOO = foo
+bar: BAR = bar
+foo: bar
+bar: baz
+baz: ; @echo $(FOO) $(BAR)
+', "", "foo bar\n");
+
+# TEST #9
+# For PR/1380: Using += assignment in target-specific variables sometimes fails
+# Also PR/1831
+
+run_make_test('
+.PHONY: all one
+all: FOO += baz
+all: one; @echo $(FOO)
+
+FOO = bar
+
+one: FOO += biz
+one: FOO += boz
+one: ; @echo $(FOO)
+',
+ '', "bar baz biz boz\nbar baz\n");
+
+# Test #10
+
+run_make_test(undef, 'one', "bar biz boz\n");
+
+# Test #11
+# PR/1709: Test semicolons in target-specific variable values
+
+run_make_test('
+foo : FOO = ; ok
+foo : ; @echo "$(FOO)"
+',
+ '', "; ok\n");
+
+# Test #12
+# PR/2020: More hassles with += target-specific vars. I _really_ think
+# I nailed it this time :-/.
+
+run_make_test('
+.PHONY: a
+
+BLAH := foo
+COMMAND = echo $(BLAH)
+
+a: ; @$(COMMAND)
+
+a: BLAH := bar
+a: COMMAND += snafu $(BLAH)
+',
+ '', "bar snafu bar\n");
+
+# Test #13
+# Test double-colon rules with target-specific variable values
+
+run_make_test('
+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
+',
+ 'foo', "ok ok foo nopat\nok ok foo nopat\n");
+
+# Test #14
+# Test double-colon rules with target-specific variable values and
+# inheritance
+
+run_make_test(undef, 'bar', "ok ok bar nopat\nok ok bar nopat\n");
+
+# Test #15
+# Test double-colon rules with pattern-specific variable values
+
+run_make_test(undef, 'foo PATTERN=yes', "ok ok foo pat\nok ok foo pat\n");
+
+# Test #16
+# Test target-specific variables with very long command line
+# (> make default buffer length)
+
+run_make_test('
+base_metals_fmd_reports.sun5 base_metals_fmd_reports CreateRealPositions CreateMarginFunds deals_changed_since : BUILD_OBJ=$(shell if [ -f "build_information.generate" ]; then echo "$(OBJ_DIR)/build_information.o"; else echo "no build information"; fi )
+
+deals_changed_since: ; @echo $(BUILD_OBJ)
+',
+ '', "no build information\n");
+
+# TEST #17
+
+# Test a merge of set_lists for files, where one list is much longer
+# than the other. See Savannah bug #15757.
+
+mkdir('t1', 0777);
+touch('t1/rules.mk');
+
+run_make_test('
+VPATH = t1
+include rules.mk
+.PHONY: all
+all: foo.x
+foo.x : rules.mk ; @echo MYVAR=$(MYVAR) FOOVAR=$(FOOVAR) ALLVAR=$(ALLVAR)
+all: ALLVAR = xxx
+foo.x: FOOVAR = bar
+rules.mk : MYVAR = foo
+.INTERMEDIATE: foo.x rules.mk
+',
+ '-I t1', 'MYVAR= FOOVAR=bar ALLVAR=xxx');
+
+rmfiles('t1/rules.mk');
+rmdir('t1');
+
+# TEST #18
+
+# Test appending to a simple variable containing a "$": avoid a
+# double-expansion. See Savannah bug #15913.
+
+run_make_test('
+VAR := $$FOO
+foo: VAR += BAR
+foo: ; @echo '."'".'$(VAR)'."'".'
+',
+ '', '$FOO BAR');
+
+# TEST #19: Override with append variables
+
+run_make_test('
+a: override FOO += f1
+a: FOO += f2
+a: ; @echo "$(FOO)"
+',
+ '', "f1\n");
+
+run_make_test(undef, 'FOO=C', "C f1\n");
+
+# TEST #20: Check for continuation after semicolons
+
+run_make_test(q!
+a: A = 'hello; \
+world'
+a: ; @echo $(A)
+!,
+ '', "hello; world\n");
+
+# TEST #19: Test define/endef variables as target-specific vars
+
+# run_make_test('
+# define b
+# @echo global
+# endef
+# a: define b
+# @echo local
+# endef
+
+# a: ; $(b)
+# ',
+# '', "local\n");
+
+1;
diff --git a/tests/scripts/features/varnesting b/tests/scripts/features/varnesting
new file mode 100644
index 0000000..15d5071
--- /dev/null
+++ b/tests/scripts/features/varnesting
@@ -0,0 +1,34 @@
+$description = "The following test creates a makefile to ...";
+
+$details = "";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE "x = variable1\n"
+ ."variable2 := Hello\n"
+ ."y = \$(subst 1,2,\$(x))\n"
+ ."z = y\n"
+ ."a := \$(\$(\$(z)))\n"
+ ."all: \n"
+ ."\t\@echo \$(a)\n";
+
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+&run_make_with_options($makefile,"",&get_logfile);
+
+# Create the answer to what should be produced by this Makefile
+$answer = "Hello\n";
+
+&compare_output($answer,&get_logfile(1));
+
+1;
+
+
+
+
+
+
diff --git a/tests/scripts/features/vpath b/tests/scripts/features/vpath
new file mode 100644
index 0000000..a3aebd9
--- /dev/null
+++ b/tests/scripts/features/vpath
@@ -0,0 +1,81 @@
+# -*-perl-*-
+
+$description = "The following test creates a makefile to test the \n"
+ ."vpath directive which allows you to specify a search \n"
+ ."path for a particular class of filenames, those that\n"
+ ."match a particular pattern.";
+
+$details = "This tests the vpath directive by specifying search directories\n"
+ ."for one class of filenames with the form: vpath pattern directories"
+ ."\nIn this test, we specify the working directory for all files\n"
+ ."that end in c or h. We also test the variables $@ (which gives\n"
+ ."target name) and $^ (which is a list of all dependencies \n"
+ ."including the directories in which they were found). It also\n"
+ ."uses the function firstword used to extract just the first\n"
+ ."dependency from the entire list.";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE "vpath %.c foo\n";
+print MAKEFILE "vpath %.c $workdir\n";
+print MAKEFILE "vpath %.h $workdir\n";
+print MAKEFILE "objects = main.o kbd.o commands.o display.o insert.o\n";
+print MAKEFILE "edit: \$(objects)\n";
+print MAKEFILE "\t\@echo cc -o \$@ \$^\n";
+print MAKEFILE "main.o : main.c defs.h\n";
+print MAKEFILE "\t\@echo cc -c \$(firstword \$^)\n";
+print MAKEFILE "kbd.o : kbd.c defs.h command.h\n";
+print MAKEFILE "\t\@echo cc -c kbd.c\n";
+print MAKEFILE "commands.o : command.c defs.h command.h\n";
+print MAKEFILE "\t\@echo cc -c commands.c\n";
+print MAKEFILE "display.o : display.c defs.h buffer.h\n";
+print MAKEFILE "\t\@echo cc -c display.c\n";
+print MAKEFILE "insert.o : insert.c defs.h buffer.h\n";
+print MAKEFILE "\t\@echo cc -c insert.c\n";
+
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+
+@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h",
+ "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h",
+ "$workdir${pathsep}commands.c","$workdir${pathsep}display.c",
+ "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c",
+ "$workdir${pathsep}command.c");
+
+&touch(@files_to_touch);
+
+&run_make_with_options($makefile,"",&get_logfile);
+
+# Create the answer to what should be produced by this Makefile
+$answer = "cc -c $workdir${pathsep}main.c\ncc -c kbd.c\ncc -c commands.c\n"
+ ."cc -c display.c\n"
+ ."cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o "
+ ."insert.o\n";
+
+if (&compare_output($answer,&get_logfile(1)))
+{
+ unlink @files_to_touch;
+}
+
+# TEST 2: after vpath lookup ensure we don't get incorrect circular dependency
+# warnings due to change of struct file ptr. Savannah bug #13529.
+
+mkdir('vpath-d', 0777);
+
+run_make_test(q!
+vpath %.te vpath-d/
+.SECONDARY:
+default: vpath-d/a vpath-d/b
+vpath-d/a: fail.te
+vpath-d/b : fail.te
+vpath-d/fail.te:
+!,
+ '', "#MAKE#: Nothing to be done for `default'.\n");
+
+rmdir('vpath-d');
+
+1;
diff --git a/tests/scripts/features/vpath2 b/tests/scripts/features/vpath2
new file mode 100644
index 0000000..7e970a7
--- /dev/null
+++ b/tests/scripts/features/vpath2
@@ -0,0 +1,45 @@
+$description = "This is part 2 in a series to test the vpath directive\n"
+ ."It tests the three forms of the directive:\n"
+ ." vpath pattern directive\n"
+ ." vpath pattern (clears path associated with pattern)\n"
+ ." vpath (clears all paths specified with vpath)\n";
+
+$details = "This test simply adds many search paths using various vpath\n"
+ ."directive forms and clears them afterwards. It has a simple\n"
+ ."rule to print a message at the end to confirm that the makefile\n"
+ ."ran with no errors.\n";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE "VPATH = $workdir:$sourcedir\n";
+print MAKEFILE "vpath %.c foo\n";
+print MAKEFILE "vpath %.c $workdir\n";
+print MAKEFILE "vpath %.c $sourcedir\n";
+print MAKEFILE "vpath %.h $workdir\n";
+print MAKEFILE "vpath %.c\n";
+print MAKEFILE "vpath\n";
+print MAKEFILE "all:\n";
+print MAKEFILE "\t\@echo ALL IS WELL\n";
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+&run_make_with_options($makefile,"",&get_logfile);
+
+# Create the answer to what should be produced by this Makefile
+$answer = "ALL IS WELL\n";
+
+&compare_output($answer,&get_logfile(1));
+
+1;
+
+
+
+
+
+
+
+
+
diff --git a/tests/scripts/features/vpath3 b/tests/scripts/features/vpath3
new file mode 100644
index 0000000..978c5ee
--- /dev/null
+++ b/tests/scripts/features/vpath3
@@ -0,0 +1,50 @@
+# -*-perl-*-
+
+$description = "Test the interaction of the -lfoo feature and vpath";
+$details = "";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE "vpath %.a a1\n";
+print MAKEFILE "vpath %.so b1\n";
+print MAKEFILE "vpath % a2 b2\n";
+print MAKEFILE "vpath % b3\n";
+print MAKEFILE "all: -l1 -l2 -l3; \@echo \$^\n";
+
+# END of Contents of MAKEFILE
+
+close(MAKEFILE);
+
+mkdir("a1", 0777);
+mkdir("b1", 0777);
+mkdir("a2", 0777);
+mkdir("b2", 0777);
+mkdir("b3", 0777);
+
+@files_to_touch = ("a1${pathsep}lib1.a",
+ "b1${pathsep}lib1.so",
+ "a2${pathsep}lib2.a",
+ "b2${pathsep}lib2.so",
+ "lib3.a",
+ "b3${pathsep}lib3.so");
+
+&touch(@files_to_touch);
+
+&run_make_with_options($makefile,"",&get_logfile);
+
+# Create the answer to what should be produced by this Makefile
+$answer = "a1${pathsep}lib1.a a2${pathsep}lib2.a lib3.a\n";
+
+if (&compare_output($answer,&get_logfile(1)))
+{
+ unlink @files_to_touch;
+ rmdir("a1");
+ rmdir("b1");
+ rmdir("a2");
+ rmdir("b2");
+ rmdir("b3");
+}
+
+1;
diff --git a/tests/scripts/features/vpathgpath b/tests/scripts/features/vpathgpath
new file mode 100644
index 0000000..f7683f5
--- /dev/null
+++ b/tests/scripts/features/vpathgpath
@@ -0,0 +1,66 @@
+# -*-perl-*-
+$description = "Tests VPATH+/GPATH functionality.";
+
+$details = "";
+
+$VP = "$workdir$pathsep";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE "VPATH = $VP\n";
+
+print MAKEFILE <<'EOMAKE';
+
+GPATH = $(VPATH)
+
+.SUFFIXES: .a .b .c .d
+.PHONY: general rename notarget intermediate
+
+%.a:
+%.b:
+%.c:
+%.d:
+
+%.a : %.b ; cat $^ > $@
+%.b : %.c ; cat $^ > $@
+%.c :: %.d ; cat $^ > $@
+
+# General testing info:
+
+general: foo.b
+foo.b: foo.c bar.c
+
+EOMAKE
+
+close(MAKEFILE);
+
+@touchedfiles = ();
+
+$off = -500;
+
+sub touchfiles {
+ foreach (@_) {
+ ($f = $_) =~ s,VP/,$VP,g;
+ &utouch($off, $f);
+ $off += 10;
+ push(@touchedfiles, $f);
+ }
+}
+
+# Run the general-case test
+
+&touchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d");
+
+&run_make_with_options($makefile,"general",&get_logfile());
+
+push(@touchedfiles, "bar.c");
+
+$answer = "$make_name: Nothing to be done for `general'.\n";
+
+&compare_output($answer,&get_logfile(1));
+
+unlink(@touchedfiles) unless $keep;
+
+1;
diff --git a/tests/scripts/features/vpathplus b/tests/scripts/features/vpathplus
new file mode 100644
index 0000000..a37fbed
--- /dev/null
+++ b/tests/scripts/features/vpathplus
@@ -0,0 +1,128 @@
+# -*-perl-*-
+$description = "Tests the new VPATH+ functionality added in 3.76.";
+
+$details = "";
+
+$VP = "$workdir$pathsep";
+
+open(MAKEFILE,"> $makefile");
+
+# The Contents of the MAKEFILE ...
+
+print MAKEFILE "VPATH = $VP\n";
+
+print MAKEFILE <<'EOMAKE';
+
+SHELL = /bin/sh
+
+.SUFFIXES: .a .b .c .d
+.PHONY: general rename notarget intermediate
+
+%.a:
+%.b:
+%.c:
+%.d:
+
+%.a : %.b
+ cat $^ > $@
+%.b : %.c
+ cat $^ > $@ 2>/dev/null || exit 1
+%.c :: %.d
+ cat $^ > $@
+
+# General testing info:
+
+general: foo.b
+foo.b: foo.c bar.c
+
+# Rename testing info:
+
+rename: $(VPATH)/foo.c foo.d
+
+# Target not made testing info:
+
+notarget: notarget.b
+notarget.c: notarget.d
+ -@echo "not creating $@ from $^"
+
+# Intermediate files:
+
+intermediate: inter.a
+
+EOMAKE
+
+close(MAKEFILE);
+
+@touchedfiles = ();
+
+$off = -500;
+
+sub touchfiles {
+ foreach (@_) {
+ &utouch($off, $_);
+ $off += 10;
+ push(@touchedfiles, $_);
+ }
+}
+
+# Run the general-case test
+
+&touchfiles("$VP/foo.d", "$VP/bar.d", "$VP/foo.c", "$VP/bar.c", "foo.b", "bar.d");
+
+&run_make_with_options($makefile,"general",&get_logfile);
+
+push(@touchedfiles, "bar.c");
+
+$answer = "cat bar.d > bar.c
+cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1
+";
+&compare_output($answer,&get_logfile(1));
+
+# Test rules that don't make the target correctly
+
+&touchfiles("$VP/notarget.c", "notarget.b", "notarget.d");
+
+&run_make_with_options($makefile,"notarget",&get_logfile,512);
+
+$answer = "not creating notarget.c from notarget.d
+cat notarget.c > notarget.b 2>/dev/null || exit 1
+$make_name: *** [notarget.b] Error 1
+";
+
+&compare_output($answer,&get_logfile(1));
+
+# Test intermediate file handling (part 1)
+
+&touchfiles("$VP/inter.d");
+
+&run_make_with_options($makefile,"intermediate",&get_logfile);
+
+push(@touchedfiles, "inter.a", "inter.b");
+
+$answer = "cat ${VP}inter.d > inter.c
+cat inter.c > inter.b 2>/dev/null || exit 1
+cat inter.b > inter.a
+rm inter.b inter.c
+";
+&compare_output($answer,&get_logfile(1));
+
+# Test intermediate file handling (part 2)
+
+&utouch(-20, "inter.a");
+&utouch(-10, "$VP/inter.b");
+&touch("$VP/inter.d");
+
+push(@touchedfiles, "$VP/inter.b", "$VP/inter.d");
+
+&run_make_with_options($makefile,"intermediate",&get_logfile);
+
+$answer = "cat ${VP}inter.d > inter.c
+cat inter.c > inter.b 2>/dev/null || exit 1
+cat inter.b > inter.a
+rm inter.c
+";
+&compare_output($answer,&get_logfile(1));
+
+unlink @touchedfiles unless $keep;
+
+1;