2008-01-29 Eric Blake <ebb9@byu.net>
+ Fix more autotest regressions.
+ * lib/autotest/general.m4 (AT_LINE): Fix regression from
+ 2007-10-04 when file name is `dnl'.
+ (AT_INIT) <PREPARE_TESTS>: Move command-line assignments...
+ <TESTS_BEGIN>: ...to this new diversion, to fix regression from
+ yesterday in libtool's testsuite.
+ (_AT_ARG_OPTION): Detect write failure.
+ * doc/autoconf.texi (Diversion support): Document PREPARE_TESTS to
+ make libtool's use kosher. Document m4_init.
+ (Programming in M4sh): Document AS_INIT.
+ (Writing Testsuites): Document limitation of AT_DATA file name.
+ * tests/autotest.at (unusual file names): New test.
+ (Banners, Keywords and ranges): Use correct shell.
+
More corner cases in testsuite VAR=VALUE handling.
* lib/autotest/general.m4 (AT_INIT) <PREPARE_TESTS): Fix quoting
bug.
diversions. Rather than using diversion numbers directly, it is nicer
to associate a name with each diversion; the diversion number associated
with a particular diversion name is an implementation detail, so you
-should only use diversion names.
+should only use diversion names. In general, you should not output text
+to a named diversion until after calling the appropriate initialization
+routine for your language (@code{m4_init}, @code{AS_INIT},
+@code{AT_INIT}, @dots{}), although there are some exceptions documented
+below.
M4sugar defines two named diversions.
@table @code
diversion once M4sh is initialized.
@end table
-For now, the named diversions of Autoconf, Autoheader, and Autotest are
-not documented.
+Autotest inherits diversions from M4sh, and changes the default
+diversion from @code{BODY} back to @code{KILL}. It also adds several
+more named diversions, with the following subset designed for developer
+use.
+@table @code
+@item PREPARE_TESTS
+This diversion contains initialization sequences which are executed
+after @file{atconfig} and @file{atlocal}, and after all command line
+arguments have been parsed, but prior to running any tests. It can be
+used to set up state that is required across all tests. This diversion
+will work even before @code{AT_INIT}.
+@end table
+
+For now, the named diversions of Autoconf and Autoheader, and the
+remaining diversions of Autotest, are not documented. In other words,
+intentionally outputting text into an undocumented diversion is subject
+to breakage in a future release of Autoconf.
@defmac m4_divert_once (@var{diversion}, @ovar{content})
@msindex{divert_once}
@end example
@end defmac
+@defmac m4_init
+@msindex{init}
+Initialize the M4sugar environment, setting up the default named
+diversion to be @code{KILL}.
+@end defmac
+
@node Conditional constructs
@subsection Conditional constructs
are expanded before the first test.
@end defmac
+@defmac AS_INIT
+@asindex{INIT}
+Initialize the M4sh environment. This macro calls @code{m4_init}, then
+outputs the @code{#! /bin/sh} line, a notice about where the output was
+generated from, and code to sanitize the environment for the rest of the
+script. Finally, it changes the current diversion to @code{BODY}.
+@end defmac
+
@defmac AS_MKDIR_P (@var{file-name})
@asindex{MKDIR_P}
Make the directory @var{file-name}, including intervening directories
Initialize an input data @var{file} with given @var{contents}. Of
course, the @var{contents} have to be properly quoted between square
brackets to protect against included commas or spurious M4
-expansion. The contents ought to end with an end of line.
+expansion. The contents must end with an end of line. @var{file} must
+be a single shell word that expands into a single file name.
@end defmac
@defmac AT_CHECK (@var{commands}, @dvar{status, 0}, @dvar{stdout, }, @
#
# - BANNERS
# Output shell initialization for the associative array of banner text.
-# - PREPARE_TESTS
+# - TESTS_BEGIN
# Like DEFAULTS but run after argument processing for purposes of
# optimization. Do anything else that needs to be done to prepare for
# tests. Sets up verbose and log file descriptors. Sets and logs PATH.
-# Declares functions shared among the tests.
+# - PREPARE_TESTS
+# Declares functions shared among the tests. Perform any user
+# initialization to be shared among all tests.
# - TESTS
# The core of the test suite.
#
m4_define([_m4_divert(VERSION_NOTICES)], 351)
m4_define([_m4_divert(VERSION_END)], 352)
m4_define([_m4_divert(BANNERS)], 400)
-m4_define([_m4_divert(PREPARE_TESTS)], 401)
-m4_define([_m4_divert(TESTS)], 402)
+m4_define([_m4_divert(TESTS_BEGIN)], 401)
+m4_define([_m4_divert(PREPARE_TESTS)], 402)
+m4_define([_m4_divert(TESTS)], 403)
m4_define([_m4_divert(TEST_SCRIPT)], 450)
m4_define([_m4_divert(TEST_GROUPS)], 500)
[m4_if(m4_defn([_AT_LINE_file]), __file__, [],
[m4_do([m4_define([_AT_LINE_file], __file__)],
[m4_define([_AT_LINE_base],
- m4_bpatsubst(__file__, [^.*/\([^/]*\)$],
- [[\1]]))])])dnl
+ m4_bregexp(/__file__, [/\([^/]*\)$], [[\1]]))])])dnl
m4_defn([_AT_LINE_base]):__line__])
exit $at_write_fail
fi
m4_divert_pop([VERSION_END])dnl
-m4_divert_push([PREPARE_TESTS])dnl
+m4_divert_push([TESTS_BEGIN])dnl
# Take any -C into account.
if $at_change_dir ; then
sed 's/^/| /' $at_file
echo
done
+} >&AS_MESSAGE_LOG_FD
+m4_divert_pop([TESTS_BEGIN])dnl
+m4_divert_push([PREPARE_TESTS])dnl
+{
AS_BOX([Tested programs.])
echo
} >&AS_MESSAGE_LOG_FD
# Internal implementation of AT_ARG_OPTION & AT_ARG_OPTION_ARG
m4_defun([_AT_ARG_OPTION],
[m4_divert_once([HELP_OTHER],
-[cat <<_ATEOF
+[cat <<_ATEOF || at_write_fail=1
Other options:
_ATEOF
])dnl m4_divert_once HELP_OTHER
m4_divert_text([HELP_OTHER],
-[cat <<_ATEOF
+[cat <<_ATEOF || at_write_fail=1
$2
_ATEOF])dnl
dnl Turn our options into our desired strings
# AT_CHECK_BANNERS(TESTSUITE-OPTIONS, PATTERN1, COUNT1, PATTERN2, COUNT2)
m4_define([AT_CHECK_BANNERS],
-[AT_CHECK([./b $1], [], [stdout])
+[AT_CHECK([$CONFIG_SHELL ./b $1], [], [stdout])
AT_CHECK_EGREP([$2], m4_if([$3], [0], [1], [0]), [$3])
AT_CHECK_EGREP([$4], m4_if([$5], [0], [1], [0]), [$5])
])
dnl check that AT_KEYWORDS does not duplicate words
AT_CHECK([grep 'key1.*key1' k], [1])
dnl check that -k requires an argument
-AT_CHECK([./k -k], [1], [], [ignore])
+AT_CHECK([$CONFIG_SHELL ./k -k], [1], [], [ignore])
# AT_CHECK_KEYS(TESTSUITE-OPTIONS, PATTERN1, COUNT1, PATTERN2, COUNT2)
m4_define([AT_CHECK_KEYS],
-[AT_CHECK([./k $1], 0, [stdout])
+[AT_CHECK([$CONFIG_SHELL ./k $1], 0, [stdout])
AT_CHECK_EGREP([$2], 0, [$3])
AT_CHECK_EGREP([$4], 1, [$5])
])
AT_CHECK_KEYS([4-], [both], [1], [none|first|second], [0])
AT_CHECK_KEYS([-k second 4-], [second|both], [2], [none|first], [0])
-AT_CHECK([./k 0], [1], [ignore], [ignore])
-AT_CHECK([./k 0-], [1], [ignore], [ignore])
-AT_CHECK([./k -0], [1], [ignore], [ignore])
-AT_CHECK([./k 5], [1], [ignore], [ignore])
-AT_CHECK([./k 5-], [1], [ignore], [ignore])
-AT_CHECK([./k 1-5], [1], [ignore], [ignore])
-AT_CHECK([./k -k nonexistent], [0], [ignore])
+AT_CHECK([$CONFIG_SHELL ./k 0], [1], [ignore], [ignore])
+AT_CHECK([$CONFIG_SHELL ./k 0-], [1], [ignore], [ignore])
+AT_CHECK([$CONFIG_SHELL ./k -0], [1], [ignore], [ignore])
+AT_CHECK([$CONFIG_SHELL ./k 5], [1], [ignore], [ignore])
+AT_CHECK([$CONFIG_SHELL ./k 5-], [1], [ignore], [ignore])
+AT_CHECK([$CONFIG_SHELL ./k 1-5], [1], [ignore], [ignore])
+AT_CHECK([$CONFIG_SHELL ./k -k nonexistent], [0], [ignore])
AT_CHECK_KEYS([--list -k nonexistent], [KEYWORDS], [1], [first|second|both], [0])
AT_CHECK_KEYS([--list 1], [none], [1], [first|second|both], [0])
AT_CHECK([top_srcdir=$wd ./suite -d], [0], [ignore])
AT_CHECK([cd suite.dir/1 && ./run top_srcdir="$wd"], [0], [ignore])
AT_CLEANUP
+
+
+## ------------------ ##
+## unusual file names ##
+## ------------------ ##
+
+AT_SETUP([unusual file names])
+AT_KEYWORDS([autotest])
+
+AT_DATA_M4SUGAR([d@&t@nl.at],
+[[AT_SETUP([test one])
+m4_pattern_allow([^dnl$])
+AT_CHECK([test "]m4_dquote(AT_LINE)[" = dn[]l.at:3])
+AT_CLEANUP
+]])
+
+mkdir sub
+AT_DATA_M4SUGAR([sub/"two spaces".at],
+[[AT_SETUP([test two])
+AT_CHECK([test "]m4_dquote(AT_LINE)[" = "two spaces.at:2"])
+AT_CLEANUP
+]])
+
+AT_DATA([suite.at],
+[[m4_define([AT_PACKAGE_NAME], [GNU Nonsense])
+m4_define([AT_PACKAGE_TARNAME], [nonsense])
+m4_define([AT_PACKAGE_VERSION], [1.0])
+m4_define([AT_PACKAGE_STRING], [GNU Nonsense 1.0])
+m4_define([AT_PACKAGE_BUGREPORT], [bug-autoconf@gnu.org])
+AT_INIT([suite to check included file names])
+m4@&t@_include([d][nl.at])
+m4@&t@_include([sub/two spaces.at])
+]])
+AT_CHECK_AUTOM4TE([--language=autotest -o suite suite.at])
+AT_CHECK([$CONFIG_SHELL ./suite], [0], [ignore])
+AT_CLEANUP