summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.cvsignore3
-rw-r--r--tests/ChangeLog.1 (renamed from tests/ChangeLog)364
-rw-r--r--tests/NEWS5
-rw-r--r--tests/README7
-rw-r--r--tests/config-flags.pm19
-rw-r--r--tests/config-flags.pm.in19
-rwxr-xr-xtests/config_flags_pm.com53
-rw-r--r--tests/guile.supp31
-rwxr-xr-xtests/mkshadow8
-rwxr-xr-xtests/run_make_tests.com272
-rw-r--r--[-rwxr-xr-x]tests/run_make_tests.pl163
-rw-r--r--tests/scripts/features/archives64
-rw-r--r--tests/scripts/features/default_names49
-rw-r--r--tests/scripts/features/double_colon9
-rw-r--r--tests/scripts/features/errors19
-rw-r--r--tests/scripts/features/escape30
-rw-r--r--tests/scripts/features/include12
-rw-r--r--tests/scripts/features/jobserver61
-rw-r--r--tests/scripts/features/load110
-rw-r--r--tests/scripts/features/loadapi116
-rw-r--r--tests/scripts/features/mult_rules2
-rw-r--r--tests/scripts/features/output-sync341
-rw-r--r--tests/scripts/features/parallelism104
-rw-r--r--tests/scripts/features/patspecific_vars10
-rw-r--r--tests/scripts/features/patternrules5
-rw-r--r--tests/scripts/features/recursion16
-rw-r--r--tests/scripts/features/reinvoke17
-rw-r--r--tests/scripts/features/rule_glob37
-rw-r--r--tests/scripts/features/se_explicit17
-rw-r--r--tests/scripts/features/se_implicit34
-rw-r--r--tests/scripts/features/targetvars12
-rw-r--r--tests/scripts/features/utf811
-rw-r--r--tests/scripts/features/varnesting47
-rw-r--r--tests/scripts/features/vpath2
-rw-r--r--tests/scripts/features/vpath365
-rw-r--r--tests/scripts/features/vpathgpath2
-rw-r--r--tests/scripts/features/vpathplus1
-rw-r--r--tests/scripts/functions/call15
-rw-r--r--tests/scripts/functions/file118
-rw-r--r--tests/scripts/functions/filter-out32
-rw-r--r--tests/scripts/functions/foreach6
-rw-r--r--tests/scripts/functions/guile99
-rw-r--r--tests/scripts/functions/sort98
-rw-r--r--tests/scripts/functions/wildcard12
-rw-r--r--tests/scripts/functions/word26
-rw-r--r--tests/scripts/misc/bs-nl83
-rw-r--r--tests/scripts/misc/fopen-fail15
-rw-r--r--tests/scripts/misc/general32
-rw-r--r--tests/scripts/misc/utf814
-rw-r--r--tests/scripts/options/dash-B4
-rw-r--r--tests/scripts/options/dash-C8
-rw-r--r--tests/scripts/options/dash-I4
-rw-r--r--tests/scripts/options/dash-W4
-rw-r--r--tests/scripts/options/dash-k11
-rw-r--r--tests/scripts/options/dash-n80
-rw-r--r--tests/scripts/options/dash-q44
-rw-r--r--tests/scripts/options/eval10
-rw-r--r--tests/scripts/options/print-directory33
-rw-r--r--tests/scripts/options/symlinks10
-rw-r--r--tests/scripts/options/warn-undefined-variables4
-rw-r--r--tests/scripts/targets/DEFAULT4
-rw-r--r--tests/scripts/targets/INTERMEDIATE4
-rw-r--r--tests/scripts/targets/ONESHELL19
-rw-r--r--tests/scripts/targets/POSIX28
-rw-r--r--tests/scripts/targets/SECONDARY11
-rw-r--r--tests/scripts/variables/DEFAULT_GOAL2
-rw-r--r--tests/scripts/variables/GNUMAKEFLAGS42
-rw-r--r--tests/scripts/variables/LIBPATTERNS2
-rw-r--r--tests/scripts/variables/MAKE4
-rw-r--r--tests/scripts/variables/MAKEFLAGS26
-rw-r--r--tests/scripts/variables/MAKE_RESTARTS4
-rw-r--r--tests/scripts/variables/SHELL19
-rw-r--r--tests/scripts/variables/define56
-rw-r--r--tests/scripts/variables/flavors20
-rw-r--r--tests/scripts/variables/private44
-rw-r--r--tests/scripts/variables/special26
-rw-r--r--tests/test_driver.pl609
77 files changed, 3144 insertions, 645 deletions
diff --git a/tests/.cvsignore b/tests/.cvsignore
deleted file mode 100644
index 2fe91872..00000000
--- a/tests/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-work
-.*gdbinit
-.gdb_history
diff --git a/tests/ChangeLog b/tests/ChangeLog.1
index d036568e..9abe731c 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog.1
@@ -1,3 +1,354 @@
+2013-10-09 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/patspecific_vars: Typo fixes.
+
+2013-10-05 Paul Smith <psmith@gnu.org>
+
+ * test_driver.pl (run_all_tests): Rewrite to be more clear.
+ * scripts/features/jobserver: Avoid using $ENV{HOME} as it doesn't
+ exist everywhere.
+ * scripts/features/default_names: End with 1;
+
+ * scripts/features/loadapi: Use new calling signatures. Verify
+ the NOEXPAND flag works. Test with all valid function name
+ characters.
+
+2013-09-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/variables/SHELL: Solaris /bin/sh can't handle options in
+ multiple words; skip that test.
+ * scripts/targets/ONESHELL: Ditto.
+
+ * scripts/variables/GNUMAKEFLAGS: Verify that GNUMAKEFLAGS is
+ cleared and options are not duplicated.
+
+2013-09-23 Paul Smith <psmith@gnu.org>
+
+ * scripts/options/print-directory: Rename dash-w to
+ print-directory to avoid conflicts with dash-W on case-insensitive
+ filesystems.
+
+2013-09-22 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/se_implicit: Verify that order-only tokens
+ inside second expansion are parsed correctly.
+ Test for Savannah bug #31155.
+
+ * run_make_tests.pl (set_more_defaults): If we can't find
+ gnumake.h based on the make program we might be running from a
+ remote build directory. Parse the Makefile for the right path.
+
+ Fix some test issues on Solaris.
+
+ * scripts/features/archives: Determine what output ar gives when
+ adding and replacing objects and compare with that.
+ * scripts/features/escape: Solaris /bin/sh doesn't properly handle
+ backslashes inside single quotes, so don't rely on it.
+ * scripts/features/output-sync: false(1) gives different exit
+ codes on different systems; use "exit 1" instead.
+ * scripts/features/parallelism: Increase the timeout for slower systems.
+
+2013-09-21 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: Some versions of ar (MacOSX) generate
+ different output when creating archives. Run it and verify the
+ real output.
+ * scripts/features/default_names: MacOSX is, like Windows,
+ case-preserving / case-insensitive. Redo the test to avoid
+ checking for "UNIX".
+ * test_driver.pl (attach_default_output): Don't dup stdout into
+ stderr. Reported by Denis Excoffier <bug-tar@Denis-Excoffier.org>
+
+ * scripts/features/se_explicit: Fix a test that behaves
+ differently with/without archive capability enabled.
+ * scripts/features/output-sync: Don't test output-sync if it's not
+ enabled. We also skip it if parallelism is not enabled, although
+ strictly speaking some of the output-sync tests are valid even
+ without parallelism.
+ * scripts/features/jobserver: Move some tests that require the
+ jobserver from features/parallelism to a separate suite. Only run
+ this if jobserver mode is enabled.
+
+ * scripts/features/output-sync: Test shell functions writing to
+ stderr in recipes: ensure it's captured via output-sync. Test
+ output generated while reading makefiles and make sure it's
+ captured via output-sync. Make sure that fatal errors dump the
+ output so it's not lost.
+
+ * scripts/options/dash-w: Add a test for -w flag.
+
+2013-09-15 Paul Smith <psmith@gnu.org>
+
+ * scripts/misc/fopen-fail: Check for failure on infinite recursion.
+ * run_make_tests.pl (run_make_test): Allow the answer string to be
+ undef, which means that we shouldn't compare it at all. Only the
+ exit code matters in this case.
+ * test_driver.pl (compare_output): Ditto.
+ Test for Savannah bug #27374.
+
+ * scripts/features/parallelism: Test broken jobserver on recursion.
+ Test for Savannah bug #39934.
+
+ * scripts/options/eval: Verify --eval during restart.
+ Test for Savannah bug #39203.
+
+2013-09-14 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync: Verify -Orecurse properly.
+
+2013-09-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync: Modify for output sync behavior.
+ * scripts/variables/MAKE_RESTARTS: Ditto.
+ * scripts/variables/MAKEFLAGS: Remove mode for --trace.
+ * scripts/variables/GNUMAKEFLAGS: Ditto.
+
+2013-07-22 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/rule_glob: Add tests for wildcards in rules.
+ Test for Savannah bug #39310.
+
+2013-07-09 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/se_implicit: Add a test for SE rules depending
+ on other SE rules to be built.
+
+2013-05-26 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: Test for Savannah bug #38442.
+
+ * scripts/misc/bs-nl: Test for Savannah bug #39035.
+ Add a test for Savannah bug #38945.
+
+2013-05-22 Paul Smith <psmith@gnu.org>
+
+ * scripts/options/dash-n: Fix results after MAKEFLAGS fixes.
+ * scripts/variables/MAKEFLAGS: Ditto.
+ * scripts/variables/GNUMAKEFLAGS: Ditto.
+
+2013-05-14 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/loadapi: Add plugin_is_GPL_compatible symbol.
+ * scripts/features/load: Ditto.
+
+2013-05-13 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync (output_sync_set): Update for new
+ --trace behavior.
+
+2013-05-05 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync (output_sync_set): Remove
+ extraneous enter/leave lines, which are no longer printed.
+ Add tests for syncing command line printing.
+ (output_sync_set): Rename options: "job"->"line"; "make"->"recurse"
+
+2013-05-04 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/loadapi: Use the new alloc functions.
+
+ * scripts/features/output-sync (output_sync_set): New test for
+ ordered recursive output for -Ojob / -Otarget.
+
+2013-05-03 Eli Zaretskii <eliz@gnu.org>
+
+ * scripts/features/load: Fix signatures of testload_gmk_setup and
+ explicit_setup, to bring them in line with the documentation.
+
+2013-04-28 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync (output_sync_set): Add tests for
+ the per-job syntax mode.
+ (output_sync_set): Test improved error message location.
+
+2013-04-15 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync (output_sync_set): New arg syntax.
+
+2013-04-14 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync: Rewrite to be more reliable.
+
+ * test_driver.pl (_run_command): Don't set SIGALRM until after we
+ start the child. Print errors to the top-level output, which will
+ be stderr.
+ (attach_default_output): Use a list of file handles as the stack.
+ (detach_default_output): Ditto.
+
+ * scripts/features/output-sync: Add a test for output-sync.
+
+2013-02-25 Paul Smith <psmith@gnu.org>
+
+ * run_make_tests.pl (valid_option): Support the -srcdir flag.
+ (set_more_defaults): Set up $srcdir if it's not set yet.
+
+ * scripts/functions/guile: Verify gmk-eval doesn't expand twice.
+ * scripts/features/load: Rework to test just the load capability.
+ * scripts/features/loadapi: New set of tests for the load API.
+
+2013-01-19 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/load: Test loaded files with and without "./"
+ prefix. Add tests for automatically rebuilding loaded files if
+ they are out of date or non-existent.
+
+2013-01-13 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: Add a check targets that have parens,
+ but are not archives. See Savannah bug #37878.
+
+ * scripts/options/dash-n: Verify -n is preserved after recursive /
+ re-exec. See Savannah bug #38051.
+
+2013-01-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/parallelism: Change rule so it doesn't depend
+ on invocation order, etc.
+
+2012-10-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/load: New test suite for the "load" directive.
+
+2012-09-09 Paul Smith <psmith@gnu.org>
+
+ * scripts/functions/file: Get errors in the C locale, not the
+ current locale. Fixes Savannah bug #35764.
+
+ * scripts/features/escape: Check that backslashes before
+ non-special characters are not removed.
+
+ * scripts/features/utf8: New test for UTF-8 support.
+ See Savannah bug #36529.
+
+ * scripts/targets/POSIX: Add tests for default macro values as
+ specified by IEEE Std 1003.1-2008. See Savannah bug #37069.
+
+2012-03-04 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/se_explicit: Test $(x:%=%) format in secondary
+ expansion prerequisite lists. See Savannah bug #16545.
+
+ * scripts/features/escape: Test escaped ":" in prerequisite lists.
+ See Savannah bug #12126.
+
+ * scripts/variables/private: Test appending private variables in
+ pattern-specific target rules. See Savannah bug #35468.
+
+2012-03-03 Paul Smith <psmith@gnu.org>
+
+ * scripts/variables/SHELL: Ensure .SHELLFLAGS works with options
+ separated by whitespace.
+
+ * scripts/targets/ONESHELL: Try .ONESHELL in combination with
+ whitespace-separated options in .SHELLFLAGS. See Savannah bug #35397.
+
+ * scripts/functions/filter-out: Add filter tests and test escape
+ operations. See Savannah bug #35410.
+
+ * guile.supp: Suppress valgrind errors from Guile
+ * run_make_tests.pl: Use the Guile suppression file.
+
+ * scripts/misc/bs-nl: Check for POSIX and non-POSIX
+ backslash/newline handling. Addresses Savannah bug #16670.
+
+2012-01-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/variables/flavors: Add tests for ::=
+ * scripts/variables/define: Ditto
+
+ * scripts/functions/file: Test the new $(file ...) function.
+
+2012-01-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/functions/guile: New regression tests for Guile support.
+
+2011-12-10 Paul Smith <psmith@gnu.org>
+
+ * scripts/targets/SECONDARY: Add prereq statements to ensure rules
+ are printed in the right order for test #9
+
+2011-11-14 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/double_colon: Check double-colon with escaped
+ filenames. See Savannah bug #33399.
+
+2011-09-18 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/parallelism: On re-exec make sure we preserve
+ the value of MAKEFLAGS when necessary. See Savannah bug #33873.
+
+ * scripts/features/vpath3: Verify handling of -lfoo libraries
+ found via vpath vs. the standard directory search.
+ See Savannah bug #32511.
+
+2011-09-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/functions/call: Verify that using export in a $(call ...)
+ context creates a global variable. See Savannah bug #32498.
+
+2011-09-02 Paul Smith <psmith@gnu.org>
+
+ * scripts/options/dash-n: Verify that in "-n -t", the -n takes
+ priority. Patch from Michael Witten <mfwitten@gmail.com>.
+
+2011-08-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/varnesting: Test resetting of variables while
+ expanding them. See Savannah patch #7534
+
+2011-06-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: Check archives with whitespace at the
+ beginning, end, and extra in the middle.
+ Another test for Savannah bug #30612.
+
+2011-05-07 Paul Smith <psmith@gnu.org>
+
+ * scripts/variables/private: Ensure we skip private variables when
+ appending. Test for Savannah bug #32872.
+
+ * scripts/functions/wildcard: Verify wildcard used to test for
+ file existence/non-existence.
+
+2011-05-02 Paul Smith <psmith@gnu.org>
+
+ * scripts/functions/sort: Add a test for Savannah bug #33125.
+
+2011-04-17 David A. Wheeler <dwheeler@dwheeler.com>
+
+ * scripts/features/shell_assignment: Regression for "!=" feature
+
+2010-11-06 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/targetvars: Fix known-good output for BS/NL changes.
+ * scripts/functions/call: Ditto.
+ * scripts/variables/special: Ditto.
+
+ * scripts/misc/bs-nl: New test suite for backslash/newline testing.
+
+2010-08-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/errors: Add new error message to output text.
+ * scripts/variables/SHELL: Ditto.
+ * scripts/targets/POSIX: Ditto.
+ * scripts/options/dash-k: Ditto.
+ * scripts/features/vpathplus: Ditto.
+ * scripts/features/patternrules: Ditto.
+ * scripts/features/parallelism: Ditto.
+
+2010-08-13 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: New regression tests for archive
+ support. Test for fix to Savannah bug #30612.
+
+ * run_make_tests.pl (set_more_defaults): Set a %FEATURES hash to
+ the features available in $(.FEATURES).
+
+2010-08-10 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/reinvoke: Ensure command line variable settings
+ are preserved across make re-exec. Tests Savannah bug #30723.
+
2010-07-28 Paul Smith <psmith@gnu.org>
* scripts/targets/POSIX: Compatibility issues with Solaris (and
@@ -299,7 +650,7 @@
* test_driver.pl (toplevel): Skip all hidden files/directories (ones
beginning with ".").
- * scripts/functions/andor: Tests for $(and ..) and $(or ...)
+ * scripts/functions/andor: Tests for $(and ...) and $(or ...)
functions.
2006-02-08 Boris Kolpackov <boris@kolpackov.net>
@@ -386,9 +737,9 @@
2005-08-13 Boris Kolpackov <boris@kolpackov.net>
- * scripts/functions/wildcard: Wrap calls to $(wildcard ) with
+ * scripts/functions/wildcard: Wrap calls to $(wildcard) with
$(sort) so that the resulting order is no longer filesystem-
- dependant.
+ dependent.
2005-08-10 Boris Kolpackov <boris@kolpackov.net>
@@ -459,7 +810,7 @@
2005-06-09 Paul D. Smith <psmith@gnu.org>
- * scripts/functions/foreach: Add a test for Savannah bug #11913.
+ * scripts/functions/foreach: Add a test for Savannah bug #11913.
2005-05-31 Boris Kolpackov <boris@kolpackov.net>
@@ -479,7 +830,7 @@
2005-05-02 Paul D. Smith <psmith@gnu.org>
* scripts/features/parallelism: Add a test for exporting recursive
- variables containing $(shell ) calls. Rewrite this script to use
+ variables containing $(shell) calls. Rewrite this script to use
run_make_test() everywhere.
2005-04-07 Paul D. Smith <psmith@gnu.org>
@@ -1062,8 +1413,7 @@
ChangeLog file for the test suite created.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright (C) 1992-2014 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
diff --git a/tests/NEWS b/tests/NEWS
index 43971ec3..584f4a4f 100644
--- a/tests/NEWS
+++ b/tests/NEWS
@@ -72,7 +72,7 @@ Changes from 0.4.4 to 0.4.5 (April 29, 1995):
Also, some tests and stuff still haven't made it in because I
haven't had time to write the test scripts for them. But they,
- too, will get in eventually. Contributions of scripts (ie, tests
+ too, will get in eventually. Contributions of scripts (i.e., tests
that I can just drop in) are particularly welcome and will be
incorporated immediately.
@@ -162,8 +162,7 @@ Changes from 0.1 to 0.2 (5-4-92):
-------------------------------------------------------------------------------
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright (C) 1992-2014 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
diff --git a/tests/README b/tests/README
index 3860bdbb..3b699eec 100644
--- a/tests/README
+++ b/tests/README
@@ -7,8 +7,7 @@ This entire test suite, including all test files, are copyright and
distributed under the following terms:
-----------------------------------------------------------------------------
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1992-2014 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -39,7 +38,7 @@ To run the test suite on Windows NT or DOS systems, use
"perl.exe ./run_make-tests.pl".
By default, the test engine picks up the first executable called "make"
-that it finds in your path. You may use the -make_path option (ie,
+that it finds in your path. You may use the -make_path option (i.e.,
"perl run_make_tests -make_path /usr/local/src/make-3.78/make") if
you want to run a particular copy. This now works correctly with
relative paths and when make is called something other than "make" (like
@@ -59,7 +58,7 @@ The options/dash-l test will not really test anything if the copy of
make you are using can't obtain the system load. Some systems require
make to be setgid sys or kmem for this; if you don't want to install
make just to test it, make it setgid to kmem or whatever group /dev/kmem
-is (ie, "chgrp kmem make;chmod g+s make" as root). In any case, the
+is (i.e., "chgrp kmem make;chmod g+s make" as root). In any case, the
options/dash-l test should no longer *fail* because make can't read
/dev/kmem.
diff --git a/tests/config-flags.pm b/tests/config-flags.pm
new file mode 100644
index 00000000..903c468a
--- /dev/null
+++ b/tests/config-flags.pm
@@ -0,0 +1,19 @@
+# This is a -*-perl-*- script
+#
+# Set variables that were defined by configure, in case we need them
+# during the tests.
+
+%CONFIG_FLAGS = (
+ AM_LDFLAGS => '-Wl,--export-dynamic',
+ AR => 'ar',
+ CC => 'gcc',
+ CFLAGS => '-g -O2',
+ CPP => 'gcc -E',
+ CPPFLAGS => '',
+ GUILE_CFLAGS => '-pthread -I/usr/include/guile/2.0 ',
+ GUILE_LIBS => '-lguile-2.0 -lgc ',
+ LDFLAGS => '',
+ LIBS => '-ldl '
+);
+
+1;
diff --git a/tests/config-flags.pm.in b/tests/config-flags.pm.in
new file mode 100644
index 00000000..29ba1469
--- /dev/null
+++ b/tests/config-flags.pm.in
@@ -0,0 +1,19 @@
+# This is a -*-perl-*- script
+#
+# Set variables that were defined by configure, in case we need them
+# during the tests.
+
+%CONFIG_FLAGS = (
+ AM_LDFLAGS => '@AM_LDFLAGS@',
+ AR => '@AR@',
+ CC => '@CC@',
+ CFLAGS => '@CFLAGS@',
+ CPP => '@CPP@',
+ CPPFLAGS => '@CPPFLAGS@',
+ GUILE_CFLAGS => '@GUILE_CFLAGS@',
+ GUILE_LIBS => '@GUILE_LIBS@',
+ LDFLAGS => '@LDFLAGS@',
+ LIBS => '@LIBS@'
+);
+
+1;
diff --git a/tests/config_flags_pm.com b/tests/config_flags_pm.com
new file mode 100755
index 00000000..3f5adffe
--- /dev/null
+++ b/tests/config_flags_pm.com
@@ -0,0 +1,53 @@
+$!
+$! config_flags_pm.com - Build config-flags.pm on VMS.
+$!
+$! Just good enough to run the self tests for now.
+$!
+$! Copyright (C) 2014 Free Software Foundation, Inc.
+$! This file is part of GNU Make.
+$!
+$! GNU Make is free software; you can redistribute it and/or modify it under
+$! the terms of the GNU General Public License as published by the Free Software
+$! Foundation; either version 3 of the License, or (at your option) any later
+$! version.
+$!
+$! GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
+$! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+$! FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+$! details.
+$!
+$! You should have received a copy of the GNU General Public License along with
+$! this program. If not, see <http://www.gnu.org/licenses/>.
+$!
+$!
+$ open/read cfpm_in config-flags.pm.in
+$!
+$ outfile = "sys$disk:[]config-flags.pm"
+$!
+$ cflags = "/include=([],[.glob]"
+$!
+$ create 'outfile'
+$ open/append cfpm 'outfile'
+$!
+$cfpm_read_loop:
+$ read cfpm_in/end=cfpm_read_loop_end line_in
+$ line_in_len = f$length(line_in)
+$ if f$locate("@", line_in) .lt. line_in_len
+$ then
+$ part1 = f$element(0, "@", line_in)
+$ key = f$element(1, "@", line_in)
+$ part2 = f$element(2, "@", line_in)
+$ value = ""
+$ if key .eqs. "CC" then value = "CC"
+$ if key .eqs. "CPP" then value = "CPP"
+$ if key .eqs. "CFLAGS" then value = cflags
+$ if key .eqs. "GUILE_CFLAGS" then value = cflags
+$ write cfpm part1, value, part2
+$ goto cfpm_read_loop
+$ endif
+$ write cfpm line_in
+$ goto cfpm_read_loop
+$cfpm_read_loop_end:
+$ close cfpm_in
+$ close cfpm
+$!
diff --git a/tests/guile.supp b/tests/guile.supp
new file mode 100644
index 00000000..9e9b01ba
--- /dev/null
+++ b/tests/guile.supp
@@ -0,0 +1,31 @@
+# Guile valgrind suppression file
+# Created with Guile 1.8.7
+
+# --- Garbage collection
+{
+ guilegc
+ Memcheck:Cond
+ ...
+ fun:scm_gc_for_newcell
+}
+{
+ guilegc
+ Memcheck:Value4
+ ...
+ fun:scm_gc_for_newcell
+}
+{
+ guilegc
+ Memcheck:Value8
+ ...
+ fun:scm_gc_for_newcell
+}
+
+
+# -- scm_alloc_struct
+{
+ guileheap
+ Memcheck:Leak
+ ...
+ fun:scm_alloc_struct
+}
diff --git a/tests/mkshadow b/tests/mkshadow
index d41b40e1..aa9b3bcd 100755
--- a/tests/mkshadow
+++ b/tests/mkshadow
@@ -3,9 +3,7 @@
# Simple script to make a "shadow" test directory, using symbolic links.
# Typically you'd put the shadow in /tmp or another local disk
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-2014 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -28,7 +26,7 @@ esac
dest="$1"
if [ ! -d "$dest" ]; then
- echo "Destination directory \`$dest' must exist!"
+ echo "Destination directory '$dest' must exist!"
exit 1
fi
@@ -55,5 +53,5 @@ done
rm -rf work
-echo "Shadow test suite created in \`$dest/$name'."
+echo "Shadow test suite created in '$dest/$name'."
exit 0
diff --git a/tests/run_make_tests.com b/tests/run_make_tests.com
new file mode 100755
index 00000000..2f17f7f5
--- /dev/null
+++ b/tests/run_make_tests.com
@@ -0,0 +1,272 @@
+$! Test_make.com
+$!
+$! This is a wrapper for the GNU make perl test programs on VMS.
+$!
+$! Parameter "-help" for description on how to use described below.
+$!
+$! Copyright (C) 2014 Free Software Foundation, Inc.
+$! This file is part of GNU Make.
+$!
+$! GNU Make is free software; you can redistribute it and/or modify it under
+$! the terms of the GNU General Public License as published by the Free Software
+$! Foundation; either version 3 of the License, or (at your option) any later
+$! version.
+$!
+$! GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
+$! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+$! FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+$! details.
+$!
+$! You should have received a copy of the GNU General Public License along with
+$! this program. If not, see <http://www.gnu.org/licenses/>.
+$!
+$!
+$! Allow more than 8 paramters with using commas as a delimiter.
+$!
+$ params = "''p1',''p2',''p3',''p4',''p5',''p6',''p7',''p8'"
+$!
+$ test_flags = ",verbose,detail,keep,usage,help,debug,"
+$ test_flags_len = f$length(test_flags)
+$ verbose_flag = ""
+$ detail_flag = ""
+$ keep_flag = ""
+$ usage_flag = ""
+$ help_flag = ""
+$ debug_flag = ""
+$!
+$ ignored_options = "profile,make,srcdir,valgrind,memcheck,massif,"
+$ ignored_option_len = f$length(ignored_options)
+$!
+$ testname = ""
+$ make :== $bin:make.exe"
+$!
+$ i = 0
+$param_loop:
+$ param = f$element(i, ",", params)
+$ i = i + 1
+$ if param .eqs. "" then goto param_loop
+$ if param .eqs. "," then goto param_loop_end
+$ param_len = f$length(param)
+$ if f$locate("/", param) .lt. param_len
+$ then
+$ if testname .nes. ""
+$ then
+$ write sys$output "Only the last test name specified will be run!"
+$ endif
+$ testname = param
+$ goto param_loop
+$ endif
+$ lc_param = f$edit(param,"LOWERCASE") - "-"
+$ if f$locate(",''lc_param',", ignored_options) .lt. ignored_option_len
+$ then
+$ write sys$output "parameter ''param' is ignored on VMS for now."
+$ goto param_loop
+$ endif
+$ if f$locate(",''lc_param',", test_flags) .lt. test_flags_len
+$ then
+$ 'lc_param'_flag = "-" + lc_param
+$ goto param_loop
+$ endif
+$ write sys$output "parameter ''param' is not known to VMS."
+$ goto param_loop
+$!
+$param_loop_end:
+$!
+$no_gnv = 1
+$no_perl = 1
+$!
+$! Find GNV 2.1.3 + manditory updates
+$! If properly updated, the GNV$GNU logical name is present.
+$! Updated GNV utilities have a gnv$ prefix on them.
+$ gnv_root = f$trnlnm("GNV$GNU", "LNM$SYSTEM_TABLE")
+$ if gnv_root .nes. ""
+$ then
+$ no_gnv = 0
+$ ! Check for update ar utility.
+$ new_ar = "gnv$gnu:[usr.bin]gnv$ar.exe"
+$ if f$search(new_ar) .nes. ""
+$ then
+$ ! See if a new port of ar exists.
+$ ar :== $'new_ar'
+$ else
+$ ! Fall back to legacy GNV AR wrapper.
+$ old_ar = "gnv$gnu:[bin]ar.exe"
+$ if f$search(old_ar) .nes. ""
+$ then
+$ ar :== $'old_ar'
+$ else
+$ no_gnv = 1
+$ endif
+$ endif
+$ ! Check for updated bash
+$ if no_gnv .eq. 0
+$ then
+$ new_bash = "gnv$gnu:[bin]gnv$bash.exe"
+$ if f$search(new_bash) .nes. ""
+$ then
+$ bash :== $'new_bash'
+$ sh :== $'new_bash'
+$ else
+$ no_gnv = 1
+$ endif
+$ endif
+$ ! Check for updated coreutils
+$ if no_gnv .eq. 0
+$ then
+$ new_cat = "gnv$gnu:[bin]gnv$cat.exe"
+$ if f$search(new_cat) .nes. ""
+$ then
+$ cat :== $'new_cat'
+$ cp :== $gnv$gnu:[bin]gnv$cp.exe
+$ echo :== $gnv$gnu:[bin]gnv$echo.exe
+$ false :== $gnv$gnu:[bin]gnv$false.exe
+$ true :== $gnv$gnu:[bin]gnv$true.exe
+$ touch :== $gnv$gnu:[bin]gnv$touch.exe
+$ mkdir :== $gnv$gnu:[bin]gnv$mkdir.exe
+$ rm :== $gnv$gnu:[bin]gnv$rm.exe
+$ sleep :== $gnv$gnu:[bin]gnv$sleep.exe
+$ else
+$ no_gnv = 1
+$ endif
+$ endif
+$ ! Check for updated diff utility.
+$ if no_gnv .eq. 0
+$ then
+$ new_diff = "gnv$gnu:[usr.bin]gnv$diff.exe"
+$ if f$search(new_diff) .nes. ""
+$ then
+$ ! See if a new port of diff exists.
+$ diff :== $'new_diff'
+$ else
+$ ! Fall back to legacy GNV diff
+$ old_diff = "gnv$gnu:[bin]diff.exe"
+$ if f$search(old_diff) .nes. ""
+$ then
+$ diff :== $'old_diff'
+$ else
+$ no_gnv = 1
+$ endif
+$ endif
+$ endif
+$ endif
+$!
+$if no_gnv
+$then
+$ write sys$output "Could not find an up to date GNV installed!"
+$ help_flag = 1
+$endif
+$!
+$! Find perl 5.18.1 or later.
+$!
+$! look in perl_root:[000000]perl_setup.com
+$ perl_root = f$trnlnm("perl_root")
+$ ! This works with known perl installed from PCSI kits.
+$ if perl_root .nes. ""
+$ then
+$ perl_ver = f$element(1, ".", perl_root)
+$ if f$locate("-", perl_ver) .lt. f$length(perl_ver)
+$ then
+$ no_perl = 0
+$ endif
+$ endif
+$ if no_perl
+$ then
+$! look for sys$common:[perl-*]perl_setup.com
+$ perl_setup = f$search("sys$common:[perl-*]perl_setup.com")
+$ if perl_setup .eqs. ""
+$ then
+$ if gnv_root .nes. ""
+$ then
+$ gnv_device = f$parse(gnv_root,,,"DEVICE")
+$ perl_templ = "[vms$common.perl-*]perl_setup.com"
+$ perl_search = f$parse(perl_templ, gnv_device)
+$ perl_setup = f$search(perl_search)
+$ endif
+$ endif
+$ if perl_setup .nes. ""
+$ then
+$ @'perl_setup'
+$ no_perl = 0
+$ endif
+$ endif
+$!
+$ if no_perl
+$ then
+$ write sys$output "Could not find an up to date Perl installed!"
+$ help_flag = "-help"
+$ endif
+$!
+$!
+$ if help_flag .nes. ""
+$ then
+$ type sys$input
+$DECK
+This is a test script wrapper for the run_make_tests.pl script.
+
+This wrapper makes sure that the DCL symbols and logical names needed to
+run the perl script are in place.
+
+The test wrapper currently requires that the DCL symbols be global symbols.
+Those symbols will be left behind after the procedure is run.
+
+The PERL_ROOT will be set to a compatible perl if such a perl is found and
+is not the default PERL_ROOT:. This setting will persist after the test.
+
+This wrapper should be run with the default set to the base directory
+of the make source.
+
+The HELP parameter will bring up this text and then run the help script
+for the Perl wrapper. Not all options for the perl script have been
+implemented, such as valgrind or specifying the make path or source path.
+
+Running the wrapper script requires:
+ Perl 5.18 or later.
+ PCSI kits available from http://sourceforge.net/projects/vmsperlkit/files/
+
+ GNV 2.1.3 or later. GNV 3.0.1 has not tested with this script.
+ Bash 4.2.47 or later.
+ Coreutils 8.21 or later.
+ http://sourceforge.net/projects/gnv/files/
+ Read before installing:
+ http://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/
+ As updates for other GNV components get posted, those updates should
+ be used.
+
+$EOD
+$ endif
+$!
+$ if no_gnv .or. no_perl then exit 44
+$!
+$!
+$ make := $bin:make.exe
+$ default = f$environment("DEFAULT")
+$ this = f$environment("PROCEDURE")
+$ on error then goto all_error
+$ set default 'f$parse(this,,,"DEVICE")''f$parse(this,,,"DIRECTORY")'
+$!
+$! Need to make sure that the config-flags.pm exists.
+$ if f$search("config-flags.pm") .eqs. ""
+$ then
+$ @config_flags_pm.com
+$ endif
+$ define/user bin 'default',gnv$gnu:[bin]
+$ define/user decc$filename_unix_noversion enable
+$ define/user decc$filename_unix_report enable
+$ define/user decc$readdir_dropdotnotype enable
+$ flags = ""
+$ if verbose_flag .nes. "" then flags = verbose_flag
+$ if detail_flag .nes. "" then flags = flags + " " + detail_flag
+$ if keep_flag .nes. "" then flags = flags + " " + keep_flag
+$ if usage_flag .nes. "" then flags = flags + " " + usage_flag
+$ if help_flag .nes. "" then flags = flags + " " + help_flag
+$ if debug_flag .nes. "" then flags = flags + " " + debug_flag
+$ flags = f$edit(flags, "TRIM, COMPRESS")
+$ if testname .nes. ""
+$ then
+$ perl run_make_tests.pl "''testname'" 'flags'
+$ else
+$ perl run_make_tests.pl 'flags'
+$ endif
+$all_error:
+$ set default 'default'
+$!
diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl
index 2c8c08b9..9468faba 100755..100644
--- a/tests/run_make_tests.pl
+++ b/tests/run_make_tests.pl
@@ -11,9 +11,7 @@
# [-make <make prog>]
# (and others)
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-2014 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -29,18 +27,39 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
+%FEATURES = ();
$valgrind = 0; # invoke make with valgrind
$valgrind_args = '';
-$memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full';
+$memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full --suppressions=guile.supp';
$massif_args = '--num-callers=15 --tool=massif --alloc-fn=xmalloc --alloc-fn=xcalloc --alloc-fn=xrealloc --alloc-fn=xstrdup --alloc-fn=xstrndup';
$pure_log = undef;
+# The location of the GNU make source directory
+$srcdir = '';
+
$command_string = '';
$all_tests = 0;
+# rmdir broken in some Perls on VMS.
+if ($^O eq 'VMS')
+{
+ require VMS::Filespec;
+ VMS::Filespec->import();
+
+ sub vms_rmdir {
+ my $vms_file = vmspath($_[0]);
+ $vms_file = fileify($vms_file);
+ my $ret = unlink(vmsify($vms_file));
+ return $ret
+ };
+
+ *CORE::GLOBAL::rmdir = \&vms_rmdir;
+}
+
require "test_driver.pl";
+require "config-flags.pm";
# Some target systems might not have the POSIX module...
$has_POSIX = eval { require "POSIX.pm" };
@@ -60,6 +79,15 @@ sub valid_option
return 1;
}
+ if ($option =~ /^-srcdir$/i) {
+ $srcdir = shift @argv;
+ if (! -f "$srcdir/gnumake.h") {
+ print "$option $srcdir: Not a valid GNU make source directory.\n";
+ exit 0;
+ }
+ return 1;
+ }
+
if ($option =~ /^-all([-_]?tests)?$/i) {
$all_tests = 1;
return 1;
@@ -98,6 +126,17 @@ sub valid_option
$old_makefile = undef;
+sub subst_make_string
+{
+ local $_ = shift;
+ $makefile and s/#MAKEFILE#/$makefile/g;
+ s/#MAKEPATH#/$mkpath/g;
+ s/#MAKE#/$make_name/g;
+ s/#PERL#/$perl_name/g;
+ s/#PWD#/$pwd/g;
+ return $_;
+}
+
sub run_make_test
{
local ($makestring, $options, $answer, $err_code, $timeout) = @_;
@@ -115,16 +154,9 @@ sub run_make_test
$makefile = &get_tmpfile();
}
- # Make sure it ends in a newline.
+ # Make sure it ends in a newline and substitute any special tokens.
$makestring && $makestring !~ /\n$/s and $makestring .= "\n";
-
- # Replace @MAKEFILE@ with the makefile name and @MAKE@ with the path to
- # make
- $makestring =~ s/#MAKEFILE#/$makefile/g;
- $makestring =~ s/#MAKEPATH#/$mkpath/g;
- $makestring =~ s/#MAKE#/$make_name/g;
- $makestring =~ s/#PERL#/$perl_name/g;
- $makestring =~ s/#PWD#/$pwd/g;
+ $makestring = subst_make_string($makestring);
# Populate the makefile!
open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
@@ -133,13 +165,10 @@ sub run_make_test
}
# Do the same processing on $answer as we did on $makestring.
-
- $answer && $answer !~ /\n$/s and $answer .= "\n";
- $answer =~ s/#MAKEFILE#/$makefile/g;
- $answer =~ s/#MAKEPATH#/$mkpath/g;
- $answer =~ s/#MAKE#/$make_name/g;
- $answer =~ s/#PERL#/$perl_name/g;
- $answer =~ s/#PWD#/$pwd/g;
+ if (defined $answer) {
+ $answer && $answer !~ /\n$/s and $answer .= "\n";
+ $answer = subst_make_string($answer);
+ }
run_make_with_options($makefile, $options, &get_logfile(0),
$err_code, $timeout);
@@ -165,6 +194,40 @@ sub run_make_with_options {
}
if ($options) {
+ if ($^O eq 'VMS') {
+ # Try to make sure arguments are properly quoted.
+ # This does not handle all cases.
+
+ # VMS uses double quotes instead of single quotes.
+ $options =~ s/\'/\"/g;
+
+ # If the leading quote is inside non-whitespace, then the
+ # quote must be doubled, because it will be enclosed in another
+ # set of quotes.
+ $options =~ s/(\S)(\".*\")/$1\"$2\"/g;
+
+ # Options must be quoted to preserve case if not already quoted.
+ $options =~ s/(\S+)/\"$1\"/g;
+
+ # Special fixup for embedded quotes.
+ $options =~ s/(\"\".+)\"(\s+)\"(.+\"\")/$1$2$3/g;
+
+ $options =~ s/(\A)(?:\"\")(.+)(?:\"\")/$1\"$2\"/g;
+
+ # Special fixup for misc/general4 test.
+ $options =~ s/""\@echo" "cc""/\@echo cc"/;
+ $options =~ s/"\@echo link"""/\@echo link"/;
+
+ # Remove shell escapes expected to be removed by bash
+ if ($options !~ /path=pre/) {
+ $options =~ s/\\//g;
+ }
+
+ # special fixup for options/eval
+ $options =~ s/"--eval=\$\(info" "eval/"--eval=\$\(info eval/;
+
+ print ("Options fixup = -$options-\n") if $debug;
+ }
$command .= " $options";
}
@@ -183,7 +246,6 @@ sub run_make_with_options {
$valgrind and $test_timeout = 0;
$code = &run_command_with_output($logname,$command);
-
$test_timeout = $old_timeout;
}
@@ -228,14 +290,16 @@ sub run_make_with_options {
sub print_usage
{
&print_standard_usage ("run_make_tests",
- "[-make_path make_pathname] [-memcheck] [-massif]",);
+ "[-make MAKE_PATHNAME] [-srcdir SRCDIR] [-memcheck] [-massif]",);
}
sub print_help
{
&print_standard_help (
- "-make_path",
+ "-make",
"\tYou may specify the pathname of the copy of make to run.",
+ "-srcdir",
+ "\tSpecify the make source directory.",
"-valgrind",
"-memcheck",
"\tRun the test suite under valgrind's memcheck tool.",
@@ -312,29 +376,34 @@ sub set_more_defaults
# Find the full pathname of Make. For DOS systems this is more
# complicated, so we ask make itself.
- my $mk = `sh -c 'echo "all:;\@echo \\\$(MAKE)" | $make_path -f-'`;
- chop $mk;
- $mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE):\n
+ if ($osname eq 'VMS') {
+ # On VMS pre-setup make to be found with simply 'make'.
+ $make_path = 'make';
+ } else {
+ my $mk = `sh -c 'echo "all:;\@echo \\\$(MAKE)" | $make_path -f-'`;
+ chop $mk;
+ $mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE):\n
'echo \"all:;\@echo \\\$(MAKE)\" | $make_path -f-' failed!\n";
- $make_path = $mk;
- print "Make\t= `$make_path'\n" if $debug;
+ $make_path = $mk;
+ }
+ print "Make\t= '$make_path'\n" if $debug;
- $string = `$make_path -v -f /dev/null 2> /dev/null`;
+ my $redir2 = '2> /dev/null';
+ $redir2 = '' if os_name eq 'VMS';
+ $string = `$make_path -v -f /dev/null $redir2`;
$string =~ /^(GNU Make [^,\n]*)/;
$testee_version = "$1\n";
- $string = `sh -c "$make_path -f /dev/null 2>&1"`;
+ my $redir = '2>&1';
+ $redir = '' if os_name eq 'VMS';
+ $string = `sh -c "$make_path -f /dev/null $redir"`;
if ($string =~ /(.*): \*\*\* No targets\. Stop\./) {
$make_name = $1;
}
else {
- if ($make_path =~ /$pathsep([^\n$pathsep]*)$/) {
- $make_name = $1;
- }
- else {
- $make_name = $make_path;
- }
+ $make_path =~ /^(?:.*$pathsep)?(.+)$/;
+ $make_name = $1;
}
# prepend pwd if this is a relative path (ie, does not
@@ -350,6 +419,24 @@ sub set_more_defaults
$mkpath = $make_path;
}
+ # If srcdir wasn't provided on the command line, see if the
+ # location of the make program gives us a clue. Don't fail if not;
+ # we'll assume it's been installed into /usr/include or wherever.
+ if (! $srcdir) {
+ $make_path =~ /^(.*$pathsep)?/;
+ my $d = $1 || '../';
+ -f "${d}gnumake.h" and $srcdir = $d;
+ }
+
+ # Not with the make program, so see if we can get it out of the makefile
+ if (! $srcdir && open(MF, "< ../Makefile")) {
+ local $/ = undef;
+ $_ = <MF>;
+ close(MF);
+ /^abs_srcdir\s*=\s*(.*?)\s*$/m;
+ -f "$1/gnumake.h" and $srcdir = $1;
+ }
+
# Get Purify log info--if any.
if (exists $ENV{PURIFYOPTIONS}
@@ -359,7 +446,7 @@ sub set_more_defaults
$purify_errors = 0;
}
- $string = `sh -c "$make_path -j 2 -f /dev/null 2>&1"`;
+ $string = `sh -c "$make_path -j 2 -f /dev/null $redir"`;
if ($string =~ /not supported/) {
$parallel_jobs = 0;
}
@@ -367,6 +454,8 @@ sub set_more_defaults
$parallel_jobs = 1;
}
+ %FEATURES = map { $_ => 1 } split /\s+/, `sh -c "echo '\\\$(info \\\$(.FEATURES))' | $make_path -f- 2>/dev/null"`;
+
# Set up for valgrind, if requested.
if ($valgrind) {
diff --git a/tests/scripts/features/archives b/tests/scripts/features/archives
index 3fe46a03..b0acfecb 100644
--- a/tests/scripts/features/archives
+++ b/tests/scripts/features/archives
@@ -11,37 +11,87 @@ exists $FEATURES{archives} or return -1;
# Create some .o files to work with
utouch(-60, qw(a1.o a2.o a3.o));
+my $ar = $CONFIG_FLAGS{AR};
+
+# Some versions of ar print different things on creation. Find out.
+my $created = `$ar rv libxx.a a1.o 2>&1`;
+
+# Some versions of ar print different things on add. Find out.
+my $add = `$ar rv libxx.a a2.o 2>&1`;
+$add =~ s/a2\.o/#OBJECT#/g;
+
+# Some versions of ar print different things on replacement. Find out.
+my $repl = `$ar rv libxx.a a2.o 2>&1`;
+$repl =~ s/a2\.o/#OBJECT#/g;
+
+unlink('libxx.a');
+
# Very simple
run_make_test('all: libxx.a(a1.o)',
- '', "ar rv libxx.a a1.o\nar: creating libxx.a\na - a1.o\n");
+ '', "$ar rv libxx.a a1.o\n$created");
# Multiple .o's. Add a new one to the existing library
+($_ = $add) =~ s/#OBJECT#/a2.o/g;
run_make_test('all: libxx.a(a1.o a2.o)',
- '', "ar rv libxx.a a2.o\na - a2.o\n");
+ '', "$ar rv libxx.a a2.o\n$_");
# Touch one of the .o's so it's rebuilt
utouch(-40, 'a1.o');
-run_make_test(undef, '', "ar rv libxx.a a1.o\nr - a1.o\n");
+($_ = $repl) =~ s/#OBJECT#/a1.o/g;
+run_make_test(undef, '', "$ar rv libxx.a a1.o\n$_");
# Use wildcards
run_make_test('all: libxx.a(*.o)',
- '', "#MAKE#: Nothing to be done for `all'.\n");
+ '', "#MAKE#: Nothing to be done for 'all'.\n");
# Touch one of the .o's so it's rebuilt
utouch(-30, 'a1.o');
-run_make_test(undef, '', "ar rv libxx.a a1.o\nr - a1.o\n");
+($_ = $repl) =~ s/#OBJECT#/a1.o/g;
+run_make_test(undef, '', "$ar rv libxx.a a1.o\n$_");
# Use both wildcards and simple names
utouch(-50, 'a2.o');
+($_ = $add) =~ s/#OBJECT#/a3.o/g;
+$_ .= "$ar rv libxx.a a2.o\n";
+($_ .= $repl) =~ s/#OBJECT#/a2.o/g;
run_make_test('all: libxx.a(a3.o *.o)', '',
- "ar rv libxx.a a3.o\na - a3.o\nar rv libxx.a a2.o\nr - a2.o\n");
+ "$ar rv libxx.a a3.o\n$_");
# Check whitespace handling
utouch(-40, 'a2.o');
+($_ = $repl) =~ s/#OBJECT#/a2.o/g;
run_make_test('all: libxx.a( a3.o *.o )', '',
- "ar rv libxx.a a2.o\nr - a2.o\n");
+ "$ar rv libxx.a a2.o\n$_");
rmfiles(qw(a1.o a2.o a3.o libxx.a));
+# Check non-archive targets
+# See Savannah bug #37878
+run_make_test(q!
+all: foo(bar).baz
+foo(bar).baz: ; @echo '$@'
+!,
+ '', "foo(bar).baz\n");
+
+# Check renaming of archive targets.
+# See Savannah bug #38442
+
+mkdir('artest', 0777);
+touch('foo.vhd');
+
+run_make_test(q!
+DIR = artest
+vpath % $(DIR)
+default: lib(foo)
+(%): %.vhd ; @cd $(DIR) && touch $(*F) && $(AR) $(ARFLAGS) $@ $(*F) >/dev/null 2>&1 && rm $(*F)
+.PHONY: default
+!,
+ '', "");
+
+run_make_test(undef, '', "#MAKE#: Nothing to be done for 'default'.\n");
+
+unlink('foo.vhd');
+remove_directory_tree('artest');
+
# 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
index e53127e1..2e838806 100644
--- a/tests/scripts/features/default_names
+++ b/tests/scripts/features/default_names
@@ -10,32 +10,35 @@ 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";
+# Create another makefile called "makefile"
+open(MAKEFILE,"> makefile");
+print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
close(MAKEFILE);
+# DOS/WIN32/MacOSX platforms are case-insensitive / case-preserving, so
+# Makefile is the same file as makefile. Just test what we can here.
+
+my $case_sensitive = 0;
+if (! -f 'Makefile') {
+ # Create another makefile called "Makefile"
+ $case_sensitive = 1;
+ 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);
-&run_make_with_options("","",&get_logfile);
-&compare_output("It chose GNUmakefile\n",&get_logfile(1));
-unlink $makefile;
+run_make_with_options("","",&get_logfile);
+compare_output("It chose makefile\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";
+if ($case_sensitive) {
+ 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";
+1;
diff --git a/tests/scripts/features/double_colon b/tests/scripts/features/double_colon
index cad605db..1097775b 100644
--- a/tests/scripts/features/double_colon
+++ b/tests/scripts/features/double_colon
@@ -151,5 +151,14 @@ two');
unlink('result','one','two');
+# TEST 10: check for proper backslash handling
+# Savannah bug #33399
+
+run_make_test('
+a\ xb :: ; @echo one
+a\ xb :: ; @echo two
+',
+ '', "one\ntwo\n");
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/features/errors b/tests/scripts/features/errors
index e372fe05..c0339cb6 100644
--- a/tests/scripts/features/errors
+++ b/tests/scripts/features/errors
@@ -42,15 +42,17 @@ close(MAKEFILE);
unlink("cleanit");
$cleanit_error = `sh -c "$rm_command cleanit 2>&1"`;
+chomp $cleanit_error;
$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";
+$answer = "$rm_command cleanit
+$cleanit_error
+$makefile:2: recipe for target 'clean' failed
+$make_name: [clean] Error $delete_error_code (ignored)
+$rm_command foo\n";
&run_make_with_options($makefile,"",&get_logfile);
@@ -74,10 +76,11 @@ if (!$vos)
# TEST #2
# -------
-$answer = "$rm_command cleanit\n"
- . $cleanit_error
- ."$make_name: [clean2] Error $delete_error_code (ignored)\n"
- ."$rm_command foo\n";
+$answer = "$rm_command cleanit
+$cleanit_error
+$makefile:5: recipe for target 'clean2' failed
+$make_name: [clean2] Error $delete_error_code (ignored)
+$rm_command foo\n";
&run_make_with_options($makefile,"clean2 -i",&get_logfile);
diff --git a/tests/scripts/features/escape b/tests/scripts/features/escape
index 97a29941..bf069df2 100644
--- a/tests/scripts/features/escape
+++ b/tests/scripts/features/escape
@@ -2,12 +2,10 @@
$description = "Test various types of escaping in makefiles.";
$details = "\
-Make sure that escaping of `:' works in target names.
+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);
+Make sure that escaping of '#' works.
+Make sure that backslash before non-special characters are kept.";
# TEST 1
@@ -26,7 +24,7 @@ foo\#bar.ext: ; @echo "foo#bar.ext = ($@)"',
run_make_test(undef,
'path=pre:',
- "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.",
+ "#MAKEFILE#:2: *** target pattern contains no '%'. Stop.",
512);
# TEST 3: This one should work, since we escape the ":".
@@ -39,7 +37,7 @@ run_make_test(undef,
run_make_test(undef,
"'path=pre\\\\:'",
- "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.",
+ "#MAKEFILE#:2: *** target pattern contains no '%'. Stop.",
512);
# TEST 5: This one should work
@@ -54,5 +52,23 @@ run_make_test(undef,
'sharp',
'foo#bar.ext = (foo#bar.ext)');
+# Test escaped colons in prerequisites
+# Quoting of backslashes in q!! is kind of messy.
+# Solaris sh does not properly handle backslashes even in '' so just
+# check the output make prints, not what the shell interprets.
+run_make_test(q!
+foo: foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar
+foo foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar: ; : '$@'
+!,
+ '', ": 'foo:bar'\n: 'foo\\:bar'\n: 'foo\\\\:bar'\n: 'foo'\n");
+
+# Test backslash before non-special chars: should be kept as-is
+
+run_make_test(q!
+all: ..\foo
+.DEFAULT: ; : '$@'
+!,
+ '', ": '..\\foo'\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
index ba8908cd..ee014bd8 100644
--- a/tests/scripts/features/include
+++ b/tests/scripts/features/include
@@ -1,6 +1,6 @@
# -*-mode: perl; rm-trailing-spaces: nil-*-
-$description = "Test various forms of the GNU make `include' command.";
+$description = "Test various forms of the GNU make 'include' command.";
$details = "\
Test include, -include, sinclude and various regressions involving them.
@@ -60,7 +60,7 @@ run_make_test
error: foo.mk ; @echo $@
',
'',
- "#MAKE#: *** No rule to make target `foo.mk', needed by `error'. Stop.\n",
+ "#MAKE#: *** No rule to make target 'foo.mk', needed by 'error'. Stop.\n",
512
);
@@ -128,7 +128,7 @@ foo: baz
bar: baz
',
'',
-"#MAKE#: *** No rule to make target `baz', needed by `bar'. Stop.\n",
+"#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
@@ -144,7 +144,7 @@ bar: baz
baz: end
',
'',
-"#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n",
+"#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
@@ -162,7 +162,7 @@ baz: end
',
'',
"#MAKEFILE#:2: bar: No such file or directory
-#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n",
+#MAKE#: *** No rule to make target 'end', needed by 'baz'. Stop.\n",
512);
if ($all_tests) {
@@ -172,7 +172,7 @@ if ($all_tests) {
include foo
foo: ; @echo foo = bar > $@
!,
- '', "#MAKE#: `foo' is up to date.\n");
+ '', "#MAKE#: 'foo' is up to date.\n");
rmfiles('foo');
}
diff --git a/tests/scripts/features/jobserver b/tests/scripts/features/jobserver
new file mode 100644
index 00000000..cedd4b34
--- /dev/null
+++ b/tests/scripts/features/jobserver
@@ -0,0 +1,61 @@
+# -*-perl-*-
+
+$description = "Test jobserver.";
+
+$details = "These tests are ones that specifically are different when the
+jobserver feature is available. Most -j tests are the same whether or not
+jobserver is available, and those appear in the 'parallelism' test suite.";
+
+exists $FEATURES{'jobserver'} or return -1;
+
+if (!$parallel_jobs) {
+ return -1;
+}
+
+# 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
+
+unlink('inc.mk');
+
+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");
+
+unlink('inc.mk');
+
+# Test recursion when make doesn't think it exists.
+# See Savannah bug #39934
+# Or Red Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=885474
+
+open(MAKEFILE,"> Makefile2");
+print MAKEFILE '
+vpath %.c ../
+foo:
+';
+close(MAKEFILE);
+
+run_make_test(q!
+default: ; @ #MAKEPATH# -f Makefile2
+!,
+ '-j2 --no-print-directory',
+"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
+#MAKE#[1]: Nothing to be done for 'foo'.");
+
+rmfiles('Makefile2');
+
+1;
diff --git a/tests/scripts/features/load b/tests/scripts/features/load
new file mode 100644
index 00000000..1f8cdc22
--- /dev/null
+++ b/tests/scripts/features/load
@@ -0,0 +1,110 @@
+# -*-perl-*-
+$description = "Test the load operator.";
+
+$details = "Test dynamic loading of modules.";
+
+# Don't do anything if this system doesn't support "load"
+exists $FEATURES{load} or return -1;
+
+# First build a shared object
+# Provide both a default and non-default load symbol
+
+unlink(qw(testload.c testload.so));
+
+open(my $F, '> testload.c') or die "open: testload.c: $!\n";
+print $F <<'EOF' ;
+#include <string.h>
+#include <stdio.h>
+
+#include "gnumake.h"
+
+int plugin_is_GPL_compatible;
+
+int
+testload_gmk_setup (gmk_floc *pos)
+{
+ (void)pos;
+ gmk_eval ("TESTLOAD = implicit", 0);
+ return 1;
+}
+
+int
+explicit_setup (gmk_floc *pos)
+{
+ (void)pos;
+ gmk_eval ("TESTLOAD = explicit", 0);
+ return 1;
+}
+EOF
+close($F) or die "close: testload.c: $!\n";
+
+# Make sure we can compile
+# CONFIG_FLAGS are loaded from config-flags.pm and set by configure
+
+my $sobuild = "$CONFIG_FLAGS{CC} ".($srcdir? "-I$srcdir":'')." $CONFIG_FLAGS{CPPFLAGS} $CONFIG_FLAGS{CFLAGS} -shared -fPIC $CONFIG_FLAGS{LDFLAGS} -o testload.so testload.c";
+
+my $clog = `$sobuild 2>&1`;
+if ($? != 0) {
+ $verbose and print "Failed to build testload.so:\n$sobuild\n$_";
+ return -1;
+}
+
+# TEST 1
+run_make_test(q!
+PRE := $(.LOADED)
+load testload.so
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+!,
+ '', "pre= post=testload.so implicit\n");
+
+# TEST 2
+# Load using an explicit function
+run_make_test(q!
+PRE := $(.LOADED)
+load ./testload.so(explicit_setup)
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+!,
+ '', "pre= post=testload.so explicit\n");
+
+# TEST 4
+# Check multiple loads
+run_make_test(q!
+PRE := $(.LOADED)
+load ./testload.so
+load testload.so(explicit_setup)
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+!,
+ '', "pre= post=testload.so implicit\n");
+
+# TEST 5
+# Check auto-rebuild of loaded file that's out of date
+utouch(-10, 'testload.so');
+touch('testload.c');
+
+run_make_test(q!
+PRE := $(.LOADED)
+load ./testload.so
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+testload.so: testload.c ; @echo "rebuilding $@"; !.$sobuild,
+ '', "rebuilding testload.so\npre= post=testload.so implicit\n");
+
+# TEST 5
+# Check auto-rebuild of loaded file when it doesn't exist
+unlink('testload.so');
+
+run_make_test(q!
+PRE := $(.LOADED)
+-load ./testload.so(explicit_setup)
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+%.so: %.c ; @echo "rebuilding $@"; !.$sobuild,
+ '', "rebuilding testload.so\npre= post=testload.so explicit\n");
+
+unlink(qw(testload.c testload.so)) unless $keep;
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/loadapi b/tests/scripts/features/loadapi
new file mode 100644
index 00000000..8c824c04
--- /dev/null
+++ b/tests/scripts/features/loadapi
@@ -0,0 +1,116 @@
+# -*-perl-*-
+$description = "Test the shared object load API.";
+
+$details = "Verify the different aspects of the shared object API.";
+
+# Don't do anything if this system doesn't support "load"
+exists $FEATURES{load} or return -1;
+
+# First build a shared object
+# Provide both a default and non-default load symbol
+
+unlink(qw(testapi.c testapi.so));
+
+open(my $F, '> testapi.c') or die "open: testapi.c: $!\n";
+print $F <<'EOF' ;
+#include <string.h>
+#include <stdio.h>
+
+#include "gnumake.h"
+
+int plugin_is_GPL_compatible;
+
+static char *
+test_eval (const char *buf)
+{
+ gmk_eval (buf, 0);
+ return NULL;
+}
+
+static char *
+test_expand (const char *val)
+{
+ return gmk_expand (val);
+}
+
+static char *
+test_noexpand (const char *val)
+{
+ char *str = gmk_alloc (strlen (val) + 1);
+ strcpy (str, val);
+ return str;
+}
+
+static char *
+func_test (const char *funcname, unsigned int argc, char **argv)
+{
+ char *mem;
+
+ if (strcmp (funcname, "test-expand") == 0)
+ return test_expand (argv[0]);
+
+ if (strcmp (funcname, "test-eval") == 0)
+ return test_eval (argv[0]);
+
+ if (strcmp (funcname, "test-noexpand") == 0)
+ return test_noexpand (argv[0]);
+
+ mem = gmk_alloc (sizeof ("unknown"));
+ strcpy (mem, "unknown");
+ return mem;
+}
+
+int
+testapi_gmk_setup ()
+{
+ gmk_add_function ("test-expand", func_test, 1, 1, GMK_FUNC_DEFAULT);
+ gmk_add_function ("test-noexpand", func_test, 1, 1, GMK_FUNC_NOEXPAND);
+ gmk_add_function ("test-eval", func_test, 1, 1, GMK_FUNC_DEFAULT);
+ gmk_add_function ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.", func_test, 0, 0, 0);
+ return 1;
+}
+EOF
+close($F) or die "close: testapi.c: $!\n";
+
+my $sobuild = "$CONFIG_FLAGS{CC} ".($srcdir? "-I$srcdir":'')." $CONFIG_FLAGS{CPPFLAGS} $CONFIG_FLAGS{CFLAGS} -shared -fPIC $CONFIG_FLAGS{LDFLAGS} -o testapi.so testapi.c";
+
+my $clog = `$sobuild 2>&1`;
+if ($? != 0) {
+ $verbose and print "Failed to build testapi.so:\n$sobuild\n$_";
+ return -1;
+}
+
+# TEST 1
+# Check the gmk_expand() function
+run_make_test(q!
+EXPAND = expansion
+all: ; @echo $(test-expand $$(EXPAND))
+load testapi.so
+!,
+ '', "expansion\n");
+
+# TEST 2
+# Check the eval operation. Prove that the argument is expanded only once
+run_make_test(q!
+load testapi.so
+TEST = bye
+ASSIGN = VAR = $(TEST) $(shell echo there)
+$(test-eval $(value ASSIGN))
+TEST = hi
+all:;@echo '$(VAR)'
+!,
+ '', "hi there\n");
+
+# TEST 2
+# Check the no-expand capability
+run_make_test(q!
+load testapi.so
+TEST = hi
+all:;@echo '$(test-noexpand $(TEST))'
+!,
+ '', "\$(TEST)\n");
+
+unlink(qw(testapi.c testapi.so)) unless $keep;
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/mult_rules b/tests/scripts/features/mult_rules
index 6f120f10..e706e17d 100644
--- a/tests/scripts/features/mult_rules
+++ b/tests/scripts/features/mult_rules
@@ -47,7 +47,7 @@ else
$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";
+$answer = "$make_name: *** No rule to make target 'extra.h', needed by 'foo.o'. Stop.\n";
&compare_output($answer,&get_logfile(1));
diff --git a/tests/scripts/features/output-sync b/tests/scripts/features/output-sync
new file mode 100644
index 00000000..a7534cb7
--- /dev/null
+++ b/tests/scripts/features/output-sync
@@ -0,0 +1,341 @@
+# -*-perl-*-
+
+$description = "Test --output-sync (-O) option.";
+
+$details = "Test the synchronization of output from parallel jobs.";
+
+# If we don't have output sync support, never mind.
+exists $FEATURES{'output-sync'} or return -1;
+
+# Output sync can't be tested without parallelization
+$parallel_jobs or return -1;
+
+
+if ($vos) {
+ $sleep_command = "sleep -seconds";
+}
+else {
+ $sleep_command = "sleep";
+}
+
+# The following subdirectories with Makefiles are used in several
+# of the following tests. The model is:
+# foo/Makefile - has a "foo" target that waits for the bar target
+# bar/Makefile - has a "bar" target that runs immediately
+# - has a "baz" target that waits for the foo target
+#
+# So, you start the two sub-makes in parallel and first the "bar" target is
+# built, followed by "foo", followed by "baz". The trick is that first each
+# target prints a "start" statement, then waits (if appropriate), then prints
+# an end statement. Thus we can tell if the -O flag is working, since
+# otherwise these statements would be mixed together.
+
+@syncfiles = ();
+
+sub output_sync_clean {
+ rmfiles('foo/Makefile', 'bar/Makefile', @syncfiles);
+ rmdir('foo');
+ rmdir('bar');
+}
+
+# We synchronize the different jobs by having them wait for a sentinel file to
+# be created, instead of relying on a certain amount of time passing.
+# Unfortunately in this test we have to sleep after we see the sync file,
+# since we also want to make the obtaining of the write synchronization lock
+# reliable. If things are too fast, then sometimes a different job will steal
+# the output sync lock and the output is mis-ordered from what we expect.
+sub output_sync_wait {
+ return "while [ ! -f ../mksync.$_[0] ]; do :; done; rm -f ../mksync.$_[0].wait; $sleep_command 1";
+}
+sub output_sync_set {
+ return "date > ../mksync.$_[0]";
+}
+
+@syncfiles = qw(mksync.foo mksync.foo_start mksync.bar mksync.bar_start);
+
+output_sync_clean();
+mkdir('foo', 0777);
+mkdir('bar', 0777);
+
+$set_foo = output_sync_set('foo');
+$set_bar = output_sync_set('bar');
+$set_foo_start = output_sync_set('foo_start');
+$set_bar_start = output_sync_set('bar_start');
+
+$wait_foo = output_sync_wait('foo');
+$wait_bar = output_sync_wait('bar');
+$wait_foo_start = output_sync_set('foo_start');
+$wait_bar_start = output_sync_set('bar_start');
+
+open(MAKEFILE,"> foo/Makefile");
+print MAKEFILE <<EOF;
+all: foo
+
+foo: foo-base ; \@$set_foo
+
+foo-base:
+\t\@echo foo: start
+\t\@$wait_bar
+\t\@echo foo: end
+
+foo-job: foo-job-base ; \@$set_foo
+
+foo-job-base:
+\t\@$wait_bar_start
+\t\@echo foo: start
+\t\@$set_foo_start
+\t\@$wait_bar
+\t\@echo foo: end
+
+foo-fail:
+\t\@echo foo-fail: start
+\t\@$wait_bar
+\t\@echo foo-fail: end
+\t\@exit 1
+EOF
+close(MAKEFILE);
+
+open(MAKEFILE,"> bar/Makefile");
+print MAKEFILE <<EOF;
+all: bar baz
+
+bar: bar-base ; \@$set_bar
+bar-base:
+\t\@echo bar: start
+\t\@echo bar: end
+
+bar-job: bar-job-base ; \@$set_bar
+
+bar-job-base:
+\t\@echo bar: start
+\t\@$set_bar_start
+\t\@$wait_foo_start
+\t\@echo bar: end
+
+baz: baz-base
+baz-base:
+\t\@echo baz: start
+\t\@$wait_foo
+\t\@echo baz: end
+EOF
+close(MAKEFILE);
+
+# Test per-make synchronization.
+unlink(@syncfiles);
+run_make_test(qq!
+all: make-foo make-bar
+
+make-foo: ; \$(MAKE) -C foo
+
+make-bar: ; \$(MAKE) -C bar!,
+ '-j -Orecurse',
+"#MAKEPATH# -C foo
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo: start
+foo: end
+#MAKE#[1]: Leaving directory '#PWD#/foo'
+#MAKEPATH# -C bar
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: start
+bar: end
+baz: start
+baz: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, 6);
+
+# Test per-target synchronization.
+# Note we have to sleep again here after starting the foo makefile before
+# starting the bar makefile, otherwise the "entering/leaving" messages for the
+# submakes might be ordered differently than we expect.
+
+unlink(@syncfiles);
+run_make_test(qq!
+x=1
+\$xMAKEFLAGS += --no-print-directory
+
+all: make-foo make-bar
+
+make-foo: ; \$(MAKE) -C foo
+
+make-bar: ; $sleep_command 1 ; \$(MAKE) -C bar!,
+ '-j --output-sync=target',
+"#MAKEPATH# -C foo
+$sleep_command 1 ; #MAKEPATH# -C bar
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: start
+bar: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo: start
+foo: end
+#MAKE#[1]: Leaving directory '#PWD#/foo'
+#MAKE#[1]: Entering directory '#PWD#/bar'
+baz: start
+baz: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, 6);
+
+# Rerun but this time suppress the directory tracking
+unlink(@syncfiles);
+run_make_test(undef, '-j --output-sync=target x=',
+ "#MAKEPATH# -C foo
+$sleep_command 1 ; #MAKEPATH# -C bar
+bar: start
+bar: end
+foo: start
+foo: end
+baz: start
+baz: end\n", 0, 6);
+
+# Test that messages from make itself are enclosed with
+# "Entering/Leaving directory" messages.
+unlink(@syncfiles);
+run_make_test(qq!
+all: make-foo-fail make-bar-bar
+
+make-foo-fail: ; \$(MAKE) -C foo foo-fail
+
+make-bar-bar: ; $sleep_command 1 ; \$(MAKE) -C bar bar!,
+ '-j -O',
+"#MAKEPATH# -C foo foo-fail
+$sleep_command 1 ; #MAKEPATH# -C bar bar
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: start
+bar: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo-fail: start
+foo-fail: end
+Makefile:20: recipe for target 'foo-fail' failed
+#MAKE#[1]: *** [foo-fail] Error 1
+#MAKE#[1]: Leaving directory '#PWD#/foo'
+#MAKEFILE#:4: recipe for target 'make-foo-fail' failed
+#MAKE#: *** [make-foo-fail] Error 2\n",
+512);
+
+# Test the per-job synchronization.
+# For this we'll have bar-job:
+# print start, invoke bar-start, wait for foo-start, print end, print-bar-end
+# And foo-job:
+# wait for bar-start, print foo-start, wait for bar-end, print end
+
+unlink(@syncfiles);
+run_make_test(qq!
+all: make-foo make-bar
+
+make-foo: ; \$(MAKE) -C foo foo-job
+
+make-bar: ; $sleep_command 1 ; \$(MAKE) -C bar bar-job!,
+ '-j --output-sync=line',
+"#MAKEPATH# -C foo foo-job
+$sleep_command 1 ; #MAKEPATH# -C bar bar-job
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo: start
+#MAKE#[1]: Leaving directory '#PWD#/foo'
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: start
+#MAKE#[1]: Leaving directory '#PWD#/bar'
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo: end
+#MAKE#[1]: Leaving directory '#PWD#/foo'\n", 0, 6);
+
+
+# Remove temporary directories and contents.
+output_sync_clean();
+
+# Ensure recursion doesn't mis-order or double-print output
+run_make_test(qq!
+all:
+\t\@echo foo
+\t\@+echo bar
+!,
+ '-j -Oline', "foo\nbar\n");
+
+run_make_test(undef, '-j -Otarget', "foo\nbar\n");
+
+# Ensure when make writes out command it's not misordered
+run_make_test(qq!
+all:
+\t\@echo foobar
+\ttrue
+!,
+ '-j -Oline', "foobar\ntrue\n");
+
+run_make_test(undef, '-j -Otarget', "foobar\ntrue\n");
+
+# Ensure that shell functions inside recipes write stderr to the sync file
+run_make_test(q!
+all: ; @: $(shell echo foo 1>&2)
+!,
+ '-w -Oline', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n");
+
+# Ensure that output generated while parsing makefiles is synced
+# when appropriate.
+run_make_test(q!
+$(shell echo foo 1>&2)
+all: ; echo bar
+!,
+ '-s -w -Otarget', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n#MAKE#: Entering directory '#PWD#'\nbar\n#MAKE#: Leaving directory '#PWD#'\n");
+
+# Test recursion
+$m1 = get_tmpfile();
+$m2 = get_tmpfile();
+
+open(M1, "> $m1");
+print M1 <<'EOF';
+$(shell echo d1 stderr 1>&2)
+$(info d1 stdout)
+all:; @:
+EOF
+close(M1);
+
+open(M2, "> $m2");
+print M2 <<'EOF';
+$(shell echo d2 stderr 1>&2)
+$(info d2 stdout)
+all:; @:
+# Force an ordering on the output
+$(shell sleep 1)
+EOF
+close(M2);
+
+run_make_test(qq!
+all: t1 t2
+t1: ; \@\$(MAKE) -f $m1
+t2: ; \@\$(MAKE) -f $m2
+!,
+ "-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKE#[1]: Entering directory '#PWD#'\nd2 stderr\nd2 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n");
+
+rmfiles($m1, $m2);
+
+# Ensure that output generated while parsing makefiles is synced
+# when appropriate.
+$m1 = get_tmpfile();
+
+open(M1, "> $m1");
+print M1 <<'EOF';
+$(shell echo d1 stderr 1>&2)
+$(info d1 stdout)
+$(error d1 failed)
+all:; @:
+EOF
+close(M1);
+
+run_make_test(qq!
+all: t1
+t1: ; -\@\$(MAKE) -f $m1
+!,
+ "-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n$m1:3: *** d1 failed. Stop.\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKEFILE#:3: recipe for target 't1' failed\n#MAKE#: [t1] Error 2 (ignored)\n");
+
+rmfiles($m1);
+
+# Test $(error ...) functions in recipes
+
+run_make_test(q!
+foo: $(OBJS) ; echo $(or $(filter %.o,$^),$(error fail))
+!,
+ '-O', "#MAKEFILE#:2: *** fail. Stop.\n", 512);
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism
index cc0f84f6..c702c268 100644
--- a/tests/scripts/features/parallelism
+++ b/tests/scripts/features/parallelism
@@ -41,7 +41,7 @@ all: 1 2; \@echo success
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");
+ "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7);
rmfiles(qw(1.inc 2.inc));
@@ -60,7 +60,7 @@ 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");
+ "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7);
rmfiles(qw(1.inc 2.inc));
@@ -91,21 +91,24 @@ run_make_test("
all: fail.1 ok fail.2 fail.3
fail.1 fail.2 fail.3:
- \@sleep \$(patsubst fail.%,%,\$\@)
+ \@$sleep_command \$(patsubst fail.%,%,\$\@)
\@echo Fail
\@exit 1
ok:
- \@sleep 4
+ \@$sleep_command 4
\@echo Ok done",
- '-rR -j5', 'Fail
+ '-rR -j5', "Fail
+#MAKEFILE#:6: recipe for target 'fail.1' failed
#MAKE#: *** [fail.1] Error 1
#MAKE#: *** Waiting for unfinished jobs....
Fail
+#MAKEFILE#:6: recipe for target 'fail.2' failed
#MAKE#: *** [fail.2] Error 1
Fail
+#MAKEFILE#:6: recipe for target 'fail.3' failed
#MAKE#: *** [fail.3] Error 1
-Ok done',
+Ok done",
512);
@@ -140,81 +143,40 @@ intermed: | phony ; touch $@
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
+# TEST #11: Make sure -jN from MAKEFLAGS is processed even when we re-exec
+# See Savannah bug #33873
+
+$extraENV{MAKEFLAGS} = '-j4';
run_make_test(q!
+things = thing1 thing2
+all: $(things)
+thing1:; @sleep 1; echo '$@ start'; sleep 2; echo '$@ end'
+thing2:; @echo '$@ start'; sleep 2; echo '$@ end'
-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' > $@
+inc.mk: ; @touch $@
!,
- '--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
+ '', "thing2 start\nthing1 start\nthing2 end\nthing1 end\n");
+delete $extraENV{MAKEFLAGS};
rmfiles('inc.mk');
-if ($all_tests) {
- # Implicit files aren't properly recreated during parallel builds
- # Savannah bug #26864
+# Ensure intermediate/secondary files are not pruned incorrectly.
+# See Savannah bug #30653
- # 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));
-}
+utouch(-15, 'file2');
+utouch(-10, 'file4');
+utouch(-5, 'file1');
-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
+run_make_test(q!
+.INTERMEDIATE: file3
+file4: file3 ; @mv -f $< $@
+file3: file2 ; touch $@
+file2: file1 ; @touch $@
!,
- '-j2',
- '#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.
-true
-true
-');
-}
+ '--no-print-directory -j2', "touch file3");
+
+rmfiles('file1', 'file2', 'file3', 'file4');
# Make sure that all jobserver FDs are closed if we need to re-exec the
# master copy.
diff --git a/tests/scripts/features/patspecific_vars b/tests/scripts/features/patspecific_vars
index 8ca228d7..a530bba1 100644
--- a/tests/scripts/features/patspecific_vars
+++ b/tests/scripts/features/patspecific_vars
@@ -81,7 +81,7 @@ all: bar baz
b%: pattern := good $$t
-global := orginal $$t
+global := original $$t
# normal target
@@ -103,14 +103,14 @@ else
%z: a := global: $(global) pattern: $(pattern) inherit: $(inherit)
endif
-%z: ; @echo \'pattrn: $a;\'
+%z: ; @echo \'pattern: $a;\'
global := new $$t
',
'',
-'normal: global: orginal $t pattern: inherit: ;
-pattrn: global: orginal $t pattern: inherit: ;');
+'normal: global: original $t pattern: inherit: ;
+pattern: global: original $t pattern: inherit: ;');
# TEST #7 -- test expansion of pattern-specific recursive variables
@@ -118,7 +118,7 @@ pattrn: global: orginal $t pattern: inherit: ;');
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;');
+pattern: global: new $t pattern: good $t inherit: good $t;');
# TEST #8: override in pattern-specific variables
diff --git a/tests/scripts/features/patternrules b/tests/scripts/features/patternrules
index eebe7c0a..0ff49a75 100644
--- a/tests/scripts/features/patternrules
+++ b/tests/scripts/features/patternrules
@@ -110,7 +110,8 @@ $(dir)/foo.bar:
',
"dir=$dir",
-"#MAKE#: *** [$dir/foo.bar] Error 1",
+"#MAKEFILE#:6: recipe for target '$dir/foo.bar' failed
+#MAKE#: *** [$dir/foo.bar] Error 1",
512);
unlink("$dir/foo.bar");
@@ -203,7 +204,7 @@ CWEAVE := :
%.tex : %.w %.ch
!,
'foo.tex',
- "#MAKE#: *** No rule to make target `foo.tex'. Stop.", 512);
+ "#MAKE#: *** No rule to make target 'foo.tex'. Stop.", 512);
unlink(@f);
diff --git a/tests/scripts/features/recursion b/tests/scripts/features/recursion
index a6b8f909..fd5e3518 100644
--- a/tests/scripts/features/recursion
+++ b/tests/scripts/features/recursion
@@ -18,7 +18,7 @@ last:
',
('CFLAGS=-O -w' . ($parallel_jobs ? ' -j 2' : '')),
($vos
- ? "#MAKE#: Entering directory `#PWD#'
+ ? "#MAKE#: Entering directory '#PWD#'
make 'CFLAGS=-O' -f #MAKEFILE# foo
make CFLAGS=-O
MAKELEVEL = 0
@@ -26,20 +26,20 @@ make 'CFLAGS=-O' -f #MAKEFILE# last
make CFLAGS=-O
MAKELEVEL = 0
THE END
-#MAKE#: Leaving directory `#PWD#'"
- : "#MAKE#: Entering directory `#PWD#'
+#MAKE#: Leaving directory '#PWD#'"
+ : "#MAKE#: Entering directory '#PWD#'
#MAKEPATH# -f #MAKEFILE# foo
-#MAKE#[1]: Entering directory `#PWD#'
+#MAKE#[1]: Entering directory '#PWD#'
#MAKEPATH#
MAKELEVEL = 1
#MAKEPATH# -f #MAKEFILE# last
-#MAKE#[2]: Entering directory `#PWD#'
+#MAKE#[2]: Entering directory '#PWD#'
#MAKEPATH#
MAKELEVEL = 2
THE END
-#MAKE#[2]: Leaving directory `#PWD#'
-#MAKE#[1]: Leaving directory `#PWD#'
-#MAKE#: Leaving directory `#PWD#'"));
+#MAKE#[2]: Leaving directory '#PWD#'
+#MAKE#[1]: Leaving directory '#PWD#'
+#MAKE#: Leaving directory '#PWD#'"));
# Test command line overrides.
diff --git a/tests/scripts/features/reinvoke b/tests/scripts/features/reinvoke
index 9952ced1..eb1a3492 100644
--- a/tests/scripts/features/reinvoke
+++ b/tests/scripts/features/reinvoke
@@ -57,9 +57,24 @@ include $(F)',
# 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")
+run_make_test(undef, 'F=b', "[ -f b ] || echo >> b\nhello\n")
&rmfiles('a','b','c');
+# Ensure command line variables are preserved properly across re-exec
+# Tests for Savannah bug #30723
+
+run_make_test('
+ifdef RECURSE
+-include foo30723
+endif
+recurse: ; @$(MAKE) -f $(MAKEFILE_LIST) RECURSE=1 test
+test: ; @echo F.O=$(F.O)
+foo30723: ; @touch $@
+',
+ '--no-print-directory F.O=bar', "F.O=bar\n");
+
+unlink('foo30723');
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/features/rule_glob b/tests/scripts/features/rule_glob
new file mode 100644
index 00000000..2d377e7e
--- /dev/null
+++ b/tests/scripts/features/rule_glob
@@ -0,0 +1,37 @@
+# -*-perl-*-
+
+$description = "Test globbing in targets and prerequisites.";
+
+$details = "";
+
+touch(qw(a.one a.two a.three));
+
+# Test wildcards in regular targets and prerequisites
+run_make_test(q{
+.PHONY: all a.one a.two a.three
+all: a.one* a.t[a-z0-9]o a.th[!q]ee
+a.o[Nn][Ee] a.t*: ; @echo $@
+},
+ '', "a.one\na.two\na.three");
+
+# Test wildcards in pattern targets and prerequisites
+run_make_test(q{
+.PHONY: all
+all: a.four
+%.four : %.t* ; @echo $@: $(sort $^)
+},
+ '', "a.four: a.three a.two");
+
+# Test wildcards in second expansion targets and prerequisites
+run_make_test(q{
+.PHONY: all
+all: a.four
+.SECONDEXPANSION:
+%.four : $$(sort %.t*) ; @echo $@: $(sort $^)
+},
+ '', "a.four: a.three a.two");
+
+unlink(qw(a.one a.two a.three));
+
+# 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
index 79e0a36f..790017af 100644
--- a/tests/scripts/features/se_explicit
+++ b/tests/scripts/features/se_explicit
@@ -6,6 +6,9 @@ $details = "";
# TEST #0: Test handing of '$' in prerequisites with and without second
# expansion.
+# If we don't support archives then the prerequisite is different
+my $prereq = exists $FEATURES{'archives'} ? '$' : '$(PRE)';
+
run_make_test(q!
ifdef SE
.SECONDEXPANSION:
@@ -18,7 +21,7 @@ PRE = three four
.DEFAULT: ; @echo '$@'
!,
'',
- "\$\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
+ "$prereq\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
run_make_test(undef, 'SE=1', "three\nfour\nbariz\nfoo\$bar : baraz bariz");
@@ -115,7 +118,7 @@ run_make_test(q!
.SECONDEXPANSION:
all : $$(eval $$(info test))
!,
- '', "test\n#MAKE#: Nothing to be done for `all'.\n");
+ '', "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.
@@ -152,5 +155,13 @@ a%l: q1x $$+ q2x ; @echo '$+'
'', "q1x bar bar q2x bar bar\n");
-# This tells the test driver that the perl test script executed properly.
+# Allow patsubst shorthand in second expansion context.
+# Requires the colon to be quoted. Savannah bug #16545
+run_make_test(q!
+.PHONY: foo.bar
+.SECONDEXPANSION:
+foo: $$(@\\:%=%.bar); @echo '$^'
+!,
+ '', "foo.bar\n");
+
1;
diff --git a/tests/scripts/features/se_implicit b/tests/scripts/features/se_implicit
index e9acb2f5..ec09d8da 100644
--- a/tests/scripts/features/se_implicit
+++ b/tests/scripts/features/se_implicit
@@ -222,5 +222,39 @@ foo.o:
!,
'', "\n");
+# Test #10: Test second expansion with second expansion prerequisites
+# Ensures pattern_search() recurses with SE prereqs.
+touch('a');
+run_make_test(q!
+.SECONDEXPANSION:
+sim_base_rgg := just_a_name
+sim_base_src := a
+sim_base_f := a a a
+sim_%.f: $${sim_$$*_f}
+ echo $@
+sim_%.src: $${sim_$$*_src}
+ echo $@
+sim_%: \
+ $$(if $$(sim_$$*_src),sim_%.src) \
+ $$(if $$(sim_$$*_f),sim_%.f) \
+ $$(if $$(sim_$$*_rgg),$$(sim_$$*_rgg).s)
+ echo $@
+!,
+ '-s sim_base', "#MAKE#: *** No rule to make target 'sim_base'. Stop.", 512);
+
+unlink('a');
+
+# Ensure that order-only tokens embedded in second expansions are parsed
+run_make_test(q!
+.SECONDEXPANSION:
+PREREQS=p1|p2
+P2=p2
+all : foo bar
+f%o: $$(PREREQS) ; @echo '$@' from '$^' and '$|'
+b%r: p1|$$(P2) ; @echo '$@' from '$^' and '$|'
+p% : ; : $@
+!,
+ "", ": p1\n: p2\nfoo from p1 and p2\nbar from p1 and p2\n");
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars
index ddd6c1f5..a9b8dbeb 100644
--- a/tests/scripts/features/targetvars
+++ b/tests/scripts/features/targetvars
@@ -237,10 +237,20 @@ a: ; @echo "$(FOO)"
run_make_test(undef, 'FOO=C', "C f1\n");
+# TEST #19: Conditional variables with command-line settings
+
+run_make_test('
+a: FOO ?= f1
+a: ; @echo "$(FOO)"
+',
+ '', "f1\n");
+
+run_make_test(undef, 'FOO=C', "C\n");
+
# TEST #20: Check for continuation after semicolons
run_make_test(q!
-a: A = 'hello; \
+a: A = 'hello;\
world'
a: ; @echo $(A)
!,
diff --git a/tests/scripts/features/utf8 b/tests/scripts/features/utf8
new file mode 100644
index 00000000..54bc4710
--- /dev/null
+++ b/tests/scripts/features/utf8
@@ -0,0 +1,11 @@
+# -*-perl-*-
+
+$description = "Test support for UTF-8.";
+
+$details = "";
+
+# Verify that the UTF-8 BOM is ignored.
+run_make_test("\xEF\xBB\xBFall: ; \@echo \$\@\n", '', "all");
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/varnesting b/tests/scripts/features/varnesting
index 15d50711..d8f3ffbb 100644
--- a/tests/scripts/features/varnesting
+++ b/tests/scripts/features/varnesting
@@ -1,29 +1,30 @@
-$description = "The following test creates a makefile to ...";
+# -*-perl-*-
+$description = "Test recursive variables";
$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));
+run_make_test('
+x = variable1
+variable2 := Hello
+y = $(subst 1,2,$(x))
+z = y
+a := $($($(z)))
+all:
+ @echo $(a)
+',
+ '', "Hello\n");
+
+# This tests resetting the value of a variable while expanding it.
+# You may only see problems with this if you're using valgrind or
+# some other memory checker that poisons freed memory.
+# See Savannah patch #7534
+
+run_make_test('
+VARIABLE = $(eval VARIABLE := echo hi)$(VARIABLE)
+wololo:
+ @$(VARIABLE)
+',
+ '', "hi\n");
1;
diff --git a/tests/scripts/features/vpath b/tests/scripts/features/vpath
index a3aebd91..ec24165f 100644
--- a/tests/scripts/features/vpath
+++ b/tests/scripts/features/vpath
@@ -74,7 +74,7 @@ vpath-d/a: fail.te
vpath-d/b : fail.te
vpath-d/fail.te:
!,
- '', "#MAKE#: Nothing to be done for `default'.\n");
+ '', "#MAKE#: Nothing to be done for 'default'.\n");
rmdir('vpath-d');
diff --git a/tests/scripts/features/vpath3 b/tests/scripts/features/vpath3
index 978c5ee6..c6ede282 100644
--- a/tests/scripts/features/vpath3
+++ b/tests/scripts/features/vpath3
@@ -1,50 +1,35 @@
-# -*-perl-*-
+# -*-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");
+my @dirs_to_make = qw(a1 b1 a2 b2 b3);
+for my $d (@dirs_to_make) {
+ mkdir($d, 0777);
+}
+my @files_to_touch = ("a1${pathsep}lib1.a",
+ "a1${pathsep}libc.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");
+run_make_test('
+vpath %.h b3
+vpath %.a a1
+vpath %.so b1
+vpath % a2 b2
+vpath % b3
+all: -l1 -lc -l2 -l3; @echo $^
+',
+ '', "a1${pathsep}lib1.a a1${pathsep}libc.a a2${pathsep}lib2.a lib3.a\n");
+
+unlink(@files_to_touch);
+for my $d (@dirs_to_make) {
+ rmdir($d);
}
1;
diff --git a/tests/scripts/features/vpathgpath b/tests/scripts/features/vpathgpath
index f7683f52..5e6217bf 100644
--- a/tests/scripts/features/vpathgpath
+++ b/tests/scripts/features/vpathgpath
@@ -57,7 +57,7 @@ sub touchfiles {
push(@touchedfiles, "bar.c");
-$answer = "$make_name: Nothing to be done for `general'.\n";
+$answer = "$make_name: Nothing to be done for 'general'.\n";
&compare_output($answer,&get_logfile(1));
diff --git a/tests/scripts/features/vpathplus b/tests/scripts/features/vpathplus
index a37fbedd..361788c7 100644
--- a/tests/scripts/features/vpathplus
+++ b/tests/scripts/features/vpathplus
@@ -86,6 +86,7 @@ cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1
$answer = "not creating notarget.c from notarget.d
cat notarget.c > notarget.b 2>/dev/null || exit 1
+$makefile:16: recipe for target 'notarget.b' failed
$make_name: *** [notarget.b] Error 1
";
diff --git a/tests/scripts/functions/call b/tests/scripts/functions/call
index f3c54708..9db9da71 100644
--- a/tests/scripts/functions/call
+++ b/tests/scripts/functions/call
@@ -13,7 +13,7 @@ print MAKEFILE <<'EOMAKE';
#
reverse = $2 $1
-# A complex `map' function, using recursive `call'.
+# A complex 'map' function, using recursive 'call'.
#
map = $(foreach a,$2,$(call $1,$a))
@@ -38,7 +38,7 @@ two = $(call one,$(1),foo,$(2))
DEP_foo = bar baz quux
DEP_baz = quux blarp
rest = $(wordlist 2,$(words ${1}),${1})
-tclose = $(if $1,$(firstword $1) \
+tclose = $(if $1,$(firstword $1)\
$(call tclose,$(sort ${DEP_$(firstword $1)} $(call rest,$1))))
all: ; @echo '$(call reverse,bar,foo)'; \
@@ -96,4 +96,15 @@ close(MAKEFILE);
$answer = "1 2 3 4 5 6 7 8 9\n1 2 3 4 5\n1 2 3\n1 2 3\n";
&compare_output($answer,&get_logfile(1));
+# Ensure that variables are defined in global scope even in a $(call ...)
+
+delete $ENV{X123};
+
+run_make_test('
+tst = $(eval export X123)
+$(call tst)
+all: ; @echo "$${X123-not set}"
+',
+ '', "\n");
+
1;
diff --git a/tests/scripts/functions/file b/tests/scripts/functions/file
new file mode 100644
index 00000000..55eb58a0
--- /dev/null
+++ b/tests/scripts/functions/file
@@ -0,0 +1,118 @@
+# -*-perl-*-
+
+$description = 'Test the $(file ...) function.';
+
+# Test > and >>
+run_make_test(q!
+define A
+a
+b
+endef
+B = c d
+$(file >file.out,$(A))
+$(foreach L,$(B),$(file >> file.out,$L))
+x:;@echo hi; cat file.out
+!,
+ '', "hi\na\nb\nc\nd");
+
+unlink('file.out');
+
+# Test >> to a non-existent file
+run_make_test(q!
+define A
+a
+b
+endef
+$(file >> file.out,$(A))
+x:;@cat file.out
+!,
+ '', "a\nb");
+
+unlink('file.out');
+
+# Test > with no content
+run_make_test(q!
+$(file >4touch)
+.PHONY:x
+x:;@cat 4touch
+!,
+ '', '');
+
+# Test >> with no content
+run_make_test(q!
+$(file >>4touch)
+.PHONY:x
+x:;@cat 4touch
+!,
+ '', '');
+unlink('4touch');
+
+# Test > to a read-only file
+touch('file.out');
+chmod(0444, 'file.out');
+
+# Find the error that will be printed
+# This seems complicated, but we need the message from the C locale
+my $loc = undef;
+if ($has_POSIX) {
+ $loc = POSIX::setlocale(POSIX::LC_MESSAGES);
+ POSIX::setlocale(POSIX::LC_MESSAGES, 'C');
+}
+my $e;
+open(my $F, '>', 'file.out') and die "Opened read-only file!\n";
+$e = "$!";
+$loc and POSIX::setlocale(POSIX::LC_MESSAGES, $loc);
+
+run_make_test(q!
+define A
+a
+b
+endef
+$(file > file.out,$(A))
+x:;@cat file.out
+!,
+ '', "#MAKEFILE#:6: *** open: file.out: $e. Stop.",
+ 512);
+
+unlink('file.out');
+
+# Use variables for operator and filename
+run_make_test(q!
+define A
+a
+b
+endef
+OP = >
+FN = file.out
+$(file $(OP) $(FN),$(A))
+x:;@cat file.out
+!,
+ '', "a\nb");
+
+unlink('file.out');
+
+# Don't add newlines if one already exists
+run_make_test(q!
+define A
+a
+b
+
+endef
+$(file >file.out,$(A))
+x:;@cat file.out
+!,
+ '', "a\nb");
+
+unlink('file.out');
+
+# Empty text
+run_make_test(q!
+$(file >file.out,)
+$(file >>file.out,)
+x:;@cat file.out
+!,
+ '', "\n\n");
+
+unlink('file.out');
+
+1;
diff --git a/tests/scripts/functions/filter-out b/tests/scripts/functions/filter-out
index 6c8b27a8..1fe4819d 100644
--- a/tests/scripts/functions/filter-out
+++ b/tests/scripts/functions/filter-out
@@ -1,6 +1,6 @@
# -*-perl-*-
-$description = "Test the filter-out function.";
+$description = "Test the filter and filter-out functions.";
$details = "The makefile created in this test has two variables. The
filter-out function is first used to discard names ending in
@@ -11,18 +11,32 @@ which is only used if there are multiple literals present in both
the pattern and text arguments. The result of both filter-out
functions is the same single .elc name.\n";
-open(MAKEFILE,"> $makefile");
+# Basic test -- filter
+run_make_test(q!
+files1 := $(filter %.o, foo.elc bar.o lose.o)
+files2 := $(filter %.o foo.i, foo.i bar.i lose.i foo.elc bar.o lose.o)
+all: ; @echo '$(files1) $(files2)'
+!,
+ '', "bar.o lose.o foo.i bar.o lose.o\n");
-print MAKEFILE <<'EOF';
+# Basic test -- filter-out
+run_make_test(q!
files1 := $(filter-out %.o, foo.elc bar.o lose.o)
files2 := $(filter-out foo.i bar.i lose.i %.o, foo.i bar.i lose.i foo.elc bar.o lose.o)
-all: ; @echo $(files1) $(files2)
-EOF
+all: ; @echo '$(files1) $(files2)'
+!,
+ '', "foo.elc foo.elc\n");
-close(MAKEFILE);
+# Escaped patterns
+run_make_test(q!all:;@echo '$(filter foo\%bar,foo%bar fooXbar)'!,
+ '', "foo%bar\n");
-&run_make_with_options($makefile, "", &get_logfile, 0);
-$answer = "foo.elc foo.elc\n";
-&compare_output($answer,&get_logfile(1));
+run_make_test(q!all:;@echo '$(filter foo\%\%\\\\\%\%bar,foo%%\\%%bar fooX\\Ybar)'!,
+ '', "foo%%\\%%bar\n");
+
+run_make_test(q!
+X = $(filter foo\\\\\%bar,foo\%bar foo\Xbar)
+all:;@echo '$(X)'!,
+ '', "foo\\%bar\n");
1;
diff --git a/tests/scripts/functions/foreach b/tests/scripts/functions/foreach
index 82e99d7b..4d1a11d1 100644
--- a/tests/scripts/functions/foreach
+++ b/tests/scripts/functions/foreach
@@ -1,5 +1,5 @@
# -*-perl-*-
-# $Id: foreach,v 1.5 2006/03/10 02:20:46 psmith Exp $
+# $Id$
$description = "Test the foreach function.";
@@ -62,7 +62,7 @@ y = $x
all: ; @echo $y',
'',
- "#MAKEFILE#:2: *** insufficient number of arguments (1) to function `foreach'. Stop.",
+ "#MAKEFILE#:2: *** insufficient number of arguments (1) to function 'foreach'. Stop.",
512);
run_make_test('
@@ -71,7 +71,7 @@ y := $x
all: ; @echo $y',
'',
- "#MAKEFILE#:2: *** insufficient number of arguments (1) to function `foreach'. Stop.",
+ "#MAKEFILE#:2: *** insufficient number of arguments (1) to function 'foreach'. Stop.",
512);
1;
diff --git a/tests/scripts/functions/guile b/tests/scripts/functions/guile
new file mode 100644
index 00000000..c63bec9b
--- /dev/null
+++ b/tests/scripts/functions/guile
@@ -0,0 +1,99 @@
+# -*-perl-*-
+
+$description = 'Test the $(guile ...) function.';
+
+$details = 'This only works on systems that support it.';
+
+# If this instance of make doesn't support GNU Guile, skip it
+# This detects if guile is loaded using the "load" directive
+# $makefile = get_tmpfile();
+# open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
+# print MAKEFILE q!
+# -load guile
+# all: ; @echo $(filter guile,$(.LOADED))
+# !;
+# close(MAKEFILE) || die "Failed to write $makefile: $!\n";
+# $cmd = subst_make_string("#MAKEPATH# -f $makefile");
+# $log = get_logfile(0);
+# $code = run_command_with_output($log, $cmd);
+# read_file_into_string ($log) eq "guile\n" and $FEATURES{guile} = 1;
+
+# If we don't have Guile support, never mind.
+exists $FEATURES{guile} or return -1;
+
+# Verify simple data type conversions
+# Currently we don't support vectors:
+# echo '$(guile (vector 1 2 3))'; \
+run_make_test(q!
+x:;@echo '$(guile #f)'; \
+ echo '$(guile #t)'; \
+ echo '$(guile #\c)'; \
+ echo '$(guile 1234)'; \
+ echo '$(guile 'foo)'; \
+ echo '$(guile "bar")'; \
+ echo '$(guile (cons 'a 'b))'; \
+ echo '$(guile '(a b (c . d) 1 (2) 3))'
+!,
+ '', "\n#t\nc\n1234\nfoo\nbar\na b\na b c d 1 2 3");
+
+# Verify the gmk-expand function
+run_make_test(q!
+VAR = $(guile (gmk-expand "$(shell echo hi)"))
+x:;@echo '$(VAR)'
+!,
+ '', "hi");
+
+# Verify the gmk-eval function
+# Prove that the string is expanded only once (by eval)
+run_make_test(q!
+TEST = bye
+EVAL = VAR = $(TEST) $(shell echo there)
+$(guile (gmk-eval "$(value EVAL)"))
+TEST = hi
+x:;@echo '$(VAR)'
+!,
+ '', "hi there");
+
+# Verify the gmk-eval function with a list
+run_make_test(q!
+$(guile (gmk-eval '(VAR = 1 (2) () 3)))
+x:;@echo '$(VAR)'
+!,
+ '', "1 2 3");
+
+# Verify the gmk-var function
+run_make_test(q!
+VALUE = hi $(shell echo there)
+VAR = $(guile (gmk-var "VALUE"))
+x:;@echo '$(VAR)'
+!,
+ '', "hi there");
+
+# Verify the gmk-var function with a symbol
+run_make_test(q!
+VALUE = hi $(shell echo there)
+VAR = $(guile (gmk-var 'VALUE))
+x:;@echo '$(VAR)'
+!,
+ '', "hi there");
+
+# Write a Guile program using define and run it
+run_make_test(q!
+# Define the "fib" function in Guile
+define fib
+;; A procedure for counting the n:th Fibonacci number
+;; See SICP, p. 37
+(define (fib n)
+ (cond ((= n 0) 0)
+ ((= n 1) 1)
+ (else (+ (fib (- n 1))
+ (fib (- n 2))))))
+endef
+$(guile $(fib))
+
+# Now run it
+x:;@echo $(guile (fib $(FIB)))
+!,
+ 'FIB=10', "55");
+
+1;
diff --git a/tests/scripts/functions/sort b/tests/scripts/functions/sort
index d472102d..b5589103 100644
--- a/tests/scripts/functions/sort
+++ b/tests/scripts/functions/sort
@@ -1,55 +1,47 @@
-$description = "The following test creates a makefile to verify\n"
- ."the ability of make to sort lists of object. Sort\n"
- ."will also remove any duplicate entries. This will also\n"
- ."be tested.";
-
-$details = "The make file is built with a list of object in a random order\n"
- ."and includes some duplicates. Make should sort all of the elements\n"
- ."remove all duplicates\n";
-
-open(MAKEFILE,"> $makefile");
-
-# The Contents of the MAKEFILE ...
-
-print MAKEFILE "foo := moon_light days \n"
- ."foo1:= jazz\n"
- ."bar := captured \n"
- ."bar2 = boy end, has rise A midnight \n"
- ."bar3:= \$(foo)\n"
- ."s1 := _by\n"
- ."s2 := _and_a\n"
- ."t1 := \$(addsuffix \$(s1), \$(bar) )\n"
- ."t2 := \$(addsuffix \$(s2), \$(foo1) )\n"
- ."t3 := \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \n"
- ."t4 := \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \n"
- ."t5 := \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \n"
- ."t6 := \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \n"
- ."t7 := \$(t6) \$(t6) \$(t6) \n"
- ."p1 := \$(addprefix \$(foo1), \$(s2) )\n"
- ."blank:= \n"
- ."all:\n"
- ."\t\@echo \$(sort \$(bar2) \$(foo) \$(addsuffix \$(s1), \$(bar) ) \$(t2) \$(bar2) \$(bar3))\n"
- ."\t\@echo \$(sort \$(blank) \$(foo) \$(bar2) \$(t1) \$(p1) )\n"
- ."\t\@echo \$(sort \$(foo) \$(bar2) \$(t1) \$(t4) \$(t5) \$(t7) \$(t6) )\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 = "A boy captured_by days end, has jazz_and_a midnight moon_light rise\n"
- ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n"
- ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n";
-
-&compare_output($answer,&get_logfile(1));
+# -*-perl-*-
+
+$description = "The following test creates a makefile to verify
+the ability of make to sort lists of object. Sort
+will also remove any duplicate entries. This will also
+be tested.";
+
+$details = "The make file is built with a list of object in a random order
+and includes some duplicates. Make should sort all of the elements
+remove all duplicates\n";
+
+run_make_test('
+foo := moon_light days
+foo1:= jazz
+bar := captured
+bar2 = boy end, has rise A midnight
+bar3:= $(foo)
+s1 := _by
+s2 := _and_a
+t1 := $(addsuffix $(s1), $(bar) )
+t2 := $(addsuffix $(s2), $(foo1) )
+t3 := $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2)
+t4 := $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3)
+t5 := $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4)
+t6 := $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5)
+t7 := $(t6) $(t6) $(t6)
+p1 := $(addprefix $(foo1), $(s2) )
+blank:=
+all:
+ @echo $(sort $(bar2) $(foo) $(addsuffix $(s1), $(bar) ) $(t2) $(bar2) $(bar3))
+ @echo $(sort $(blank) $(foo) $(bar2) $(t1) $(p1) )
+ @echo $(sort $(foo) $(bar2) $(t1) $(t4) $(t5) $(t7) $(t6) )
+',
+ '', 'A boy captured_by days end, has jazz_and_a midnight moon_light rise
+A boy captured_by days end, has jazz_and_a midnight moon_light rise
+A boy captured_by days end, has jazz_and_a midnight moon_light rise
+');
+
+
+# Test with non-space/tab whitespace. Note that you can't see the
+# original bug except using valgrind.
+
+run_make_test("FOO = a b\tc\rd\fe \f \f \f \f \ff
+all: ; \@echo \$(words \$(sort \$(FOO)))\n",
+ '', "5\n");
1;
-
-
-
-
-
-
diff --git a/tests/scripts/functions/wildcard b/tests/scripts/functions/wildcard
index 2841f5d5..bcd84ad7 100644
--- a/tests/scripts/functions/wildcard
+++ b/tests/scripts/functions/wildcard
@@ -88,4 +88,16 @@ all: ; @echo $(wildcard xz--y*.7)
!,
'', "\n");
+# TEST #5: wildcard used to verify file existence
+
+touch('xxx.yyy');
+
+run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!,
+ '', "file=xxx.yyy\n");
+
+unlink('xxx.yyy');
+
+run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!,
+ '', "file=\n");
+
1;
diff --git a/tests/scripts/functions/word b/tests/scripts/functions/word
index 34527ea7..4dcc9406 100644
--- a/tests/scripts/functions/word
+++ b/tests/scripts/functions/word
@@ -56,32 +56,32 @@ wordlist-e1: ; @echo $(wordlist ,,$(FOO))
wordlist-e2: ; @echo $(wordlist abc ,,$(FOO))
wordlist-e3: ; @echo $(wordlist 1, 12a ,$(FOO))',
'word-e1',
- "#MAKEFILE#:3: *** non-numeric first argument to `word' function: ''. Stop.",
+ "#MAKEFILE#:3: *** non-numeric first argument to 'word' function: ''. Stop.",
512);
run_make_test(undef,
'word-e2',
- "#MAKEFILE#:4: *** non-numeric first argument to `word' function: 'abc '. Stop.",
+ "#MAKEFILE#:4: *** non-numeric first argument to 'word' function: 'abc '. Stop.",
512);
run_make_test(undef,
'word-e3',
- "#MAKEFILE#:5: *** non-numeric first argument to `word' function: '1a'. Stop.",
+ "#MAKEFILE#:5: *** non-numeric first argument to 'word' function: '1a'. Stop.",
512);
run_make_test(undef,
'wordlist-e1',
- "#MAKEFILE#:7: *** non-numeric first argument to `wordlist' function: ''. Stop.",
+ "#MAKEFILE#:7: *** non-numeric first argument to 'wordlist' function: ''. Stop.",
512);
run_make_test(undef,
'wordlist-e2',
- "#MAKEFILE#:8: *** non-numeric first argument to `wordlist' function: 'abc '. Stop.",
+ "#MAKEFILE#:8: *** non-numeric first argument to 'wordlist' function: 'abc '. Stop.",
512);
run_make_test(undef,
'wordlist-e3',
- "#MAKEFILE#:9: *** non-numeric second argument to `wordlist' function: ' 12a '. Stop.",
+ "#MAKEFILE#:9: *** non-numeric second argument to 'wordlist' function: ' 12a '. Stop.",
512);
# Test error conditions again, but this time in a variable reference
@@ -94,37 +94,37 @@ WL = $(wordlist $s,$e,$(FOO))
word-e: ; @echo $(W)
wordlist-e: ; @echo $(WL)',
'word-e x=',
- "#MAKEFILE#:3: *** non-numeric first argument to `word' function: ''. Stop.",
+ "#MAKEFILE#:3: *** non-numeric first argument to 'word' function: ''. Stop.",
512);
run_make_test(undef,
'word-e x=abc',
- "#MAKEFILE#:3: *** non-numeric first argument to `word' function: 'abc'. Stop.",
+ "#MAKEFILE#:3: *** non-numeric first argument to 'word' function: 'abc'. Stop.",
512);
run_make_test(undef,
'word-e x=0',
- "#MAKEFILE#:3: *** first argument to `word' function must be greater than 0. Stop.",
+ "#MAKEFILE#:3: *** first argument to 'word' function must be greater than 0. Stop.",
512);
run_make_test(undef,
'wordlist-e s= e=',
- "#MAKEFILE#:4: *** non-numeric first argument to `wordlist' function: ''. Stop.",
+ "#MAKEFILE#:4: *** non-numeric first argument to 'wordlist' function: ''. Stop.",
512);
run_make_test(undef,
'wordlist-e s=abc e=',
- "#MAKEFILE#:4: *** non-numeric first argument to `wordlist' function: 'abc'. Stop.",
+ "#MAKEFILE#:4: *** non-numeric first argument to 'wordlist' function: 'abc'. Stop.",
512);
run_make_test(undef,
'wordlist-e s=4 e=12a',
- "#MAKEFILE#:4: *** non-numeric second argument to `wordlist' function: '12a'. Stop.",
+ "#MAKEFILE#:4: *** non-numeric second argument to 'wordlist' function: '12a'. Stop.",
512);
run_make_test(undef,
'wordlist-e s=0 e=12',
- "#MAKEFILE#:4: *** invalid first argument to `wordlist' function: `0'. Stop.",
+ "#MAKEFILE#:4: *** invalid first argument to 'wordlist' function: '0'. Stop.",
512);
diff --git a/tests/scripts/misc/bs-nl b/tests/scripts/misc/bs-nl
index 979abb5b..4fc3f639 100644
--- a/tests/scripts/misc/bs-nl
+++ b/tests/scripts/misc/bs-nl
@@ -50,27 +50,80 @@ run_make_test("squote:;\@echo 'squ\\\n\t\t ote'\n",
# Backslash-newlines in variable values
# Simple
-run_make_test("
-var = he\\\nllo
-var:;\@echo '|\$(var)|'",
+run_make_test(q!
+var = he\
+llo
+var:;@echo '|$(var)|'!,
'', "|he llo|");
-# Preserve preceding space
-run_make_test("
-var = he \\\nllo
-var:;\@echo '|\$(var)|'",
- '', "|he llo|");
+# Condense trailing space
+run_make_test(q!
+var = he \
+llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
# Remove leading space
-run_make_test("
-var = he\\\n llo
-var:;\@echo '|\$(var)|'",
+run_make_test(q!
+var = he\
+ llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
+
+# Multiple bs/nl condensed
+run_make_test(q!
+var = he\
+\
+\
+ llo
+var:;@echo '|$(var)|'!,
'', "|he llo|");
-# One space per bs-nl
-run_make_test("
-var = he\\\n\\\n\\\n llo
-var:;\@echo '|\$(var)|'",
+# POSIX: Preserve trailing space
+run_make_test(q!
+.POSIX:
+x = y
+var = he \
+llo
+var:;@echo '|$(var)|'!,
'', "|he llo|");
+# POSIX: One space per bs-nl
+run_make_test(q!
+.POSIX:
+x = y
+var = he\
+\
+\
+ llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
+
+# Savannah #39035: handle whitespace in call
+run_make_test(q!
+f = echo $(1)
+t:; @$(call f,"a \
+ b"); \
+ $(call f,"a \
+ b")
+!,
+ '', "a b\na b\n");
+
+# Savannah #38945: handle backslash CRLF
+# We need our own makefile so we can set binmode
+my $m1 = get_tmpfile();
+open(MAKEFILE, "> $m1");
+binmode(MAKEFILE);
+print MAKEFILE "FOO = foo \\\r\n";
+close(MAKEFILE);
+
+my $m2 = get_tmpfile();
+open(MAKEFILE, "> $m2");
+print MAKEFILE "include $m1\ndefine BAR\nall: ; \@echo \$(FOO) bar\nendef\n\$(eval \$(BAR))\n";
+close(MAKEFILE);
+
+run_make_with_options($m2, '', get_logfile());
+compare_output("foo bar\n", get_logfile(1));
+
+
1;
diff --git a/tests/scripts/misc/fopen-fail b/tests/scripts/misc/fopen-fail
new file mode 100644
index 00000000..6580e519
--- /dev/null
+++ b/tests/scripts/misc/fopen-fail
@@ -0,0 +1,15 @@
+# -*-perl-*-
+
+$description = "Make sure make exits with an error if fopen fails.";
+
+# Recurse infinitely until we run out of open files, and ensure we
+# fail with a non-zero exit code. Don't bother to test the output
+# since it's hard to know what it will be, exactly.
+# See Savannah bug #27374.
+
+run_make_test(q!
+include $(lastword $(MAKEFILE_LIST))
+!,
+ '', undef, 512);
+
+1;
diff --git a/tests/scripts/misc/general3 b/tests/scripts/misc/general3
index b3142c24..8ad0f8e2 100644
--- a/tests/scripts/misc/general3
+++ b/tests/scripts/misc/general3
@@ -26,7 +26,7 @@ TAB = \t \# A TAB and some spaces
\$(STR)
\$(STR) \$(TAB)",
- '', "#MAKE#: Nothing to be done for `all'.");
+ '', "#MAKE#: Nothing to be done for 'all'.");
# TEST 2
diff --git a/tests/scripts/misc/utf8 b/tests/scripts/misc/utf8
new file mode 100644
index 00000000..2adcd071
--- /dev/null
+++ b/tests/scripts/misc/utf8
@@ -0,0 +1,14 @@
+# -*-perl-*-
+$description = "Test utf8 handling.";
+
+$details = "";
+
+# Variable names containing UTF8 characters
+run_make_test("
+\xe2\x96\xaa := hello
+\$(info \$(\xe2\x96\xaa))
+all:
+",
+ '', "hello\n#MAKE#: Nothing to be done for 'all'.");
+
+1;
diff --git a/tests/scripts/options/dash-B b/tests/scripts/options/dash-B
index e36842e3..9c708b77 100644
--- a/tests/scripts/options/dash-B
+++ b/tests/scripts/options/dash-B
@@ -22,13 +22,13 @@ foo: bar.x
',
'', 'cp bar.x foo');
-run_make_test(undef, '', "#MAKE#: Nothing to be done for `all'.");
+run_make_test(undef, '', "#MAKE#: Nothing to be done for 'all'.");
run_make_test(undef, '-B', 'cp bar.x foo');
# Put the timestamp for foo into the future; it should still be remade.
utouch(1000, 'foo');
-run_make_test(undef, '', "#MAKE#: Nothing to be done for `all'.");
+run_make_test(undef, '', "#MAKE#: Nothing to be done for 'all'.");
run_make_test(undef, '-B', 'cp bar.x foo');
# Clean up
diff --git a/tests/scripts/options/dash-C b/tests/scripts/options/dash-C
index 5864ffd2..42d0a8ba 100644
--- a/tests/scripts/options/dash-C
+++ b/tests/scripts/options/dash-C
@@ -34,9 +34,9 @@ if (-f $example) {
}
# Create the answer to what should be produced by this Makefile
-$answer = "$make_name: Entering directory `$wpath'\n"
+$answer = "$make_name: Entering directory '$wpath'\n"
. "$delete_command EXAMPLE\n"
- . "$make_name: Leaving directory `$wpath'\n";
+ . "$make_name: Leaving directory '$wpath'\n";
&compare_output($answer,&get_logfile(1));
@@ -62,9 +62,9 @@ if (-f $example) {
}
# Create the answer to what should be produced by this Makefile
-$answer = "$make_name: Entering directory `$wpath'\n"
+$answer = "$make_name: Entering directory '$wpath'\n"
. "$delete_command EXAMPLEslash\n"
- . "$make_name: Leaving directory `$wpath'\n";
+ . "$make_name: Leaving directory '$wpath'\n";
&compare_output($answer,&get_logfile(1));
diff --git a/tests/scripts/options/dash-I b/tests/scripts/options/dash-I
index 8dc5d9ba..d47a8d8a 100644
--- a/tests/scripts/options/dash-I
+++ b/tests/scripts/options/dash-I
@@ -51,9 +51,9 @@ $answer = "This is another included makefile\n";
$answer = "$mkpath ANOTHER -f $makefile
-${make_name}[1]: Entering directory `$pwd'
+${make_name}[1]: Entering directory '$pwd'
This is another included makefile
-${make_name}[1]: Leaving directory `$pwd'\n";
+${make_name}[1]: Leaving directory '$pwd'\n";
&run_make_with_options($makefile,"-I $workdir recurse",&get_logfile);
&compare_output($answer,&get_logfile(1));
diff --git a/tests/scripts/options/dash-W b/tests/scripts/options/dash-W
index d3fde87c..20b9f745 100644
--- a/tests/scripts/options/dash-W
+++ b/tests/scripts/options/dash-W
@@ -12,7 +12,7 @@ a.x b.x: ; echo >> $@
# Run it again: nothing should happen
-run_make_test(undef, '', "#MAKE#: `a.x' is up to date.");
+run_make_test(undef, '', "#MAKE#: 'a.x' is up to date.");
# Now run it with -W b.x: should rebuild a.x
@@ -21,7 +21,7 @@ run_make_test(undef, '-W b.x', 'echo >> a.x');
# Put the timestamp for a.x into the future; it should still be remade.
utouch(1000, 'a.x');
-run_make_test(undef, '', "#MAKE#: `a.x' is up to date.");
+run_make_test(undef, '', "#MAKE#: 'a.x' is up to date.");
run_make_test(undef, '-W b.x', 'echo >> a.x');
# Clean up
diff --git a/tests/scripts/options/dash-k b/tests/scripts/options/dash-k
index d87a7861..e784e0db 100644
--- a/tests/scripts/options/dash-k
+++ b/tests/scripts/options/dash-k
@@ -57,10 +57,10 @@ else {
# Create the answer to what should be produced by this Makefile
$answer = "cc -c main.c
-$make_name: *** No rule to make target `kbd.c', needed by `kbd.o'.
+$make_name: *** No rule to make target 'kbd.c', needed by 'kbd.o'.
cc -c commands.c
cc -c display.c
-$make_name: Target `edit' not remade because of errors.\n";
+$make_name: Target 'edit' not remade because of errors.\n";
# COMPARE RESULTS
@@ -92,8 +92,9 @@ close(MAKEFILE);
&run_make_with_options($makefile2, "-k", &get_logfile, $error_code);
$answer = "exit 1
+$makefile2:9: recipe for target 'foo.o' failed
$make_name: *** [foo.o] Error 1
-$make_name: Target `all' not remade because of errors.\n";
+$make_name: Target 'all' not remade because of errors.\n";
&compare_output($answer, &get_logfile(1));
@@ -106,8 +107,8 @@ ifile: no-such-file; @false
',
'-k',
"#MAKEFILE#:2: ifile: No such file or directory
-#MAKE#: *** No rule to make target `no-such-file', needed by `ifile'.
-#MAKE#: Failed to remake makefile `ifile'.
+#MAKE#: *** No rule to make target 'no-such-file', needed by 'ifile'.
+#MAKE#: Failed to remake makefile 'ifile'.
hi\n",
512);
diff --git a/tests/scripts/options/dash-n b/tests/scripts/options/dash-n
index de19f42c..dfed419d 100644
--- a/tests/scripts/options/dash-n
+++ b/tests/scripts/options/dash-n
@@ -3,37 +3,24 @@ $description = "Test the -n option.\n";
$details = "Try various uses of -n and ensure they all give the correct results.\n";
-open(MAKEFILE, "> $makefile");
-
-# The Contents of the MAKEFILE ...
-
-print MAKEFILE <<'EOMAKE';
+touch('orig');
+run_make_test(q!
final: intermediate ; echo >> $@
intermediate: orig ; echo >> $@
-
-EOMAKE
-
-close(MAKEFILE);
-
-&touch('orig');
-
-# TEST 0
-
-&run_make_with_options($makefile, "", &get_logfile);
-$answer = "echo >> intermediate\necho >> final\n";
-&compare_output($answer, &get_logfile(1));
+!,
+ '', "echo >> intermediate\necho >> final\n");
# TEST 1
-&run_make_with_options($makefile, "-Worig -n", &get_logfile);
-$answer = "echo >> intermediate\necho >> final\n";
-&compare_output($answer, &get_logfile(1));
+run_make_test(undef, '-Worig -n', "echo >> intermediate\necho >> final\n");
-unlink('orig', 'intermediate', 'final');
+rmfiles(qw(orig intermediate final));
# We consider the actual updated timestamp of targets with all
-# recursive commands, even with -n.
+# recursive commands, even with -n. Switching this to the new model
+# is non-trivial because we use a trick below to change the log content
+# before we compare it ...
$makefile2 = &get_tmpfile;
@@ -56,15 +43,58 @@ close(MAKEFILE);
# TEST 2
&run_make_with_options($makefile2, "", &get_logfile);
-$answer = "$make_name: `a' is up to date.\n";
+$answer = "$make_name: 'a' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST 3
&run_make_with_options($makefile2, "-n", &get_logfile);
-$answer = "$make_name: `a' is up to date.\n";
+$answer = "$make_name: 'a' is up to date.\n";
+&compare_output($answer, &get_logfile(1));
+
+# TEST 4
+
+unlink(qw(a b));
+
+&run_make_with_options($makefile2, "-t -n", &get_logfile);
+
+open(DASH_N_LOG, ">>" . &get_logfile(1));
+print DASH_N_LOG "a exists but should not!\n" if -e 'a';
+print DASH_N_LOG "b exists but should not!\n" if -e 'b';
+close(DASH_N_LOG);
+
+&compare_output("touch b\ntouch a\n", &get_logfile(1));
+
+# CLEANUP
+
+unlink(qw(a b c));
+
+# Ensure -n continues to be included with recursive/re-execed make
+# See Savannah bug #38051
+
+$topmake = &get_tmpfile;
+$submake = &get_tmpfile;
+
+open(MAKEFILE, "> $topmake");
+print MAKEFILE <<"EOF";
+foo: ; \@\$(MAKE) -f "$submake" bar
+EOF
+close(MAKEFILE);
+
+
+# The bar target should print what would happen, but not actually run
+open(MAKEFILE, "> $submake");
+print MAKEFILE <<'EOF';
+inc: ; touch $@
+-include inc
+bar: ; @echo $(strip $(MAKEFLAGS))
+EOF
+close(MAKEFILE);
+
+&run_make_with_options($topmake, '-n --no-print-directory', &get_logfile);
+$answer = "$make_path -f \"$submake\" bar\ntouch inc\necho n --no-print-directory\n";
&compare_output($answer, &get_logfile(1));
-unlink('a', 'b', 'c');
+unlink('inc');
1;
diff --git a/tests/scripts/options/dash-q b/tests/scripts/options/dash-q
index 56f04a1f..194588d9 100644
--- a/tests/scripts/options/dash-q
+++ b/tests/scripts/options/dash-q
@@ -5,21 +5,21 @@ $details = "Try various uses of -q and ensure they all give the correct results.
# TEST 0
-run_make_test('
+run_make_test(qq!
one:
two: ;
three: ; :
-four: ; $(.XY)
-five: ; \
- $(.XY)
-six: ; \
- $(.XY)
- $(.XY)
-seven: ; \
- $(.XY)
- : foo
- $(.XY)
-',
+four: ; \$(.XY)
+five: ; \\
+ \$(.XY)
+six: ; \\
+ \$(.XY)
+\t\$(.XY)
+seven: ; \\
+ \$(.XY)
+\t: foo
+\t\$(.XY)
+!,
'-q one', '');
# TEST 1
@@ -54,4 +54,24 @@ one:: ; @echo two
',
'-q', '', 256);
+# TEST 7 : Savannah bug # 42249
+# Make sure we exit with 1 even for prerequisite updates
+run_make_test('
+build-stamp: ; echo $@
+build-arch: build-stamp
+build-x: build-arch
+build-y: build-x
+',
+ '-q build-y', '', 256);
+
+# TEST 8
+# Make sure we exit with 2 on error even with -q
+run_make_test('
+build-stamp: ; echo $@
+build-arch: build-stamp-2
+build-x: build-arch
+build-y: build-x
+',
+ '-q build-y', "#MAKE#: *** No rule to make target 'build-stamp-2', needed by 'build-arch'. Stop.\n", 512);
+
1;
diff --git a/tests/scripts/options/eval b/tests/scripts/options/eval
index 06a035c3..0f824090 100644
--- a/tests/scripts/options/eval
+++ b/tests/scripts/options/eval
@@ -16,4 +16,14 @@ recurse: ; @$(MAKE) -f #MAKEFILE# && echo recurse!,
run_make_test(undef, '--no-print-directory --eval=\$\(info\ eval\) recurse',
"eval\neval\nall\nrecurse");
+# Make sure that --eval is handled correctly during restarting
+run_make_test(q!
+all: ; @echo $@
+-include gen.mk
+gen.mk: ; @echo > $@
+!,
+ '--eval=\$\(info\ eval\)', "eval\neval\nall");
+
+unlink('gen.mk');
+
1;
diff --git a/tests/scripts/options/print-directory b/tests/scripts/options/print-directory
new file mode 100644
index 00000000..a05bbee7
--- /dev/null
+++ b/tests/scripts/options/print-directory
@@ -0,0 +1,33 @@
+# -*-perl-*-
+
+$description = "Test the -w option to GNU make.";
+
+# Simple test without -w
+run_make_test(q!
+all: ; @echo hi
+!,
+ "", "hi\n");
+
+# Simple test with -w
+run_make_test(undef, "-w",
+ "#MAKE#: Entering directory '#PWD#'\nhi\n#MAKE#: Leaving directory '#PWD#'\n");
+
+# Test makefile rebuild to ensure no enter/leave
+run_make_test(q!
+include foo
+all: ;@:
+foo: ; touch foo
+!,
+ "", "#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n");
+unlink('foo');
+
+# Test makefile rebuild with -w
+run_make_test(q!
+include foo
+all: ;@:
+foo: ; touch foo
+!,
+ "-w", "#MAKE#: Entering directory '#PWD#'\n#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n#MAKE#: Leaving directory '#PWD#'\n");
+unlink('foo');
+
+1;
diff --git a/tests/scripts/options/symlinks b/tests/scripts/options/symlinks
index 40d25648..a1bfce03 100644
--- a/tests/scripts/options/symlinks
+++ b/tests/scripts/options/symlinks
@@ -26,7 +26,7 @@ if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
# Without -L, nothing should happen
# With -L, it should update targ
run_make_test('targ: sym ; @echo make $@ from $<', '',
- "#MAKE#: `targ' is up to date.");
+ "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
# Now update dep; in all cases targ should be out of date.
@@ -36,8 +36,8 @@ if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
# Now update targ; in all cases targ should be up to date.
&touch('targ');
- run_make_test(undef, '', "#MAKE#: `targ' is up to date.");
- run_make_test(undef, '-L', "#MAKE#: `targ' is up to date.");
+ run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
+ run_make_test(undef, '-L', "#MAKE#: 'targ' is up to date.");
# Add in a new link between sym and dep. Be sure it's newer than targ.
sleep(1);
@@ -46,7 +46,7 @@ if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
# Without -L, nothing should happen
# With -L, it should update targ
- run_make_test(undef, '', "#MAKE#: `targ' is up to date.");
+ run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
rmfiles('targ', 'dep', 'sym', 'dep1');
@@ -56,7 +56,7 @@ if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
symlink("../$dirname/dep", 'sym');
run_make_test('targ: sym ; @echo make $@ from $<', '',
- "#MAKE#: *** No rule to make target `sym', needed by `targ'. Stop.", 512);
+ "#MAKE#: *** No rule to make target 'sym', needed by 'targ'. Stop.", 512);
run_make_test('targ: sym ; @echo make $@ from $<', '-L',
'make targ from sym');
diff --git a/tests/scripts/options/warn-undefined-variables b/tests/scripts/options/warn-undefined-variables
index 34bfaea4..ce15507d 100644
--- a/tests/scripts/options/warn-undefined-variables
+++ b/tests/scripts/options/warn-undefined-variables
@@ -18,8 +18,8 @@ all: ; @echo ref $(EREF) $(UREF)',
# With --warn-undefined-variables, it should warn me
run_make_test(undef, '--warn-undefined-variables',
- "#MAKEFILE#:7: warning: undefined variable `UNDEFINED'
-#MAKEFILE#:9: warning: undefined variable `UNDEFINED'
+ "#MAKEFILE#:7: warning: undefined variable 'UNDEFINED'
+#MAKEFILE#:9: warning: undefined variable 'UNDEFINED'
ref");
1;
diff --git a/tests/scripts/targets/DEFAULT b/tests/scripts/targets/DEFAULT
index 0cabde94..f3d51484 100644
--- a/tests/scripts/targets/DEFAULT
+++ b/tests/scripts/targets/DEFAULT
@@ -35,9 +35,9 @@ close(MAKEFILE);
&run_make_with_options($makefile,'bar',&get_logfile);
# Create the answer to what should be produced by this Makefile
-$answer = "${make_name}[1]: Entering directory `$pwd'\n"
+$answer = "${make_name}[1]: Entering directory '$pwd'\n"
. "Executing rule BAR\n"
- . "${make_name}[1]: Leaving directory `$pwd'\n";
+ . "${make_name}[1]: Leaving directory '$pwd'\n";
# COMPARE RESULTS
diff --git a/tests/scripts/targets/INTERMEDIATE b/tests/scripts/targets/INTERMEDIATE
index 4fdd7a2a..2b3021b2 100644
--- a/tests/scripts/targets/INTERMEDIATE
+++ b/tests/scripts/targets/INTERMEDIATE
@@ -42,7 +42,7 @@ $answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n";
# TEST #1
&run_make_with_options($makefile,'foo.d',&get_logfile);
-$answer = "$make_name: `foo.d' is up to date.\n";
+$answer = "$make_name: 'foo.d' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST #2
@@ -63,7 +63,7 @@ $answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm bar.e foo
# TEST #4
&run_make_with_options($makefile,'foo.c',&get_logfile);
-$answer = "$make_name: `foo.c' is up to date.\n";
+$answer = "$make_name: 'foo.c' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST #5
diff --git a/tests/scripts/targets/ONESHELL b/tests/scripts/targets/ONESHELL
index 997423f4..87713da4 100644
--- a/tests/scripts/targets/ONESHELL
+++ b/tests/scripts/targets/ONESHELL
@@ -4,6 +4,10 @@ $description = "Test the behaviour of the .ONESHELL target.";
$details = "";
+# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in
+# separate arguments.
+my $t = `/bin/sh -e -c true 2>/dev/null`;
+my $multi_ok = $? == 0;
# Simple
@@ -17,6 +21,21 @@ all:
[ 0"$a" -eq "$$" ] || echo fail
');
+# Simple but use multi-word SHELLFLAGS
+
+if ($multi_ok) {
+ run_make_test(q!
+.ONESHELL:
+.SHELLFLAGS = -e -c
+all:
+ a=$$$$
+ [ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+ '', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+}
+
# Again, but this time with inner prefix chars
run_make_test(q!
diff --git a/tests/scripts/targets/POSIX b/tests/scripts/targets/POSIX
index 9c30e181..a24e3bcf 100644
--- a/tests/scripts/targets/POSIX
+++ b/tests/scripts/targets/POSIX
@@ -1,6 +1,6 @@
# -*-perl-*-
-$description = "Test the behaviour of the .PHONY target.";
+$description = "Test the behaviour of the .POSIX target.";
$details = "";
@@ -17,7 +17,8 @@ run_make_test(qq!
.POSIX:
all: ; \@$script
!,
- '', "#MAKE#: *** [all] Error $err\n", 512);
+ '', "#MAKEFILE#:3: recipe for target 'all' failed
+#MAKE#: *** [all] Error $err\n", 512);
# User settings must override .POSIX
$flags = '-xc';
@@ -29,5 +30,28 @@ all: ; \@$script
!,
'', $out);
+# Test the default value of various POSIX-specific variables
+my %POSIX = (AR => 'ar', ARFLAGS => '-rv',
+ YACC => 'yacc', YFLAGS => '',
+ LEX => 'lex', LFLAGS => '',
+ LDFLAGS => '',
+ CC => 'c99', CFLAGS => '-O',
+ FC => 'fort77', FFLAGS => '-O 1',
+ GET => 'get', GFLAGS => '',
+ SCCSFLAGS => '', SCCSGETFLAGS => '-s');
+my $make = join('', map { "\t\@echo '$_=\$($_)'\n" } sort keys %POSIX);
+my $r = join('', map { "$_=$POSIX{$_}\n"} sort keys %POSIX);
+run_make_test(qq!
+.POSIX:
+all:
+$make
+!,
+ '', $r);
+
+# Make sure that local settings take precedence
+%extraENV = map { $_ => "xx-$_" } keys %POSIX;
+$r = join('', map { "$_=xx-$_\n"} sort keys %POSIX);
+run_make_test(undef, '', $r);
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/targets/SECONDARY b/tests/scripts/targets/SECONDARY
index c954ee9a..447c275e 100644
--- a/tests/scripts/targets/SECONDARY
+++ b/tests/scripts/targets/SECONDARY
@@ -44,7 +44,7 @@ $answer = "cp foo.f foo.e\ncp foo.e foo.d\n";
unlink('foo.e');
&run_make_with_options($makefile,'foo.d',&get_logfile);
-$answer = "$make_name: `foo.d' is up to date.\n";
+$answer = "$make_name: 'foo.d' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST #3
@@ -67,7 +67,7 @@ $answer = "cp foo.e foo.c\n";
unlink('foo.e');
&run_make_with_options($makefile,'foo.c',&get_logfile);
-$answer = "$make_name: `foo.c' is up to date.\n";
+$answer = "$make_name: 'foo.c' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST #6
@@ -103,7 +103,7 @@ close(MAKEFILE);
touch('final');
&run_make_with_options($makefile2, '', &get_logfile);
-$answer = "$make_name: `final' is up to date.\n";
+$answer = "$make_name: 'final' is up to date.\n";
&compare_output($answer, &get_logfile(1));
unlink('source', 'final', 'intermediate');
@@ -129,10 +129,11 @@ touch(qw(1.a 2.a));
run_make_test('
%.c : %.b ; cp $< $@
%.b : %.a ; cp $< $@
-all : 1.c 2.c', '-rR -j',
+all : 1.c 2.c
+2.a: 1.c', '-rR -j',
'cp 1.a 1.b
-cp 2.a 2.b
cp 1.b 1.c
+cp 2.a 2.b
cp 2.b 2.c
rm 1.b 2.b');
diff --git a/tests/scripts/variables/DEFAULT_GOAL b/tests/scripts/variables/DEFAULT_GOAL
index 1c065067..8188ce71 100644
--- a/tests/scripts/variables/DEFAULT_GOAL
+++ b/tests/scripts/variables/DEFAULT_GOAL
@@ -42,7 +42,7 @@ run_make_test('
.DEFAULT_GOAL = foo
',
'',
-'#MAKE#: *** No rule to make target `foo\'. Stop.',
+"#MAKE#: *** No rule to make target 'foo'. Stop.",
512);
diff --git a/tests/scripts/variables/GNUMAKEFLAGS b/tests/scripts/variables/GNUMAKEFLAGS
new file mode 100644
index 00000000..6e507949
--- /dev/null
+++ b/tests/scripts/variables/GNUMAKEFLAGS
@@ -0,0 +1,42 @@
+# -*-perl-*-
+
+$description = "Test proper behavior of GNUMAKEFLAGS";
+
+# Accept flags from GNUMAKEFLAGS as well as MAKEFLAGS
+# Results always go in MAKEFLAGS
+
+$extraENV{'GNUMAKEFLAGS'} = '-e -r -R';
+
+run_make_test(q!
+all: ; @echo $(MAKEFLAGS)
+!,
+ '', 'erR');
+
+# Long arguments mean everything is prefixed with "-"
+
+$extraENV{'GNUMAKEFLAGS'} = '--no-print-directory -e -r -R --trace';
+
+run_make_test(q!
+all: ; @echo $(MAKEFLAGS)
+!,
+ '', "#MAKEFILE#:2: target 'all' does not exist
+echo erR --trace --no-print-directory
+erR --trace --no-print-directory");
+
+# Verify that re-exec / recursion doesn't duplicate flags from GNUMAKEFLAGS
+
+unlink('x.mk');
+
+$extraENV{GNUMAKEFLAGS} = '-Itst/bad';
+
+run_make_test(q!
+recurse: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS; #MAKEPATH# -f #MAKEFILE# all
+all: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS
+-include x.mk
+x.mk: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS; echo > $@
+!,
+ "", "x.mk\nMAKEFLAGS = -Itst/bad\nGNUMAKEFLAGS =\nrecurse\nMAKEFLAGS = -Itst/bad\nGNUMAKEFLAGS =\n#MAKE#[1]: Entering directory '#PWD#'\nall\nMAKEFLAGS = w -Itst/bad\nGNUMAKEFLAGS =\n#MAKE#[1]: Leaving directory '#PWD#'\n");
+
+unlink('x.mk');
+
+1;
diff --git a/tests/scripts/variables/LIBPATTERNS b/tests/scripts/variables/LIBPATTERNS
index 826f2fa0..91829544 100644
--- a/tests/scripts/variables/LIBPATTERNS
+++ b/tests/scripts/variables/LIBPATTERNS
@@ -20,7 +20,7 @@ run_make_test('
.LIBPATTERNS = mtest_foo.a mtest_%.a
all: -lfoo ; @echo "build $@ from $<"
',
- '', "#MAKE#: .LIBPATTERNS element `mtest_foo.a' is not a pattern
+ '', "#MAKE#: .LIBPATTERNS element 'mtest_foo.a' is not a pattern
build all from mtest_foo.a\n");
# TEST 2: target-specific override
diff --git a/tests/scripts/variables/MAKE b/tests/scripts/variables/MAKE
index d1081dac..dc621606 100644
--- a/tests/scripts/variables/MAKE
+++ b/tests/scripts/variables/MAKE
@@ -16,8 +16,8 @@ foo:
!,
'',
"#MAKEPATH#\n#MAKEPATH# -f #MAKEFILE# foo\n"
- . "#MAKE#[1]: Entering directory `#PWD#'\n"
- . "#MAKEPATH#\n#MAKE#[1]: Leaving directory `#PWD#'\n");
+ . "#MAKE#[1]: Entering directory '#PWD#'\n"
+ . "#MAKEPATH#\n#MAKE#[1]: Leaving directory '#PWD#'\n");
rmfiles("foo");
diff --git a/tests/scripts/variables/MAKEFLAGS b/tests/scripts/variables/MAKEFLAGS
index 0b567e8f..8a5d0f6a 100644
--- a/tests/scripts/variables/MAKEFLAGS
+++ b/tests/scripts/variables/MAKEFLAGS
@@ -1,4 +1,4 @@
-# -*-perl-*-
+# -*-perl-*-
$description = "Test proper behavior of MAKEFLAGS";
@@ -8,36 +8,34 @@ $details = "DETAILS";
run_make_test(q!
all: ; @echo $(MAKEFLAGS)
!,
- '-e -r -R', 'Rre');
+ '-e -r -R', 'erR');
# Long arguments mean everything is prefixed with "-"
run_make_test(q!
all: ; @echo $(MAKEFLAGS)
!,
- '--no-print-directory -e -r -R', '--no-print-directory -Rre');
+ '--no-print-directory -e -r -R --trace', "#MAKEFILE#:2: target 'all' does not exist
+echo erR --trace --no-print-directory
+erR --trace --no-print-directory");
-if ($all_tests) {
- # Recursive invocations of make should accumulate MAKEFLAGS values.
- # Savannah bug #2216
- run_make_test(q!
+# Recursive invocations of make should accumulate MAKEFLAGS values.
+# Savannah bug #2216
+run_make_test(q!
MSG = Fails
all:
@echo '$@: MAKEFLAGS=$(MAKEFLAGS)'
@MSG=Works $(MAKE) -e -f #MAKEFILE# jump
jump:
- @echo '$@: MAKEFLAGS=$(MAKEFLAGS)'
+ @echo '$@ $(MSG): MAKEFLAGS=$(MAKEFLAGS)'
@$(MAKE) -f #MAKEFILE# print
print:
- @echo '$@: MAKEFLAGS=$(MAKEFLAGS)'
- @echo $(MSG)
+ @echo '$@ $(MSG): MAKEFLAGS=$(MAKEFLAGS)'
.PHONY: all jump print
!,
'--no-print-directory',
'all: MAKEFLAGS= --no-print-directory
-jump: MAKEFLAGS= --no-print-directory -e
-print: MAKEFLAGS= --no-print-directory -e
-Works');
-}
+jump Works: MAKEFLAGS=e --no-print-directory
+print Works: MAKEFLAGS=e --no-print-directory');
1;
diff --git a/tests/scripts/variables/MAKE_RESTARTS b/tests/scripts/variables/MAKE_RESTARTS
index 53ab7386..ef8e368f 100644
--- a/tests/scripts/variables/MAKE_RESTARTS
+++ b/tests/scripts/variables/MAKE_RESTARTS
@@ -52,10 +52,10 @@ MAKE_RESTARTS=1
foo.x:1: bar.x: No such file or directory
MAKE_RESTARTS=2
recurse MAKE_RESTARTS=
+#MAKE#[1]: Entering directory '#PWD#'
MAKE_RESTARTS=
-#MAKE#[1]: Entering directory `#PWD#'
all MAKE_RESTARTS=
-#MAKE#[1]: Leaving directory `#PWD#'");
+#MAKE#[1]: Leaving directory '#PWD#'");
rmfiles('foo.x', 'bar.x');
diff --git a/tests/scripts/variables/SHELL b/tests/scripts/variables/SHELL
index 7b7e7fef..1d01ba3f 100644
--- a/tests/scripts/variables/SHELL
+++ b/tests/scripts/variables/SHELL
@@ -70,6 +70,22 @@ all: ; \@$script
!,
'', $out);
+# Do it again but add spaces to SHELLFLAGS
+
+# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in
+# separate arguments.
+my $t = `/bin/sh -e -c true 2>/dev/null`;
+my $multi_ok = $? == 0;
+
+if ($multi_ok) {
+ $flags = '-x -c';
+ run_make_test(qq!
+.SHELLFLAGS = $flags
+all: ; \@$script
+!,
+ '', $out);
+}
+
# We can't just use "false" because on different systems it provides a
# different exit code--once again Solaris: false exits with 255 not 1
$script = 'true; false; true';
@@ -81,6 +97,7 @@ run_make_test(qq!
.SHELLFLAGS = $flags
all: ; \@$script
!,
- '', "$out#MAKE#: *** [all] Error $err\n", 512);
+ '', "$out#MAKEFILE#:3: recipe for target 'all' failed
+#MAKE#: *** [all] Error $err\n", 512);
1;
diff --git a/tests/scripts/variables/define b/tests/scripts/variables/define
index f91519e3..7324cbc7 100644
--- a/tests/scripts/variables/define
+++ b/tests/scripts/variables/define
@@ -30,6 +30,10 @@ define simple :=
@echo $(FOO)
endef
+define posix ::=
+@echo $(FOO)
+endef
+
append = @echo a
define append +=
@@ -49,10 +53,54 @@ FOO = there
all: ; $(multi)
$(simple)
+ $(posix)
+ $(append)
+ $(cond)
+',
+ '', "echo hi\nhi\nthere\nfoo\nfoo\na\nb\nfirst\n");
+
+# TEST 1a: Various new-style define/endef, with no spaces
+
+run_make_test('
+FOO = foo
+
+define multi=
+echo hi
+@echo $(FOO)
+endef # this is the end
+
+define simple:=
+@echo $(FOO)
+endef
+
+define posix::=
+@echo $(FOO)
+endef
+
+append = @echo a
+
+define append+=
+
+@echo b
+endef
+
+define cond?= # this is a conditional
+@echo first
+endef
+
+define cond?=
+@echo second
+endef
+
+FOO = there
+
+all: ; $(multi)
+ $(simple)
+ $(posix)
$(append)
$(cond)
',
- '', "echo hi\nhi\nthere\nfoo\na\nb\nfirst\n");
+ '', "echo hi\nhi\nthere\nfoo\nfoo\na\nb\nfirst\n");
# TEST 2: define in true section of conditional (containing conditional)
@@ -112,7 +160,7 @@ ouch
endef
all: ; @echo ok
',
- '', "#MAKEFILE#:3: extraneous text after `define' directive\nok\n");
+ '', "#MAKEFILE#:3: extraneous text after 'define' directive\nok\n");
# TEST 7: NEGATIVE: extra text after endef
@@ -123,7 +171,7 @@ ouch
endef $(NAME)
all: ; @echo ok
',
- '', "#MAKEFILE#:5: extraneous text after `endef' directive\nok\n");
+ '', "#MAKEFILE#:5: extraneous text after 'endef' directive\nok\n");
# TEST 8: NEGATIVE: missing endef
@@ -134,7 +182,7 @@ define NAME =
ouch
endef$(NAME)
',
- '', "#MAKEFILE#:4: *** missing `endef', unterminated `define'. Stop.\n", 512);
+ '', "#MAKEFILE#:4: *** missing 'endef', unterminated 'define'. Stop.\n", 512);
# -------------------------
# Make sure that prefix characters apply properly to define/endef values.
diff --git a/tests/scripts/variables/flavors b/tests/scripts/variables/flavors
index 92feed6e..ba133ea8 100644
--- a/tests/scripts/variables/flavors
+++ b/tests/scripts/variables/flavors
@@ -73,4 +73,24 @@ all: ; @echo $(foo)
',
'', "Hello\n");
+# TEST 6: Simple using POSIX syntax
+run_make_test('
+bar = Goodbye
+foo ::= $(bar)
+bar = ${ugh}
+ugh = Hello
+all: ; @echo $(foo)
+',
+ '', "Goodbye\n");
+
+# TEST 7: POSIX syntax no spaces
+run_make_test('
+bar = Goodbye
+foo::=$(bar)
+bar = ${ugh}
+ugh = Hello
+all: ; @echo $(foo)
+',
+ '', "Goodbye\n");
+
1;
diff --git a/tests/scripts/variables/private b/tests/scripts/variables/private
index b4baf5f2..8967ffb5 100644
--- a/tests/scripts/variables/private
+++ b/tests/scripts/variables/private
@@ -75,4 +75,48 @@ a b: ; @echo $@=$(private)
',
'', "b=a\na=a\n");
+# 9: make sure private suppresses inheritance
+run_make_test(q!
+DEFS = FOO
+all: bar1
+bar1: private DEFS += 1
+bar3: private DEFS += 3
+bar1: bar2
+bar2: bar3
+bar1 bar2 bar3: ; @echo '$@: $(DEFS)'
+!,
+ '', "bar3: FOO 3\nbar2: FOO\nbar1: FOO 1\n");
+
+# 10: Test append with pattern-specific variables and private
+
+run_make_test(q!
+IA = global
+PA = global
+PS = global
+S = global
+PS = global
+SV = global
+b%: IA += b%
+b%: private PA += b%
+b%: private PS = b%
+bar: all
+bar: IA += bar
+bar: private PA += bar
+bar: private PS = bar
+a%: IA += a%
+a%: private PA += a%
+a%: private PS = a%
+all: IA += all
+all: private PA += all
+all: private PS = all
+
+bar all: ; @echo '$@: IA=$(IA)'; echo '$@: PA=$(PA)'; echo '$@: PS=$(PS)'
+!,
+ '', "all: IA=global b% bar a% all
+all: PA=global a% all
+all: PS=all
+bar: IA=global b% bar
+bar: PA=global b% bar
+bar: PS=bar\n");
+
1;
diff --git a/tests/scripts/variables/special b/tests/scripts/variables/special
index a1e15c22..a5ab93aa 100644
--- a/tests/scripts/variables/special
+++ b/tests/scripts/variables/special
@@ -53,7 +53,7 @@ all:
# Test the .RECIPEPREFIX variable
&run_make_test('
define foo
-: foo-one \
+: foo-one\
foo-two
: foo-three
: foo-four
@@ -114,4 +114,28 @@ reset-four \
: foo-three
: foo-four');
+# Test that the "did you mean TAB" message is printed properly
+
+run_make_test(q!
+$x.
+!,
+ '', '#MAKEFILE#:2: *** missing separator. Stop.', 512);
+
+run_make_test(q!
+foo:
+ bar
+!,
+ '', '#MAKEFILE#:3: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.', 512);
+
+run_make_test(q!
+.RECIPEPREFIX = :
+foo:
+ bar
+!,
+ '', '#MAKEFILE#:4: *** missing separator. Stop.', 512);
+
1;
+
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End:
diff --git a/tests/test_driver.pl b/tests/test_driver.pl
index dec869d8..91141eb4 100644
--- a/tests/test_driver.pl
+++ b/tests/test_driver.pl
@@ -5,9 +5,7 @@
# Written 91-12-02 through 92-01-01 by Stephen McGee.
# Modified 92-02-11 through 92-02-22 by Chris Arthur to further generalize.
#
-# Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-# 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1991-2014 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -30,7 +28,7 @@
# this routine controls the whole mess; each test suite sets up a few
# variables and then calls &toplevel, which does all the real work.
-# $Id: test_driver.pl,v 1.30 2010/07/28 05:39:50 psmith Exp $
+# $Id$
# The number of test categories we've run
@@ -50,9 +48,9 @@ $tests_passed = 0;
# Yeesh. This whole test environment is such a hack!
$test_passed = 1;
-
# Timeout in seconds. If the test takes longer than this we'll fail it.
$test_timeout = 5;
+$test_timeout = 10 if $^O eq 'VMS';
# Path to Perl
$perl_name = $^X;
@@ -64,19 +62,67 @@ $perl_name = $^X;
# These are RESET AFTER EVERY TEST!
%extraENV = ();
+sub vms_get_process_logicals {
+ # Sorry for the long note here, but to keep this test running on
+ # VMS, it is needed to be understood.
+ #
+ # Perl on VMS by default maps the %ENV array to the system wide logical
+ # name table.
+ #
+ # This is a very large dynamically changing table.
+ # On Linux, this would be the equivalent of a table that contained
+ # every mount point, temporary pipe, and symbolic link on every
+ # file system. You normally do not have permission to clear or replace it,
+ # and if you did, the results would be catastrophic.
+ #
+ # On VMS, added/changed %ENV items show up in the process logical
+ # name table. So to track changes, a copy of it needs to be captured.
+
+ my $raw_output = `show log/process/access_mode=supervisor`;
+ my @raw_output_lines = split('\n',$raw_output);
+ my %log_hash;
+ foreach my $line (@raw_output_lines) {
+ if ($line =~ /^\s+"([A-Za-z\$_]+)"\s+=\s+"(.+)"$/) {
+ $log_hash{$1} = $2;
+ }
+ }
+ return \%log_hash
+}
+
# %origENV is the caller's original environment
-%origENV = %ENV;
+if ($^O ne 'VMS') {
+ %origENV = %ENV;
+} else {
+ my $proc_env = vms_get_process_logicals;
+ %origENV = %{$proc_env};
+}
sub resetENV
{
# We used to say "%ENV = ();" but this doesn't work in Perl 5.000
# through Perl 5.004. It was fixed in Perl 5.004_01, but we don't
# want to require that here, so just delete each one individually.
- foreach $v (keys %ENV) {
- delete $ENV{$v};
+
+ if ($^O ne 'VMS') {
+ foreach $v (keys %ENV) {
+ delete $ENV{$v};
+ }
+
+ %ENV = %makeENV;
+ } else {
+ my $proc_env = vms_get_process_logicals();
+ my %delta = %{$proc_env};
+ foreach my $v (keys %delta) {
+ if (exists $origENV{$v}) {
+ if ($origENV{$v} ne $delta{$v}) {
+ $ENV{$v} = $origENV{$v};
+ }
+ } else {
+ delete $ENV{$v};
+ }
+ }
}
- %ENV = %makeENV;
foreach $v (keys %extraENV) {
$ENV{$v} = $extraENV{$v};
delete $extraENV{$v};
@@ -89,6 +135,7 @@ sub toplevel
foreach (# UNIX-specific things
'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH',
+ 'LD_LIBRARY_PATH',
# Purify things
'PURIFYOPTIONS',
# Windows NT-specific stuff
@@ -106,7 +153,7 @@ sub toplevel
# Replace the environment with the new one
#
- %origENV = %ENV;
+ %origENV = %ENV unless $^O eq 'VMS';
resetENV();
@@ -131,7 +178,7 @@ sub toplevel
&parse_command_line (@ARGV);
- print "OS name = `$osname'\n" if $debug;
+ print "OS name = '$osname'\n" if $debug;
$workpath = "$cwdslash$workdir";
$scriptpath = "$cwdslash$scriptdir";
@@ -140,6 +187,25 @@ sub toplevel
&print_banner;
+ if ($osname eq 'VMS' && $cwdslash eq "")
+ {
+ # Porting this script to VMS revealed a small bug in opendir() not
+ # handling search lists correctly when the directory only exists in
+ # one of the logical_devices. Need to find the first directory in
+ # the search list, as that is where things will be written to.
+ my @dirs = split("/", $pwd);
+
+ my $logical_device = $ENV{$dirs[1]};
+ if ($logical_device =~ /([A-Za-z0-9_]+):(:?.+:)+/)
+ {
+ # A search list was found. Grab the first logical device
+ # and use it instead of the search list.
+ $dirs[1]=$1;
+ my $lcl_pwd = join('/', @dirs);
+ $workpath = $lcl_pwd . '/' . $workdir
+ }
+ }
+
if (-d $workpath)
{
print "Clearing $workpath...\n";
@@ -166,7 +232,7 @@ sub toplevel
$dir = $1;
push (@rmdirs, $dir);
-d "$workpath/$dir"
- || mkdir ("$workpath/$dir", 0777)
+ || mkdir ("$workpath/$dir", 0777)
|| &error ("Couldn't mkdir $workpath/$dir: $!\n");
}
}
@@ -175,23 +241,25 @@ sub toplevel
{
print "Finding tests...\n";
opendir (SCRIPTDIR, $scriptpath)
- || &error ("Couldn't opendir $scriptpath: $!\n");
+ || &error ("Couldn't opendir $scriptpath: $!\n");
@dirs = grep (!/^(\..*|CVS|RCS)$/, readdir (SCRIPTDIR) );
closedir (SCRIPTDIR);
foreach $dir (@dirs)
{
next if ($dir =~ /^(\..*|CVS|RCS)$/ || ! -d "$scriptpath/$dir");
push (@rmdirs, $dir);
+ # VMS can have overlayed file systems, so directories may repeat.
+ next if -d "$workpath/$dir";
mkdir ("$workpath/$dir", 0777)
- || &error ("Couldn't mkdir $workpath/$dir: $!\n");
+ || &error ("Couldn't mkdir $workpath/$dir: $!\n");
opendir (SCRIPTDIR, "$scriptpath/$dir")
- || &error ("Couldn't opendir $scriptpath/$dir: $!\n");
+ || &error ("Couldn't opendir $scriptpath/$dir: $!\n");
@files = grep (!/^(\..*|CVS|RCS|.*~)$/, readdir (SCRIPTDIR) );
closedir (SCRIPTDIR);
foreach $test (@files)
{
-d $test and next;
- push (@TESTS, "$dir/$test");
+ push (@TESTS, "$dir/$test");
}
}
}
@@ -203,7 +271,7 @@ sub toplevel
print "\n";
- &run_each_test;
+ run_all_tests();
foreach $dir (@rmdirs)
{
@@ -221,7 +289,7 @@ sub toplevel
print "s" unless $total_tests_failed == 1;
print " in $categories_failed Categor";
print ($categories_failed == 1 ? "y" : "ies");
- print " Failed (See .$diffext files in $workdir dir for details) :-(\n\n";
+ print " Failed (See .$diffext* files in $workdir dir for details) :-(\n\n";
return 0;
}
else
@@ -240,6 +308,13 @@ sub get_osname
# Set up an initial value. In perl5 we can do it the easy way.
$osname = defined($^O) ? $^O : '';
+ if ($osname eq 'VMS')
+ {
+ $vos = 0;
+ $pathsep = "/";
+ return;
+ }
+
# Find a path to Perl
# See if the filesystem supports long file names with multiple
@@ -276,15 +351,15 @@ sub get_osname
eval "chop (\$osname = `sh -c 'uname -nmsr 2>&1'`)";
if ($osname =~ /not found/i)
{
- $osname = "(something posixy with no uname)";
+ $osname = "(something posixy with no uname)";
}
elsif ($@ ne "" || $?)
{
eval "chop (\$osname = `sh -c 'uname -a 2>&1'`)";
if ($@ ne "" || $?)
{
- $osname = "(something posixy)";
- }
+ $osname = "(something posixy)";
+ }
}
$vos = 0;
$pathsep = "/";
@@ -416,128 +491,138 @@ sub print_banner
print "\n";
}
-sub run_each_test
+sub run_all_tests
{
- $categories_run = 0;
+ $categories_run = 0;
+
+ $lasttest = '';
+ foreach $testname (sort @TESTS) {
+ # Skip duplicates on VMS caused by logical name search lists.
+ next if $testname eq $lasttest;
+ $lasttest = $testname;
+ $suite_passed = 1; # reset by test on failure
+ $num_of_logfiles = 0;
+ $num_of_tmpfiles = 0;
+ $description = "";
+ $details = "";
+ $old_makefile = undef;
+ $testname =~ s/^$scriptpath$pathsep//;
+ $perl_testname = "$scriptpath$pathsep$testname";
+ $testname =~ s/(\.pl|\.perl)$//;
+ $testpath = "$workpath$pathsep$testname";
+ # Leave enough space in the extensions to append a number, even
+ # though it needs to fit into 8+3 limits.
+ if ($short_filenames) {
+ $logext = 'l';
+ $diffext = 'd';
+ $baseext = 'b';
+ $runext = 'r';
+ $extext = '';
+ } else {
+ $logext = 'log';
+ $diffext = 'diff';
+ $baseext = 'base';
+ $runext = 'run';
+ $extext = '.';
+ }
+ $extext = '_' if $^O eq 'VMS';
+ $log_filename = "$testpath.$logext";
+ $diff_filename = "$testpath.$diffext";
+ $base_filename = "$testpath.$baseext";
+ $run_filename = "$testpath.$runext";
+ $tmp_filename = "$testpath.$tmpfilesuffix";
- foreach $testname (sort @TESTS)
- {
- ++$categories_run;
- $suite_passed = 1; # reset by test on failure
- $num_of_logfiles = 0;
- $num_of_tmpfiles = 0;
- $description = "";
- $details = "";
- $old_makefile = undef;
- $testname =~ s/^$scriptpath$pathsep//;
- $perl_testname = "$scriptpath$pathsep$testname";
- $testname =~ s/(\.pl|\.perl)$//;
- $testpath = "$workpath$pathsep$testname";
- # Leave enough space in the extensions to append a number, even
- # though it needs to fit into 8+3 limits.
- if ($short_filenames) {
- $logext = 'l';
- $diffext = 'd';
- $baseext = 'b';
- $runext = 'r';
- $extext = '';
- } else {
- $logext = 'log';
- $diffext = 'diff';
- $baseext = 'base';
- $runext = 'run';
- $extext = '.';
- }
- $log_filename = "$testpath.$logext";
- $diff_filename = "$testpath.$diffext";
- $base_filename = "$testpath.$baseext";
- $run_filename = "$testpath.$runext";
- $tmp_filename = "$testpath.$tmpfilesuffix";
+ setup_for_test();
- &setup_for_test; # suite-defined
+ $output = "........................................................ ";
- $output = "........................................................ ";
+ substr($output,0,length($testname)) = "$testname ";
- substr($output,0,length($testname)) = "$testname ";
+ print $output;
- print $output;
+ $tests_run = 0;
+ $tests_passed = 0;
- # Run the actual test!
- $tests_run = 0;
- $tests_passed = 0;
+ # Run the test!
+ $code = do $perl_testname;
- $code = do $perl_testname;
+ ++$categories_run;
+ $total_tests_run += $tests_run;
+ $total_tests_passed += $tests_passed;
- $total_tests_run += $tests_run;
- $total_tests_passed += $tests_passed;
+ # How did it go?
+ if (!defined($code)) {
+ # Failed to parse or called die
+ if (length ($@)) {
+ warn "\n*** Test died ($testname): $@\n";
+ } else {
+ warn "\n*** Couldn't parse $perl_testname\n";
+ }
+ $status = "FAILED ($tests_passed/$tests_run passed)";
+ }
- # How did it go?
- if (!defined($code))
- {
- $suite_passed = 0;
- if (length ($@)) {
- warn "\n*** Test died ($testname): $@\n";
- } else {
- warn "\n*** Couldn't run $perl_testname\n";
- }
- }
- elsif ($code == -1) {
- $suite_passed = 0;
- }
- elsif ($code != 1 && $code != -1) {
- $suite_passed = 0;
- warn "\n*** Test returned $code\n";
- }
+ elsif ($code == -1) {
+ # Skipped... not supported
+ $status = "N/A";
+ --$categories_run;
+ }
- if ($suite_passed) {
- ++$categories_passed;
- $status = "ok ($tests_passed passed)";
- for ($i = $num_of_tmpfiles; $i; $i--)
- {
- &rmfiles ($tmp_filename . &num_suffix ($i) );
- }
+ elsif ($code != 1) {
+ # Bad result... this shouldn't really happen. Usually means that
+ # the suite forgot to end with "1;".
+ warn "\n*** Test returned $code\n";
+ $status = "FAILED ($tests_passed/$tests_run passed)";
+ }
- for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--)
- {
- &rmfiles ($log_filename . &num_suffix ($i) );
- &rmfiles ($base_filename . &num_suffix ($i) );
- }
- }
- elsif (!defined $code || $code > 0) {
- $status = "FAILED ($tests_passed/$tests_run passed)";
- }
- elsif ($code < 0) {
- $status = "N/A";
- --$categories_run;
- }
+ elsif ($tests_run == 0) {
+ # Nothing was done!!
+ $status = "FAILED (no tests found!)";
+ }
- # If the verbose option has been specified, then a short description
- # of each test is printed before displaying the results of each test
- # describing WHAT is being tested.
+ elsif ($tests_run > $tests_passed) {
+ # Lose!
+ $status = "FAILED ($tests_passed/$tests_run passed)";
+ }
- if ($verbose)
- {
- if ($detail)
- {
- print "\nWHAT IS BEING TESTED\n";
- print "--------------------";
- }
- print "\n\n$description\n\n";
- }
+ else {
+ # Win!
+ ++$categories_passed;
+ $status = "ok ($tests_passed passed)";
+
+ # Clean up
+ for ($i = $num_of_tmpfiles; $i; $i--) {
+ rmfiles($tmp_filename . num_suffix($i));
+ }
+ for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--) {
+ rmfiles($log_filename . num_suffix($i));
+ rmfiles($base_filename . num_suffix($i));
+ }
+ }
- # If the detail option has been specified, then the details of HOW
- # the test is testing what it says it is testing in the verbose output
- # will be displayed here before the results of the test are displayed.
+ # If the verbose option has been specified, then a short description
+ # of each test is printed before displaying the results of each test
+ # describing WHAT is being tested.
- if ($detail)
- {
- print "\nHOW IT IS TESTED\n";
- print "----------------";
- print "\n\n$details\n\n";
- }
+ if ($verbose) {
+ if ($detail) {
+ print "\nWHAT IS BEING TESTED\n";
+ print "--------------------";
+ }
+ print "\n\n$description\n\n";
+ }
- print "$status\n";
- }
+ # If the detail option has been specified, then the details of HOW
+ # the test is testing what it says it is testing in the verbose output
+ # will be displayed here before the results of the test are displayed.
+
+ if ($detail) {
+ print "\nHOW IT IS TESTED\n";
+ print "----------------";
+ print "\n\n$details\n\n";
+ }
+
+ print "$status\n";
+ }
}
# If the keep flag is not set, this subroutine deletes all filenames that
@@ -654,38 +739,158 @@ sub compare_output
local($answer,$logfile) = @_;
local($slurp, $answer_matched) = ('', 0);
- print "Comparing Output ........ " if $debug;
-
- $slurp = &read_file_into_string ($logfile);
-
- # For make, get rid of any time skew error before comparing--too bad this
- # has to go into the "generic" driver code :-/
- $slurp =~ s/^.*modification time .*in the future.*\n//gm;
- $slurp =~ s/^.*Clock skew detected.*\n//gm;
-
++$tests_run;
- if ($slurp eq $answer) {
- $answer_matched = 1;
+ if (! defined $answer) {
+ print "Ignoring output ........ " if $debug;
+ $answer_matched = 1;
} else {
- # See if it is a slash or CRLF problem
- local ($answer_mod, $slurp_mod) = ($answer, $slurp);
-
- $answer_mod =~ tr,\\,/,;
- $answer_mod =~ s,\r\n,\n,gs;
+ print "Comparing Output ........ " if $debug;
- $slurp_mod =~ tr,\\,/,;
- $slurp_mod =~ s,\r\n,\n,gs;
+ $slurp = &read_file_into_string ($logfile);
- $answer_matched = ($slurp_mod eq $answer_mod);
+ # For make, get rid of any time skew error before comparing--too bad this
+ # has to go into the "generic" driver code :-/
+ $slurp =~ s/^.*modification time .*in the future.*\n//gm;
+ $slurp =~ s/^.*Clock skew detected.*\n//gm;
- # If it still doesn't match, see if the answer might be a regex.
- if (!$answer_matched && $answer =~ m,^/(.+)/$,) {
- $answer_matched = ($slurp =~ /$1/);
- if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) {
- $answer_matched = ($slurp_mod =~ /$1/);
+ if ($slurp eq $answer) {
+ $answer_matched = 1;
+ } else {
+ # See if it is a slash or CRLF problem
+ local ($answer_mod, $slurp_mod) = ($answer, $slurp);
+
+ $answer_mod =~ tr,\\,/,;
+ $answer_mod =~ s,\r\n,\n,gs;
+
+ $slurp_mod =~ tr,\\,/,;
+ $slurp_mod =~ s,\r\n,\n,gs;
+
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ if ($^O eq 'VMS') {
+
+ # VMS has extra blank lines in output sometimes.
+ # Ticket #41760
+ if (!$answer_matched) {
+ $slurp_mod =~ s/\n\n+/\n/gm;
+ $slurp_mod =~ s/\A\n+//g;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+
+ # VMS adding a "Waiting for unfinished jobs..."
+ # Remove it for now to see what else is going on.
+ if (!$answer_matched) {
+ $slurp_mod =~ s/^.+\*\*\* Waiting for unfinished jobs.+$//m;
+ $slurp_mod =~ s/\n\n/\n/gm;
+ $slurp_mod =~ s/^\n+//gm;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+
+ # VMS wants target device to exist or generates an error,
+ # Some test tagets look like VMS devices and trip this.
+ if (!$answer_matched) {
+ $slurp_mod =~ s/^.+\: no such device or address.*$//gim;
+ $slurp_mod =~ s/\n\n/\n/gm;
+ $slurp_mod =~ s/^\n+//gm;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+
+ # VMS error message has a different case
+ if (!$answer_matched) {
+ $slurp_mod =~ s/no such file /No such file /gm;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+
+ # VMS is putting comas instead of spaces in output
+ if (!$answer_matched) {
+ $slurp_mod =~ s/,/ /gm;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+
+ # VMS Is sometimes adding extra leading spaces to output?
+ if (!$answer_matched) {
+ my $slurp_mod = $slurp_mod;
+ $slurp_mod =~ s/^ +//gm;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+
+ # VMS port not handling POSIX encoded child status
+ # Translate error case it for now.
+ if (!$answer_matched) {
+ $slurp_mod =~ s/0x1035a00a/1/gim;
+ $answer_matched = 1 if $slurp_mod =~ /\Q$answer_mod\E/i;
+
+ }
+ if (!$answer_matched) {
+ $slurp_mod =~ s/0x1035a012/2/gim;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+
+ # Tests are using a UNIX null command, temp hack
+ # until this can be handled by the VMS port.
+ # ticket # 41761
+ if (!$answer_matched) {
+ $slurp_mod =~ s/^.+DCL-W-NOCOMD.*$//gim;
+ $slurp_mod =~ s/\n\n+/\n/gm;
+ $slurp_mod =~ s/^\n+//gm;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+ # Tests are using exit 0;
+ # this generates a warning that should stop the make, but does not
+ if (!$answer_matched) {
+ $slurp_mod =~ s/^.+NONAME-W-NOMSG.*$//gim;
+ $slurp_mod =~ s/\n\n+/\n/gm;
+ $slurp_mod =~ s/^\n+//gm;
+ $answer_matched = ($slurp_mod eq $answer_mod);
+ }
+
+ # VMS is sometimes adding single quotes to output?
+ if (!$answer_matched) {
+ my $noq_slurp_mod = $slurp_mod;
+ $noq_slurp_mod =~ s/\'//gm;
+ $answer_matched = ($noq_slurp_mod eq $answer_mod);
+
+ # And missing an extra space in output
+ if (!$answer_matched) {
+ $noq_answer_mod = $answer_mod;
+ $noq_answer_mod =~ s/\h\h+/ /gm;
+ $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
+ }
+
+ # VMS adding ; to end of some lines.
+ if (!$answer_matched) {
+ $noq_slurp_mod =~ s/;\n/\n/gm;
+ $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
+ }
+
+ # VMS adding trailing space to end of some quoted lines.
+ if (!$answer_matched) {
+ $noq_slurp_mod =~ s/\h+\n/\n/gm;
+ $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
+ }
+
+ # And VMS missing leading blank line
+ if (!$answer_matched) {
+ $noq_answer_mod =~ s/\A\n//g;
+ $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
+ }
+
+ # Unix double quotes showing up as single quotes on VMS.
+ if (!$answer_matched) {
+ $noq_answer_mod =~ s/\"//g;
+ $answer_matched = ($noq_slurp_mod eq $noq_answer_mod);
+ }
+ }
+ }
+
+ # If it still doesn't match, see if the answer might be a regex.
+ if (!$answer_matched && $answer =~ m,^/(.+)/$,) {
+ $answer_matched = ($slurp =~ /$1/);
+ if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) {
+ $answer_matched = ($slurp_mod =~ /$1/);
+ }
+ }
}
- }
}
if ($answer_matched && $test_passed)
@@ -707,11 +912,8 @@ sub compare_output
local($command) = "diff -c " . &get_basefile . " " . $logfile;
&run_command_with_output(&get_difffile,$command);
- } else {
- &rmfiles ();
}
- $suite_passed = 0;
return 0;
}
@@ -731,6 +933,9 @@ sub read_file_into_string
return $slurp;
}
+my @OUTSTACK = ();
+my @ERRSTACK = ();
+
sub attach_default_output
{
local ($filename) = @_;
@@ -743,17 +948,16 @@ sub attach_default_output
return 1;
}
- open ("SAVEDOS" . $default_output_stack_level . "out", ">&STDOUT")
- || &error ("ado: $! duping STDOUT\n", 1);
- open ("SAVEDOS" . $default_output_stack_level . "err", ">&STDERR")
- || &error ("ado: $! duping STDERR\n", 1);
+ my $dup = undef;
+ open($dup, '>&', STDOUT) or error("ado: $! duping STDOUT\n", 1);
+ push @OUTSTACK, $dup;
- open (STDOUT, "> " . $filename)
- || &error ("ado: $filename: $!\n", 1);
- open (STDERR, ">&STDOUT")
- || &error ("ado: $filename: $!\n", 1);
+ $dup = undef;
+ open($dup, '>&', STDERR) or error("ado: $! duping STDERR\n", 1);
+ push @ERRSTACK, $dup;
- $default_output_stack_level++;
+ open(STDOUT, '>', $filename) or error("ado: $filename: $!\n", 1);
+ open(STDERR, ">&STDOUT") or error("ado: $filename: $!\n", 1);
}
# close the current stdout/stderr, and restore the previous ones from
@@ -770,23 +974,14 @@ sub detach_default_output
return 1;
}
- if (--$default_output_stack_level < 0)
- {
- &error ("default output stack has flown under!\n", 1);
- }
+ @OUTSTACK or error("default output stack has flown under!\n", 1);
- close (STDOUT);
- close (STDERR);
+ close(STDOUT);
+ close(STDERR) unless $^O eq 'VMS';
- open (STDOUT, ">&SAVEDOS" . $default_output_stack_level . "out")
- || &error ("ddo: $! duping STDOUT\n", 1);
- open (STDERR, ">&SAVEDOS" . $default_output_stack_level . "err")
- || &error ("ddo: $! duping STDERR\n", 1);
- close ("SAVEDOS" . $default_output_stack_level . "out")
- || &error ("ddo: $! closing SCSDOSout\n", 1);
- close ("SAVEDOS" . $default_output_stack_level . "err")
- || &error ("ddo: $! closing SAVEDOSerr\n", 1);
+ open (STDOUT, '>&', pop @OUTSTACK) or error("ddo: $! duping STDOUT\n", 1);
+ open (STDERR, '>&', pop @ERRSTACK) or error("ddo: $! duping STDERR\n", 1);
}
# This runs a command without any debugging info.
@@ -800,14 +995,44 @@ sub _run_command
resetENV();
eval {
- local $SIG{ALRM} = sub { die "timeout\n"; };
- alarm $test_timeout;
- $code = system(@_);
+ if ($^O eq 'VMS') {
+ local $SIG{ALRM} = sub {
+ my $e = $ERRSTACK[0];
+ print $e "\nTest timed out after $test_timeout seconds\n";
+ die "timeout\n"; };
+# alarm $test_timeout;
+ system(@_);
+ my $severity = ${^CHILD_ERROR_NATIVE} & 7;
+ $code = 0;
+ if (($severity & 1) == 0) {
+ $code = 512;
+ }
+
+ # Get the vms status.
+ my $vms_code = ${^CHILD_ERROR_NATIVE};
+
+ # Remove the print status bit
+ $vms_code &= ~0x10000000;
+
+ # Posix code translation.
+ if (($vms_code & 0xFFFFF000) == 0x35a000) {
+ $code = (($vms_code & 0xFFF) >> 3) * 256;
+ }
+ } else {
+ my $pid = fork();
+ if (! $pid) {
+ exec(@_) or die "Cannot execute $_[0]\n";
+ }
+ local $SIG{ALRM} = sub { my $e = $ERRSTACK[0]; print $e "\nTest timed out after $test_timeout seconds\n"; die "timeout\n"; };
+ alarm $test_timeout;
+ waitpid($pid, 0) > 0 or die "No such pid: $pid\n";
+ $code = $?;
+ }
alarm 0;
};
if ($@) {
# The eval failed. If it wasn't SIGALRM then die.
- $@ eq "timeout\n" or die;
+ $@ eq "timeout\n" or die "Command failed: $@";
# Timed out. Resend the alarm to our process group to kill the children.
$SIG{ALRM} = 'IGNORE';
@@ -826,7 +1051,7 @@ sub run_command
print "\nrun_command: @_\n" if $debug;
my $code = _run_command(@_);
print "run_command returned $code.\n" if $debug;
-
+ print "vms status = ${^CHILD_ERROR_NATIVE}\n" if $debug and $^O eq 'VMS';
return $code;
}
@@ -841,10 +1066,14 @@ sub run_command_with_output
print "\nrun_command_with_output($filename,$runname): @_\n" if $debug;
&attach_default_output ($filename);
- my $code = _run_command(@_);
+ my $code = eval { _run_command(@_) };
+ my $err = $@;
&detach_default_output;
- print "run_command_with_output returned $code.\n" if $debug;
+ $err and die $err;
+
+ print "run_command_with_output returned $code.\n" if $debug;
+ print "vms status = ${^CHILD_ERROR_NATIVE}\n" if $debug and $^O eq 'VMS';
return $code;
}
@@ -904,7 +1133,15 @@ sub remove_directory_tree_inner
}
else
{
- unlink $object || return 0;
+ if ($^O ne 'VMS')
+ {
+ unlink $object || return 0;
+ }
+ else
+ {
+ # VMS can have multiple versions of a file.
+ 1 while unlink $object;
+ }
}
}
closedir ($dirhandle);
@@ -942,7 +1179,7 @@ sub touch
foreach $file (@_) {
(open(T, ">> $file") && print(T "\n") && close(T))
- || &error("Couldn't touch $file: $!\n", 1);
+ || &error("Couldn't touch $file: $!\n", 1);
}
}