Ingo Weinhold 939977cf72 Merged autoconf 2.61 into trunk.
git-svn-id: file:///srv/svn/repos/haiku/buildtools/trunk@24464 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-03-19 12:42:05 +00:00

1524 lines
48 KiB
Plaintext

# This file is part of Autoconf. -*- Autoconf -*-
# M4 macros used in building test suites.
# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
# Foundation, Inc.
# This program 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 2, or (at your option)
# any later version.
#
# This program 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception, the Free Software Foundation gives unlimited
# permission to copy, distribute and modify the configure scripts that
# are the output of Autoconf. You need not follow the terms of the GNU
# General Public License when using or distributing such scripts, even
# though portions of the text of Autoconf appear in them. The GNU
# General Public License (GPL) does govern all other use of the material
# that constitutes the Autoconf program.
#
# Certain portions of the Autoconf source text are designed to be copied
# (in certain cases, depending on the input) into the output of
# Autoconf. We call these the "data" portions. The rest of the Autoconf
# source text consists of comments plus executable code that decides which
# of the data portions to output in any given case. We call these
# comments and executable code the "non-data" portions. Autoconf never
# copies any of the non-data portions into its output.
#
# This special exception to the GPL applies to versions of Autoconf
# released by the Free Software Foundation. When you make and
# distribute a modified version of Autoconf, you may extend this special
# exception to the GPL to apply to your modified version as well, *unless*
# your modified version has the potential to copy into its output some
# of the text that was the non-data portion of the version that you started
# with. (In other words, unless your change moves or copies text from
# the non-data portions to the data portions.) If your modification has
# such potential, you must delete any notice of this special exception
# to the GPL from your modified version.
# _m4_divert(DIVERSION-NAME)
# --------------------------
# Convert a diversion name into its number. Otherwise, return
# DIVERSION-NAME which is supposed to be an actual diversion number.
# Of course it would be nicer to use m4_case here, instead of zillions
# of little macros, but it then takes twice longer to run `autoconf'!
#
# From M4sugar:
# -1. KILL
# 10000. GROW
#
# From M4sh:
# 0. BINSH
# 1. HEADER-REVISION
# 2. HEADER-COMMENT
# 3. HEADER-COPYRIGHT
# 4. M4SH-SANITIZE
# 5. M4SH-INIT
# 1000. BODY
#
# Defined below:
# - DEFAULTS
# Overall initialization, value of $at_groups_all.
# - PARSE_ARGS_BEGIN
# Setup defaults required for option processing.
# - PARSE_ARGS
# Option processing. After AT_INIT, user options can be entered here as
# cases of a case statement.
# - PARSE_ARGS_END
# Finish up the option processing.
#
# - HELP
# Start printing the help message.
# - HELP_MODES
# Modes help text. Additional modes can be appended as self-contained
# cat'd here-docs as generated by AS_HELP_STRING.
# - HELP_TUNING
# Tuning help text. Additional tuning options can be appended as
# self-contained cat'd here-docs as generated by AS_HELP_STRING.
# - HELP_OTHER
# User help can be appended to this as self-contained cat'd here-docs.
# - HELP_END
# Finish up the help texts.
#
# - VERSION
# Head of the handling of --version.
# - VERSION_NOTICES
# Copyright notices for --version.
# - VERSION_END
# Tail of the handling of --version.
#
# - PREPARE_TESTS
# 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.
# - TESTS
# The core of the test suite.
# - TESTS_END
# tail of the core for;case, overall wrap up, generation of debugging
# scripts and statistics.
# - TEST_SCRIPT
# The code for each test, the ``normal'' diversion
m4_define([_m4_divert(DEFAULTS)], 100)
m4_define([_m4_divert(PARSE_ARGS_BEGIN)], 200)
m4_define([_m4_divert(PARSE_ARGS)], 201)
m4_define([_m4_divert(PARSE_ARGS_END)], 202)
m4_define([_m4_divert(HELP)], 300)
m4_define([_m4_divert(HELP_MODES)], 301)
m4_define([_m4_divert(HELP_TUNING)], 302)
m4_define([_m4_divert(HELP_OTHER)], 303)
m4_define([_m4_divert(HELP_END)], 304)
m4_define([_m4_divert(VERSION)], 350)
m4_define([_m4_divert(VERSION_NOTICES)], 351)
m4_define([_m4_divert(VERSION_END)], 352)
m4_define([_m4_divert(PREPARE_TESTS)], 400)
m4_define([_m4_divert(TESTS)], 401)
m4_define([_m4_divert(TESTS_END)], 402)
m4_define([_m4_divert(TEST_SCRIPT)], 403)
# AT_LINE
# -------
# Return the current file sans directory, a colon, and the current
# line. Be sure to return a _quoted_ file name, so if, for instance,
# the user is lunatic enough to have a file named `dnl' (and I, for
# one, love to be brainless and stubborn sometimes), then we return a
# quoted name.
#
# Gee, we can't use simply
#
# m4_bpatsubst(__file__, [^.*/\(.*\)], [[\1]])
#
# since then, since `dnl' doesn't match the pattern, it is returned
# with once quotation level less, so you lose! And since GNU M4
# is one of the biggest junk in the whole universe wrt regexp, don't
# even think about using `?' or `\?'. Bah, `*' will do.
# Pleeeeeeeease, Gary, provide us with dirname and ERE!
m4_define([AT_LINE],
[m4_bpatsubst(__file__, [^\(.*/\)*\(.*\)], [[\2]]):__line__])
# _AT_NORMALIZE_TEST_GROUP_NUMBER(SHELL-VAR)
# ------------------------------------------
# Normalize SHELL-VAR so that its value has the same number of digits as
# all the other test group numbers.
m4_define([_AT_NORMALIZE_TEST_GROUP_NUMBER],
[
while :; do
case $$1 in #(
$at_format*) break;;
esac
$1=0$$1
done
])
# _AT_CREATE_DEBUGGING_SCRIPT
# ---------------------------
# Create the debugging script $at_group_dir/run which will reproduce the
# current test group.
m4_define([_AT_CREATE_DEBUGGING_SCRIPT],
[ {
echo "#! /bin/sh"
echo 'test "${ZSH_VERSION+set}" = set && alias -g '\''${1+"$[@]"}'\''='\''"$[@]"'\'''
echo "cd '$at_dir'"
echo 'exec ${CONFIG_SHELL-'"$SHELL"'}' "$[0]" \
'-v -d' "$at_debug_args" "$at_group" '${1+"$[@]"}'
echo 'exit 1'
} >$at_group_dir/run
chmod +x $at_group_dir/run
])# _AT_CREATE_DEBUGGING_SCRIPT
# AT_INIT([TESTSUITE-NAME])
# -------------------------
# Begin test suite.
m4_define([AT_INIT],
[m4_pattern_forbid([^_?AT_])
m4_define([AT_TESTSUITE_NAME],
m4_defn([AT_PACKAGE_STRING])[ test suite]m4_ifval([$1], [: $1]))
m4_define([AT_ordinal], 0)
m4_define([AT_banner_ordinal], 0)
m4_define([AT_groups_all], [])
m4_define([AT_help_all], [])
AS_INIT
AT_COPYRIGHT(
[Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
Foundation, Inc.
This test suite is free software; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.])
AS_PREPARE
m4_divert_push([DEFAULTS])dnl
SHELL=${CONFIG_SHELL-/bin/sh}
# How were we run?
at_cli_args="$[@]"
# Load the config file.
for at_file in atconfig atlocal
do
test -r $at_file || continue
. ./$at_file || AS_ERROR([invalid content: $at_file])
done
# Autoconf <=2.59b set at_top_builddir instead of at_top_build_prefix:
: ${at_top_build_prefix=$at_top_builddir}
# atconfig delivers names relative to the directory the test suite is
# in, but the groups themselves are run in testsuite-dir/group-dir.
if test -n "$at_top_srcdir"; then
builddir=../..
for at_dir in srcdir top_srcdir top_build_prefix
do
at_val=AS_VAR_GET([at_$at_dir])
AS_VAR_SET([$at_dir], [$at_val/../..])
done
fi
# Not all shells have the 'times' builtin; the subshell is needed to make
# sure we discard the 'times: not found' message from the shell.
at_times_p=false
(times) >/dev/null 2>&1 && at_times_p=:
# CLI Arguments to pass to the debugging scripts.
at_debug_args=
# -e sets to true
at_errexit_p=false
# Shall we be verbose?
at_verbose=:
at_quiet=echo
# Shall we keep the debug scripts? Must be `:' when the suite is
# run by a debug script, so that the script doesn't remove itself.
at_debug_p=false
# Display help message?
at_help_p=false
# Display the version message?
at_version_p=false
# List test groups?
at_list_p=false
# Test groups to run
at_groups=
# The directory we are in.
at_dir=`pwd`
# The directory the whole suite works in.
# Should be absolutely to let the user `cd' at will.
at_suite_dir=$at_dir/$as_me.dir
# The file containing the suite.
at_suite_log=$at_dir/$as_me.log
# The file containing the location of the last AT_CHECK.
at_check_line_file=$at_suite_dir/at-check-line
# The file containing the exit status of the last command.
at_status_file=$at_suite_dir/at-status
# The files containing the output of the tested commands.
at_stdout=$at_suite_dir/at-stdout
at_stder1=$at_suite_dir/at-stder1
at_stderr=$at_suite_dir/at-stderr
# The file containing dates.
at_times_file=$at_suite_dir/at-times
m4_divert_pop([DEFAULTS])dnl
m4_wrap([m4_divert_text([DEFAULTS],
[
# List of the tested programs.
at_tested='m4_ifdef([AT_tested], [AT_tested])'
# List of the all the test groups.
at_groups_all='AT_groups_all'
# As many question marks as there are digits in the last test group number.
# Used to normalize the test group numbers so that `ls' lists them in
# numerical order.
at_format='m4_bpatsubst(m4_defn([AT_ordinal]), [.], [?])'
# Description of all the test groups.
at_help_all="AS_ESCAPE(m4_defn([AT_help_all]))"])])dnl
m4_divert_push([PARSE_ARGS])dnl
at_prev=
for at_option
do
# If the previous option needs an argument, assign it.
if test -n "$at_prev"; then
at_option=$at_prev=$at_option
at_prev=
fi
case $at_option in
*=*) at_optarg=`expr "x$at_option" : 'x[[^=]]*=\(.*\)'` ;;
*) at_optarg= ;;
esac
# Accept the important Cygnus configure options, so we can diagnose typos.
case $at_option in
--help | -h )
at_help_p=:
;;
--list | -l )
at_list_p=:
;;
--version | -V )
at_version_p=:
;;
--clean | -c )
test -d "$at_suite_dir" &&
find "$at_suite_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
rm -f -r "$at_suite_dir" "$at_suite_log"
exit 0
;;
--debug | -d )
at_debug_p=:
;;
--errexit | -e )
at_debug_p=:
at_errexit_p=:
;;
--verbose | -v )
at_verbose=echo; at_quiet=:
;;
--trace | -x )
at_traceon='set -x'; at_traceoff='set +x'
;;
[[0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]])
at_groups="$at_groups$at_option "
;;
# Ranges
[[0-9]- | [0-9][0-9]- | [0-9][0-9][0-9]- | [0-9][0-9][0-9][0-9]-])
at_range_start=`echo $at_option |tr -d X-`
at_range=`echo " $at_groups_all " | \
sed -e 's/^.* \('$at_range_start' \)/\1/'`
at_groups="$at_groups$at_range "
;;
[-[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | -[0-9][0-9][0-9][0-9]])
at_range_end=`echo $at_option |tr -d X-`
at_range=`echo " $at_groups_all " | \
sed -e 's/\( '$at_range_end'\) .*$/\1/'`
at_groups="$at_groups$at_range "
;;
[[0-9]-[0-9] | [0-9]-[0-9][0-9] | [0-9]-[0-9][0-9][0-9]] | \
[[0-9]-[0-9][0-9][0-9][0-9] | [0-9][0-9]-[0-9][0-9]] | \
[[0-9][0-9]-[0-9][0-9][0-9] | [0-9][0-9]-[0-9][0-9][0-9][0-9]] | \
[[0-9][0-9][0-9]-[0-9][0-9][0-9]] | \
[[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]] | \
[[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]] )
at_range_start=`expr $at_option : '\(.*\)-'`
at_range_end=`expr $at_option : '.*-\(.*\)'`
if test $at_range_start -gt $at_range_end; then
at_tmp=$at_range_end
at_range_end=$at_range_start
at_range_start=$at_tmp
fi
at_range=`echo " $at_groups_all " | \
sed -e 's/^.*\( '$at_range_start' \)/\1/' \
-e 's/\( '$at_range_end'\) .*$/\1/'`
at_groups="$at_groups$at_range "
;;
# Keywords.
--keywords | -k )
at_prev=--keywords
;;
--keywords=* )
at_groups_selected=$at_help_all
at_save_IFS=$IFS
IFS=,
set X $at_optarg
shift
IFS=$at_save_IFS
for at_keyword
do
at_invert=
case $at_keyword in
'!'*)
at_invert="-v"
at_keyword=`expr "X$at_keyword" : 'X!\(.*\)'`
;;
esac
# It is on purpose that we match the test group titles too.
at_groups_selected=`echo "$at_groups_selected" |
grep -i $at_invert ["^[1-9][^;]*;.*[; ]$at_keyword[ ;]"]`
done
at_groups_selected=`echo "$at_groups_selected" | sed 's/;.*//'`
# Smash the newlines.
at_groups="$at_groups`echo $at_groups_selected` "
;;
m4_divert_pop([PARSE_ARGS])dnl
dnl Process *=* last to allow for user specified --option=* type arguments.
m4_divert_push([PARSE_ARGS_END])dnl
*=*)
at_envvar=`expr "x$at_option" : 'x\([[^=]]*\)='`
# Reject names that are not valid shell variable names.
expr "x$at_envvar" : "[.*[^_$as_cr_alnum]]" >/dev/null &&
AS_ERROR([invalid variable name: $at_envvar])
at_value=`echo "$at_optarg" | sed "s/'/'\\\\\\\\''/g"`
eval "$at_envvar='$at_value'"
export $at_envvar
# Propagate to debug scripts.
at_debug_args="$at_debug_args $at_envvar='$at_value'"
;;
*) echo "$as_me: invalid option: $at_option" >&2
echo "Try \`$[0] --help' for more information." >&2
exit 1
;;
esac
done
# Selected test groups.
if test -z "$at_groups"; then
at_groups=$at_groups_all
else
# Sort the tests, removing duplicates:
at_groups=`echo $at_groups | tr ' ' "$as_nl" | sort -nu`
# and add banners. (Passing at_groups_all is tricky--see the comment
# starting with "Passing at_groups is tricky.")
at_groups=`echo "$at_groups$as_nl $at_groups_all" |
awk ['BEGIN { FS = "@" } # Effectively switch off field splitting.
/^$/ { next } # Ignore the empty line.
!/ / { groups++; selected[$ 0] = 1; next }
# The last line, containing at_groups_all.
{
n = split($ 0, a, " ")
# If there are several tests, select their banners:
if (groups > 1) {
for (i = 1; i <= n; i++) {
if (a[i] ~ /^banner-/)
banner = a[i]
else if (banner != "" && selected[a[i]] == 1)
selected[banner] = 1
}
}
for (i = 1; i <= n; i++)
if (selected[a[i]] == 1)
list = list " " a[i]
print list
}']`
fi
m4_divert_pop([PARSE_ARGS_END])dnl
m4_divert_push([HELP])dnl
# Help message.
if $at_help_p; then
cat <<_ATEOF
Usage: $[0] [[OPTION]... [VARIABLE=VALUE]... [TESTS]]
Run all the tests, or the selected TESTS, given by numeric ranges, and
save a detailed log file. Upon failure, create debugging scripts.
You should not change environment variables unless explicitly passed
as command line arguments. Set \`AUTOTEST_PATH' to select the executables
to exercise. Each relative directory is expanded as build and source
directories relatively to the top level of this distribution. E.g.,
$ $[0] AUTOTEST_PATH=bin
possibly amounts into
PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:\$PATH
_ATEOF
m4_divert_pop([HELP])dnl
m4_divert_push([HELP_MODES])dnl
cat <<_ATEOF
Operation modes:
-h, --help print the help message, then exit
-V, --version print version number, then exit
-c, --clean remove all the files this test suite might create and exit
-l, --list describes all the tests, or the selected TESTS
_ATEOF
m4_divert_pop([HELP_MODES])dnl
m4_divert_push([HELP_TUNING])dnl
cat <<_ATEOF
Execution tuning:
-k, --keywords=KEYWORDS
select the tests matching all the comma-separated KEYWORDS
multiple \`-k' accumulate; prefixed \`!' negates a KEYWORD
-e, --errexit abort as soon as a test fails; implies --debug
-v, --verbose force more detailed output
default for debugging scripts
-d, --debug inhibit clean up and top-level logging
default for debugging scripts
-x, --trace enable tests shell tracing
_ATEOF
m4_divert_pop([HELP_TUNING])dnl
m4_divert_push([HELP_END])dnl
cat <<_ATEOF
Report bugs to <AT_PACKAGE_BUGREPORT>.
_ATEOF
exit 0
fi
# List of tests.
if $at_list_p; then
cat <<_ATEOF
AT_TESTSUITE_NAME test groups:
NUM: FILE-NAME:LINE TEST-GROUP-NAME
KEYWORDS
_ATEOF
# Passing at_groups is tricky. We cannot use it to form a literal string
# or regexp because of the limitation of AIX awk. And Solaris' awk
# doesn't grok more than 99 fields in a record, so we have to use `split'.
echo "$at_groups$as_nl$at_help_all" |
awk 'BEGIN { FS = ";" }
NR == 1 {
for (n = split($ 0, a, " "); n; n--) selected[[a[n]]] = 1
next
}
{
if (selected[[$ 1]]) {
printf " %3d: %-18s %s\n", $ 1, $ 2, $ 3
if ($ 4) printf " %s\n", $ 4
}
}'
exit 0
fi
m4_divert_pop([HELP_END])dnl
m4_divert_push([VERSION])dnl
if $at_version_p; then
echo "$as_me (AT_PACKAGE_STRING)"
cat <<\_ACEOF
m4_divert_pop([VERSION])dnl
m4_divert_push([VERSION_END])dnl
_ACEOF
exit 0
fi
m4_divert_pop([VERSION_END])dnl
m4_divert_push([PREPARE_TESTS])dnl
# Don't take risks: use only absolute directories in PATH.
#
# For stand-alone test suites, AUTOTEST_PATH is relative to `.'.
#
# For embedded test suites, AUTOTEST_PATH is relative to the top level
# of the package. Then expand it into build/src parts, since users
# may create executables in both places.
AUTOTEST_PATH=`echo $AUTOTEST_PATH | sed "s&:&$PATH_SEPARATOR&g"`
at_path=
_AS_PATH_WALK([$AUTOTEST_PATH $PATH],
[test -n "$at_path" && at_path=$at_path$PATH_SEPARATOR
case $as_dir in
[[\\/]]* | ?:[[\\/]]* )
at_path=$at_path$as_dir
;;
* )
if test -z "$at_top_build_prefix"; then
# Stand-alone test suite.
at_path=$at_path$as_dir
else
# Embedded test suite.
at_path=$at_path$at_top_build_prefix$as_dir$PATH_SEPARATOR
at_path=$at_path$at_top_srcdir/$as_dir
fi
;;
esac])
# Now build and simplify PATH.
#
# There might be directories that don't exist, but don't redirect
# builtins' (eg., cd) stderr directly: Ultrix's sh hates that.
PATH=
_AS_PATH_WALK([$at_path],
[as_dir=`(cd "$as_dir" && pwd) 2>/dev/null`
test -d "$as_dir" || continue
case $PATH in
$as_dir | \
$as_dir$PATH_SEPARATOR* | \
*$PATH_SEPARATOR$as_dir | \
*$PATH_SEPARATOR$as_dir$PATH_SEPARATOR* ) ;;
'') PATH=$as_dir ;;
*) PATH=$PATH$PATH_SEPARATOR$as_dir ;;
esac])
export PATH
# Setting up the FDs.
# 5 is the log file. Not to be overwritten if `-d'.
m4_define([AS_MESSAGE_LOG_FD], [5])
if $at_debug_p; then
at_suite_log=/dev/null
else
: >"$at_suite_log"
fi
exec AS_MESSAGE_LOG_FD>>"$at_suite_log"
# Banners and logs.
AS_BOX(m4_defn([AT_TESTSUITE_NAME])[.])
{
AS_BOX(m4_defn([AT_TESTSUITE_NAME])[.])
echo
echo "$as_me: command line was:"
echo " $ $[0] $at_cli_args"
echo
# Try to find a few ChangeLogs in case it might help determining the
# exact version. Use the relative dir: if the top dir is a symlink,
# find will not follow it (and options to follow the links are not
# portable), which would result in no output here.
if test -n "$at_top_srcdir"; then
AS_BOX([ChangeLogs.])
echo
for at_file in `find "$at_top_srcdir" -name ChangeLog -print`
do
echo "$as_me: $at_file:"
sed 's/^/| /;10q' $at_file
echo
done
AS_UNAME
echo
fi
# Contents of the config files.
for at_file in atconfig atlocal
do
test -r $at_file || continue
echo "$as_me: $at_file:"
sed 's/^/| /' $at_file
echo
done
AS_BOX([Tested programs.])
echo
} >&AS_MESSAGE_LOG_FD
# Report what programs are being tested.
for at_program in : $at_tested
do
test "$at_program" = : && continue
_AS_PATH_WALK([$PATH], [test -f "$as_dir/$at_program" && break])
if test -f "$as_dir/$at_program"; then
{
echo "$at_srcdir/AT_LINE: $as_dir/$at_program --version"
"$as_dir/$at_program" --version
echo
} >&AS_MESSAGE_LOG_FD 2>&1
else
AS_ERROR([cannot find $at_program])
fi
done
{
AS_BOX([Running the tests.])
} >&AS_MESSAGE_LOG_FD
at_start_date=`date`
at_start_time=`date +%s 2>/dev/null`
echo "$as_me: starting at: $at_start_date" >&AS_MESSAGE_LOG_FD
at_xpass_list=
at_xfail_list=
at_pass_list=
at_fail_list=
at_skip_list=
at_group_count=0
m4_divert_pop([PREPARE_TESTS])dnl
m4_divert_push([TESTS])dnl
# Create the master directory if it doesn't already exist.
test -d "$at_suite_dir" ||
mkdir "$at_suite_dir" ||
AS_ERROR([cannot create '$at_suite_dir'])
# Can we diff with `/dev/null'? DU 5.0 refuses.
if diff /dev/null /dev/null >/dev/null 2>&1; then
at_devnull=/dev/null
else
at_devnull=$at_suite_dir/devnull
>"$at_devnull"
fi
# Use `diff -u' when possible.
if at_diff=`diff -u "$at_devnull" "$at_devnull" 2>&1` && test -z "$at_diff"
then
at_diff='diff -u'
else
at_diff=diff
fi
for at_group in $at_groups
do
# Be sure to come back to the top test directory.
cd "$at_suite_dir"
case $at_group in
banner-*)
at_group_log=$at_suite_log
;;
*)
at_group_normalized=$at_group
_AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
# Create a fresh directory for the next test group, and enter.
at_group_dir=$at_suite_dir/$at_group_normalized
at_group_log=$at_group_dir/$as_me.log
if test -d "$at_group_dir"; then
find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
rm -fr "$at_group_dir"
fi
# Be tolerant if the above `rm' was not able to remove the directory.
AS_MKDIR_P([$at_group_dir])
cd $at_group_dir
;;
esac
echo 0 > "$at_status_file"
# Clearly separate the test groups when verbose.
test $at_group_count != 0 && $at_verbose
# In verbose mode, append to the log file *and* show on
# the standard output; in quiet mode only write to the log
if test $at_verbose = echo; then
at_tee_pipe='tee -a "$at_group_log"'
else
at_tee_pipe='cat >> "$at_group_log"'
fi
case $at_group in
dnl Test groups inserted here (TESTS).
m4_divert_pop([TESTS])[]dnl
m4_divert_push([TESTS_END])[]dnl
* )
echo "$as_me: no such test group: $at_group" >&2
continue
;;
esac
# Be sure to come back to the suite directory, in particular
# since below we might `rm' the group directory we are in currently.
cd "$at_suite_dir"
case $at_group in
banner-*) ;;
*)
if test ! -f "$at_check_line_file"; then
sed "s/^ */$as_me: warning: /" <<_ATEOF
A failure happened in a test group before any test could be
run. This means that test suite is improperly designed. Please
report this failure to <AT_PACKAGE_BUGREPORT>.
_ATEOF
echo "$at_setup_line" >"$at_check_line_file"
fi
at_group_count=`expr 1 + $at_group_count`
$at_verbose $ECHO_N "$at_group. $at_setup_line: $ECHO_C"
echo $ECHO_N "$at_group. $at_setup_line: $ECHO_C" >> "$at_group_log"
case $at_xfail:$at_status in
yes:0)
at_msg="UNEXPECTED PASS"
at_xpass_list="$at_xpass_list $at_group"
at_errexit=$at_errexit_p
;;
no:0)
at_msg="ok"
at_pass_list="$at_pass_list $at_group"
at_errexit=false
;;
*:77)
at_msg='skipped ('`cat "$at_check_line_file"`')'
at_skip_list="$at_skip_list $at_group"
at_errexit=false
;;
yes:*)
at_msg='expected failure ('`cat "$at_check_line_file"`')'
at_xfail_list="$at_xfail_list $at_group"
at_errexit=false
;;
no:*)
at_msg='FAILED ('`cat "$at_check_line_file"`')'
at_fail_list="$at_fail_list $at_group"
at_errexit=$at_errexit_p
;;
esac
# Make sure there is a separator even with long titles.
echo " $at_msg"
at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg"
case $at_status in
0|77)
# $at_times_file is only available if the group succeeded.
# We're not including the group log, so the success message
# is written in the global log separately. But we also
# write to the group log in case they're using -d.
if test -f "$at_times_file"; then
at_log_msg="$at_log_msg ("`sed 1d "$at_times_file"`')'
rm -f "$at_times_file"
fi
echo "$at_log_msg" >> "$at_group_log"
echo "$at_log_msg" >&AS_MESSAGE_LOG_FD
# Cleanup the group directory, unless the user wants the files.
if $at_debug_p ; then
_AT_CREATE_DEBUGGING_SCRIPT
elif test -d "$at_group_dir"; then
find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
rm -fr "$at_group_dir"
fi
;;
*)
# Upon failure, include the log into the testsuite's global
# log. The failure message is written in the group log. It
# is later included in the global log.
echo "$at_log_msg" >> "$at_group_log"
# Upon failure, keep the group directory for autopsy, and
# create the debugging script.
_AT_CREATE_DEBUGGING_SCRIPT
$at_errexit && break
;;
esac
;;
esac
done
# Back to the top directory.
cd "$at_dir"
# Compute the duration of the suite.
at_stop_date=`date`
at_stop_time=`date +%s 2>/dev/null`
echo "$as_me: ending at: $at_stop_date" >&AS_MESSAGE_LOG_FD
case $at_start_time,$at_stop_time in
[[0-9]*,[0-9]*])
at_duration_s=`expr $at_stop_time - $at_start_time`
at_duration_m=`expr $at_duration_s / 60`
at_duration_h=`expr $at_duration_m / 60`
at_duration_s=`expr $at_duration_s % 60`
at_duration_m=`expr $at_duration_m % 60`
at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s"
echo "$as_me: test suite duration: $at_duration" >&AS_MESSAGE_LOG_FD
;;
esac
# Wrap up the test suite with summary statistics.
at_skip_count=`set dummy $at_skip_list; shift; echo $[@%:@]`
at_fail_count=`set dummy $at_fail_list; shift; echo $[@%:@]`
at_xpass_count=`set dummy $at_xpass_list; shift; echo $[@%:@]`
at_xfail_count=`set dummy $at_xfail_list; shift; echo $[@%:@]`
at_run_count=`expr $at_group_count - $at_skip_count`
at_unexpected_count=`expr $at_xpass_count + $at_fail_count`
at_total_fail_count=`expr $at_xfail_count + $at_fail_count`
echo
AS_BOX([Test results.])
echo
{
echo
AS_BOX([Test results.])
echo
} >&AS_MESSAGE_LOG_FD
dnl
dnl FIXME: this code is as far from i18n-cleanness as man
dnl could imagine...
dnl
if test $at_run_count = 1; then
at_result="1 test"
at_were=was
else
at_result="$at_run_count tests"
at_were=were
fi
if $at_errexit_p && test $at_unexpected_count != 0; then
if test $at_xpass_count = 1; then
at_result="$at_result $at_were run, one passed"
else
at_result="$at_result $at_were run, one failed"
fi
at_result="$at_result unexpectedly and inhibited subsequent tests."
else
# Don't you just love exponential explosion of the number of cases?
case $at_xpass_count:$at_fail_count:$at_xfail_count in
# So far, so good.
0:0:0) at_result="$at_result $at_were successful." ;;
0:0:*) at_result="$at_result behaved as expected." ;;
# Some unexpected failures
0:*:0) at_result="$at_result $at_were run,
$at_fail_count failed unexpectedly." ;;
# Some failures, both expected and unexpected
0:*:1) at_result="$at_result $at_were run,
$at_total_fail_count failed ($at_xfail_count expected failure)." ;;
0:*:*) at_result="$at_result $at_were run,
$at_total_fail_count failed ($at_xfail_count expected failures)." ;;
# No unexpected failures, but some xpasses
*:0:*) at_result="$at_result $at_were run,
$at_xpass_count passed unexpectedly." ;;
# No expected failures, but failures and xpasses
*:1:0) at_result="$at_result $at_were run,
$at_unexpected_count did not behave as expected ($at_fail_count unexpected failure)." ;;
*:*:0) at_result="$at_result $at_were run,
$at_unexpected_count did not behave as expected ($at_fail_count unexpected failures)." ;;
# All of them.
*:*:1) at_result="$at_result $at_were run,
$at_xpass_count passed unexpectedly,
$at_total_fail_count failed ($at_xfail_count expected failure)." ;;
*:*:*) at_result="$at_result $at_were run,
$at_xpass_count passed unexpectedly,
$at_total_fail_count failed ($at_xfail_count expected failures)." ;;
esac
if test $at_skip_count = 0 && test $at_run_count -gt 1; then
at_result="All $at_result"
fi
fi
# Now put skips in the mix.
case $at_skip_count in
0) ;;
1) at_result="$at_result
1 test was skipped." ;;
*) at_result="$at_result
$at_skip_count tests were skipped." ;;
esac
if test $at_unexpected_count = 0; then
echo "$at_result"
echo "$at_result" >&AS_MESSAGE_LOG_FD
else
echo "ERROR: $at_result" >&2
echo "ERROR: $at_result" >&AS_MESSAGE_LOG_FD
{
echo
AS_BOX([Summary of the failures.])
# Summary of failed and skipped tests.
if test $at_fail_count != 0; then
echo "Failed tests:"
$SHELL "$[0]" $at_fail_list --list
echo
fi
if test $at_skip_count != 0; then
echo "Skipped tests:"
$SHELL "$[0]" $at_skip_list --list
echo
fi
if test $at_xpass_count != 0; then
echo "Unexpected passes:"
$SHELL "$[0]" $at_xpass_list --list
echo
fi
if test $at_fail_count != 0; then
AS_BOX([Detailed failed tests.])
echo
for at_group in $at_fail_list
do
at_group_normalized=$at_group
_AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
cat "$at_suite_dir/$at_group_normalized/$as_me.log"
echo
done
echo
fi
if test -n "$at_top_srcdir"; then
AS_BOX([${at_top_build_prefix}config.log])
sed 's/^/| /' ${at_top_build_prefix}config.log
echo
fi
} >&AS_MESSAGE_LOG_FD
AS_BOX([$as_me.log was created.])
echo
echo "Please send \`${at_testdir+${at_testdir}/}$as_me.log' and all information you think might help:"
echo
echo " To: <AT_PACKAGE_BUGREPORT>"
echo " Subject: @<:@AT_PACKAGE_STRING@:>@ $as_me:dnl
$at_fail_list${at_fail_list:+ failed${at_xpass_list:+,}}dnl
$at_xpass_list${at_xpass_list:+ passed unexpectedly}"
echo
if test $at_debug_p = false; then
echo
echo 'You may investigate any problem if you feel able to do so, in which'
echo 'case the test suite provides a good starting point. Its output may'
echo "be found below \`${at_testdir+${at_testdir}/}$as_me.dir'."
echo
fi
exit 1
fi
exit 0
m4_divert_pop([TESTS_END])dnl
dnl End of AT_INIT: divert to KILL, only test groups are to be
dnl output, the rest is ignored. Current diversion is BODY, inherited
dnl from M4sh.
m4_divert_pop([BODY])
m4_divert_push([KILL])
])# AT_INIT
# _AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ARGS],[ACTION-IF-GIVEN],
# [ACTION-IF-NOT-GIVEN])
# ---------------------------------------------------------------------------
# Internal implementation of AT_ARG_OPTION & AT_ARG_OPTION_ARG
m4_defun([_AT_ARG_OPTION],
[m4_divert_once([HELP_OTHER],
[cat <<_ATEOF
Other options:
_ATEOF
])dnl m4_divert_once HELP_OTHER
m4_divert_text([HELP_OTHER],
[cat <<_ATEOF
$2
_ATEOF])dnl
dnl Turn our options into our desired strings
m4_ifdef([AT_first_option],[m4_undefine([AT_first_option])])dnl
m4_ifdef([AT_case],[m4_undefine([AT_case])])dnl
m4_ifdef([AT_case_no],[m4_undefine([AT_case_no])])dnl
m4_ifdef([AT_case_arg],[m4_undefine([AT_case_arg])])dnl
m4_foreach([AT_option], m4_split(m4_normalize([$1]),[[ \|]+]),
[m4_define_default([AT_first_option],AT_option)dnl
m4_append([AT_case],m4_if(m4_len(AT_option),1,[],[-])[-]AT_option, [ | ])dnl
m4_append([AT_case_no],[--no]AT_option, [ | ])dnl
m4_append([AT_case_arg],m4_if(m4_len(AT_option),1,[],[-])[-]AT_option[=*], [ | ])dnl
])dnl m4_foreach AT_option
dnl keep track so we or the user may process ACTION-IF-NOT-GIVEN
m4_divert_once([PARSE_ARGS_BEGIN],
[
##
## Set up package specific options.
##
])dnl
m4_divert_text([PARSE_ARGS_BEGIN],
[dnl Provide a default value for options without arguments.
m4_ifvaln([$3],,[at_arg_[]m4_bpatsubst([AT_first_option], -, _)=false])dnl
at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=false
])dnl m4_divert_text DEFAULTS
m4_ifval([$3],[m4_divert_once([PARSE_ARGS_END],
[
##
## Verify our last option didn't require an argument
##
AS_IF([test -n "$at_prev"],[AS_ERROR([`$at_prev' requires an argument.])])])])
m4_divert_text([PARSE_ARGS],
[dnl Parse the options and args when necessary.
m4_ifvaln([$3],
[ AT_case )
at_prev=--m4_bpatsubst([AT_first_option], -, _)
;;
AT_case_arg )
at_arg_[]m4_bpatsubst([AT_first_option], -, _)=$at_optarg
at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
$4
;;],
[ AT_case )
at_optarg=:
at_arg_[]m4_bpatsubst([AT_first_option], -, _)=:
at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
m4_ifval([$4],[$4])dnl
;;
AT_case_no )
at_optarg=false
at_arg_[]m4_bpatsubst([AT_first_option], -, _)=false
at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
m4_ifval([$4],[$4])dnl
;;])dnl m4_ifvaln $3
])dnl m4_divert_text PARSE_ARGS
m4_ifvaln([$5],
[m4_divert_once([PARSE_ARGS_END],
[
##
## Process package specific options when _not_ supplied.
##])dnl m4_divert_once PARSE_ARGS_END
m4_divert_text([PARSE_ARGS_END],
[
AS_IF([$at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)],,[$5])dnl
])dnl m4_divert_text PARSE_ARGS_END
])dnl m4_ifvaln $5
])dnl _AT_ARG_OPTION
# AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
# ------------------------------------------------------------------------
# Accept a set of OPTIONS with arguments. Add HELP-TEXT to the HELP_OTHER
# diversion.
#
# Preceding dashes should not be passed into OPTIONS. Users will be required
# to pass `--' before long options and `-' before single character options.
#
# $at_arg_OPTION will be set to `:' if this option is received, `false' if
# if --noOPTION is received, and `false' by default.
#
# Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered with
# $at_optarg set to `:' or `false' as appropriate. $at_optarg is actually
# just a copy of $at_arg_OPTION.
#
# ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
# if no option from OPTIONS was found.
m4_defun([AT_ARG_OPTION],[_AT_ARG_OPTION([$1],[$2],,[$3],[$4])])
# AT_ARG_OPTION_ARG(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
# ---------------------------------------------------------------------------
# Accept a set of OPTIONS with arguments, seperated by commas. Add HELP-TEXT
# to the HELP_OTHER diversion.
#
# Preceding dashes should not be passed into OPTIONS. Users will be required
# to pass `--' before long options and `-' before single character options.
#
# By default, any argument to these options will be assigned to the shell
# variable $at_arg_OPTION, where OPTION is the first option in OPTIONS with
# any `-' characters replaced with `_'.
#
# Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered with
# $at_optarg set. $at_optarg is actually just a copy of $at_arg_OPTION.
#
# ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
# if no option from OPTIONS was found.
m4_defun([AT_ARG_OPTION_ARG],[_AT_ARG_OPTION([$1],[$2],1,[$3],[$4])])
# AT_TESTED(PROGRAMS)
# -------------------
# Specify the list of programs exercised by the test suite. Their
# versions are logged, and in the case of embedded test suite, they
# must correspond to the version of the package. PATH should be
# already preset so the proper executable will be selected.
m4_define([AT_TESTED],
[m4_append_uniq([AT_tested], [$1], [
])])
# AT_COPYRIGHT(TEXT)
# ------------------
# Emit TEXT, a copyright notice, in the top of the test suite and in
# --version output. Macros in TEXT are evaluated once.
m4_define([AT_COPYRIGHT],
[AS_COPYRIGHT([$1])[]dnl
m4_divert_text([VERSION_NOTICES],
[
$1])])# AT_COPYRIGHT
# AT_SETUP(DESCRIPTION)
# ---------------------
# Start a group of related tests, all to be executed in the same subshell.
# The group is testing what DESCRIPTION says.
m4_define([AT_SETUP],
[m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])])
m4_ifdef([AT_capture_files], [m4_undefine([AT_capture_files])])
m4_define([AT_line], AT_LINE)
m4_define([AT_xfail], [at_xfail=no])
m4_define([AT_description], [$1])
m4_define([AT_ordinal], m4_incr(AT_ordinal))
m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal]))
m4_divert_push([TESTS])dnl
AT_ordinal ) @%:@ AT_ordinal. m4_defn([AT_line]): $1
at_setup_line='m4_defn([AT_line])'
at_desc="AS_ESCAPE([$1])"
$at_quiet $ECHO_N "m4_format([%3d: %-]m4_eval(47 - m4_qdelta([$1]))[s],
AT_ordinal, AS_ESCAPE([[$1]]))[]$ECHO_C"
m4_divert_push([TEST_SCRIPT])dnl
])
# AT_XFAIL_IF(SHELL-EXPRESSION)
# -----------------------------
# Set up the test to be expected to fail if SHELL-EXPRESSION evaluates to
# true (exitcode = 0).
m4_define([AT_XFAIL_IF],
[dnl
dnl Try to limit the amount of conditionals that we emit.
m4_case([$1],
[], [],
[false], [],
[:], [m4_define([AT_xfail], [at_xfail=yes])],
[true], [m4_define([AT_xfail], [at_xfail=yes])],
[m4_append([AT_xfail], [
$1 && at_xfail=yes])])])
# AT_KEYWORDS(KEYWORDS)
# ---------------------
# Declare a list of keywords associated to the current test group.
m4_define([AT_KEYWORDS],
[m4_append_uniq([AT_keywords], [$1], [ ])])
# AT_CAPTURE_FILE(FILE)
# ---------------------
# If the current test group does not behave as expected, save the contents of
# FILE in the test suite log.
m4_define([AT_CAPTURE_FILE],
[m4_append_uniq([AT_capture_files], ["$1"], [ \
])])
# AT_CLEANUP
# ----------
# Complete a group of related tests.
m4_define([AT_CLEANUP],
[m4_append([AT_help_all],
m4_defn([AT_ordinal]);m4_defn([AT_line]);m4_defn([AT_description]);m4_ifdef([AT_keywords], [m4_defn([AT_keywords])]);
)dnl
m4_divert_pop([TEST_SCRIPT])dnl Back to TESTS
AT_xfail
echo "# -*- compilation -*-" >> "$at_group_log"
(
echo "AT_ordinal. m4_defn([AT_line]): testing $1..."
$at_traceon
m4_undivert([TEST_SCRIPT])dnl Insert the code here
$at_traceoff
$at_times_p && times >"$at_times_file"
) AS_MESSAGE_LOG_FD>&1 2>&1 | eval $at_tee_pipe
at_status=`cat "$at_status_file"`
;;
m4_divert_pop([TESTS])dnl Back to KILL.
])# AT_CLEANUP
# AT_BANNER(TEXT)
# ---------------
# Output TEXT without any shell expansion.
m4_define([AT_BANNER],
[m4_define([AT_banner_ordinal], m4_incr(AT_banner_ordinal))
m4_append([AT_groups_all], [ banner-]m4_defn([AT_banner_ordinal]))
m4_divert_text([TESTS],
[
banner-AT_banner_ordinal ) @%:@ Banner AT_banner_ordinal. AT_LINE
cat <<\_ATEOF
$1
_ATEOF
;;
])dnl
])# AT_BANNER
# AT_DATA(FILE, CONTENTS)
# -----------------------
# Initialize an input data FILE with given CONTENTS, which should end with
# an end of line.
# This macro is not robust to active symbols in CONTENTS *on purpose*.
# If you don't want CONTENTS to be evaluated, quote it twice.
m4_define([AT_DATA],
[cat >$1 <<'_ATEOF'
$2[]_ATEOF
])
# AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,
# [RUN-IF-FAIL], [RUN-IF-PASS])
# ------------------------------------------------
# Execute a test by performing given shell COMMANDS. These commands
# should normally exit with STATUS, while producing expected STDOUT and
# STDERR contents. Shell metacharacters in STDOUT and STDERR are
# _not_ processed by the shell, but are treated as string literals.
#
# STATUS, STDOUT, and STDERR are not checked if equal to `ignore'.
#
# If STDOUT is `expout', then stdout is compared to the content of the file
# `expout'. Likewise for STDERR and `experr'.
#
# If STDOUT is `stdout', then the stdout is left in the file `stdout',
# likewise for STDERR and `stderr'. Don't do this:
#
# AT_CHECK([command >out])
# # Some checks on `out'
#
# do this instead:
#
# AT_CHECK([command], [], [stdout])
# # Some checks on `stdout'
#
# This is an unfortunate limitation inherited from Ultrix which will not
# let you redirect several times the same FD (see the Autoconf documentation).
# If you use the `AT_CHECK([command >out])' be sure to get a test suite
# that will show spurious failures.
#
# You might wonder why not just use `ignore' and directly use stdout and
# stderr left by the test suite. Firstly because the names of these files
# is an internal detail, and secondly, because
#
# AT_CHECK([command], [], [ignore])
# AT_CHECK([check stdout])
#
# will use `stdout' both in input and output: undefined behavior would
# certainly result. That's why the test suite will save them in `at-stdout'
# and `at-stderr', and will provide you with `stdout' and `stderr'.
#
# Any line of stderr starting with leading blanks and a `+' are filtered
# out, since most shells when tracing include subshell traces in stderr.
# This may cause spurious failures when the test suite is run with `-x'.
#
m4_define([AT_CHECK],
[_AT_CHECK([$1],[$2],[$3],[$4],[$5],[$6],1)])
# AT_CHECK_NOESCAPE(COMMANDS, [STATUS = 0], STDOUT, STDERR,
# [RUN-IF-FAIL], [RUN-IF-PASS])
# ---------------------------------------------------------
# Like AT_CHECK, but do not AS_ESCAPE shell metacharacters in the STDOUT
# and STDERR arguments before running the comparison.
m4_define([AT_CHECK_NOESCAPE],
[_AT_CHECK([$1],[$2],[$3],[$4],[$5],[$6])])
# _AT_DECIDE_TRACEABLE(COMMANDS)
# ------------------------------
# Worker for for _AT_CHECK that expands to shell code. If COMMANDS are safe to
# trace with `set -x', the shell code will set `at_trace_this=yes'. Otherwise,
# the shell code will print a message stating an aspect of COMMANDS that makes
# tracing them unsafe.
#
# Tracing COMMANDS is not safe if they contain a command that spans multiple
# lines. When the test suite user passes `-x' or `--trace', the test suite
# precedes every command with a `set -x'. Since most tests expect a specific
# stderr, if only to confirm that it is empty, the test suite filters ^+ from
# the captured stderr before comparing with the expected stderr. If a command
# spans multiple lines, so will its trace, but a `+' only prefixes the first
# line of that trace:
#
# $ echo 'foo
# bar'
# => stdout
# foo
# bar
# => stderr
# + foo
# bar
#
# In a subset of cases, one could filter such extended shell traces from stderr.
# Since test commands spanning several lines are rare, I chose instead to simply
# not trace COMMANDS that could yield multiple trace lines. Distinguishing such
# COMMANDS became the task at hand.
#
# These features may cause a shell command to span multiple lines:
#
# (a) A quoted literal newline.
# Example:
# echo foo'
# 'bar
# M4 is a hostile language for the job of parsing COMMANDS to determine whether
# each literal newline is quoted, so we simply disable tracing for all COMMANDS
# that bear literal newlines.
#
# (b) A command substitution not subject to word splitting.
# Example:
# var=$(printf 'foo\nbar')
# Example:
# echo "`printf 'foo\\nbar`"
# One cannot know in general the number of lines a command substitution will
# yield without executing the substituted command. As such, we disable tracing
# for all COMMANDS containing these constructs.
#
# (c) A parameter expansion not subject to word splitting.
# Example:
# var=foo'
# 'bar
# echo "$var"
# Parameter expansions appear in COMMANDS with much greater frequency than do
# newlines and command substitutions, so disabling tracing for all such COMMANDS
# would much more substantially devalue `testsuite -x'. To determine which
# parameter expansions yield multiple lines, we escape all ``', `"', and `\' in
# a copy of COMMANDS and expand that string within double quotes at runtime. If
# the result of that expansion contains multiple lines, the test suite disables
# tracing for the command in question.
#
# This method leads the test suite to expand some parameters that the shell
# itself will never expand due to single-quotes or backslash escapes. This is
# not a problem for `$foo' expansions, which will simply yield the empty string
# or some unrelated value. A `${...}' expansion could actually form invalid
# shell code, however; consider `${=foo}'. Therefore, we disable tracing for
# all COMMANDS containing `${...}'. This affects few COMMANDS.
#
# This macro falls in a very hot path; the Autoconf test suite expands it 1640
# times as of this writing. To give a sense of the impact of the heuristics I
# just described, the test suite preemptively disables tracing for 31 of those,
# and 268 contain parameter expansions that require runtime evaluation. The
# balance are always safe to trace.
#
# _AT_CHECK expands COMMANDS, but the Autoconf language does not provide a way
# to safely expand arbitrary COMMANDS in an argument list, so the below tests
# examine COMMANDS unexpanded.
m4_define([_AT_DECIDE_TRACEABLE],
[dnl Utility macros.
m4_pushdef([at_lf], [
])[]dnl
dnl
dnl Examine COMMANDS for a reason to never trace COMMANDS.
m4_pushdef([at_reason],
m4_bmatch([$1],
[`.*`], [[a `...` command substitution]],
[\$(], [[a $(...) command substitution]],
[\${], [[a ${...} parameter expansion]],
at_lf, [[an embedded newline]],
[[]]dnl No reason.
))dnl
dnl
m4_ifval(m4_defn([at_reason]),
[echo 'Not enabling shell tracing (command contains ]m4_defn([at_reason])[)'],
[m4_bmatch([$1], [\$],
dnl COMMANDS may contain parameter expansions; expand them at runtime.
[case "AS_ESCAPE([$1], [`"\])" in
*'
'*) echo 'Not enabling shell tracing (command contains an embedded newline)' ;;
*) at_trace_this=yes ;;
esac],
dnl We know at build time that tracing COMMANDS is always safe.
[at_trace_this=yes])])[]dnl
m4_popdef([at_lf])[]dnl
m4_popdef([at_reason])])
# _AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,
# [RUN-IF-FAIL], [RUN-IF-PASS], SHELL_ESCAPE_IO)
# ---------------------------------------------------------
# Worker for AT_CHECK & AT_CHECK_NOESCAPE. The final SHELL-ESCAPE-IO
# argument determines whether the STDOUT & STDERR arguments will be escaped or
# not.
#
#
# Implementation Details
# ----------------------
# Ideally, we would like to run
#
# ( $at_traceon; COMMANDS >at-stdout 2> at-stderr )
#
# but we must group COMMANDS as it is not limited to a single command, and
# then the shells will save the traces in at-stderr. So we have to filter
# them out when checking stderr, and we must send them into the test suite's
# stderr to honor -x properly. Since only the first line of the trace of a
# multiline command starts with a `+', and I know of no straightforward way to
# filter out the unadorned trace lines, we disable shell tracing entirely for
# commands that could span multiple lines.
#
# Limiting COMMANDS to a single command is not good either, since them
# the user herself would use {} or (), and then we face the same problem.
#
# But then, there is no point in running
#
# ( $at_traceon { $1 ; } >at-stdout 2>at-stder1 )
#
# instead of the simpler
#
# ( $at_traceon; $1 ) >at-stdout 2>at-stder1
#
m4_define([_AT_CHECK],
[$at_traceoff
echo "$at_srcdir/AT_LINE: AS_ESCAPE([$1])"
echo AT_LINE >"$at_check_line_file"
at_trace_this=
if test -n "$at_traceon"; then
_AT_DECIDE_TRACEABLE([$1])
fi
if test -n "$at_trace_this"; then
( $at_traceon; $1 ) >"$at_stdout" 2>"$at_stder1"
at_status=$?
grep '^ *+' "$at_stder1" >&2
grep -v '^ *+' "$at_stder1" >"$at_stderr"
else
( :; $1 ) >"$at_stdout" 2>"$at_stderr"
at_status=$?
fi
at_failed=false
dnl Check stderr.
m4_case([$4],
stderr, [echo stderr:; tee stderr <"$at_stderr"],
ignore, [echo stderr:; cat "$at_stderr"],
experr, [$at_diff experr "$at_stderr" || at_failed=:],
[], [$at_diff "$at_devnull" "$at_stderr" || at_failed=:],
[echo >>"$at_stderr"; echo "m4_ifval([$7],[AS_ESCAPE([$4])],[$4])" | $at_diff - "$at_stderr" || at_failed=:])
dnl Check stdout.
m4_case([$3],
stdout, [echo stdout:; tee stdout <"$at_stdout"],
ignore, [echo stdout:; cat "$at_stdout"],
expout, [$at_diff expout "$at_stdout" || at_failed=:],
[], [$at_diff "$at_devnull" "$at_stdout" || at_failed=:],
[echo >>"$at_stdout"; echo "m4_ifval([$7],[AS_ESCAPE([$3])],[$3])" | $at_diff - "$at_stdout" || at_failed=:])
dnl Check exit val. Don't `skip' if we are precisely checking $? = 77.
case $at_status in
m4_if([$2], [77],
[],
[ 77) echo 77 > "$at_status_file"; exit 77;;
])dnl
m4_if([$2], [ignore],
[ *);;],
[ m4_default([$2], [0])) ;;
*) echo "$at_srcdir/AT_LINE: exit code was $at_status, expected m4_default([$2], [0])"
at_failed=:;;])
esac
AS_IF($at_failed, [$5
m4_ifdef([AT_capture_files],
[for file in AT_capture_files
do echo "$file:"; sed 's/^/> /' "$file"; done])
echo 1 > "$at_status_file"
exit 1], [$6])
$at_traceon
])# _AT_CHECK