Current Path : /compat/linux/proc/self/root/usr/local/share/autoconf-2.62/autotest/ |
FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64 |
Current File : //compat/linux/proc/self/root/usr/local/share/autoconf-2.62/autotest/general.m4 |
# This file is part of Autoconf. -*- Autoconf -*- # M4 macros used in building test suites. # Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # 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. # # - BANNERS # Output shell initialization for the associative array of banner text. # - 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. # - 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. # # - TEST_SCRIPT # The collector for code for each test, the ``normal'' diversion, but # undiverted into other locations before final output. # # - TEST_GROUPS # Contents of each test group. The tests deliberately occur after the # end of the shell script, so that the shell need not spend time parsing # commands it will not execute. 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(BANNERS)], 400) 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) # 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 recompiles the regular expression for every m4_bpatsubst, but __file__ # rarely changes. Be fast - only compute the dirname when necessary; for # autoconf alone, this shaves off several seconds in building testsuite. m4_define([_AT_LINE_file]) m4_define([_AT_LINE_base]) m4_define([AT_LINE], [m4_if(m4_defn([_AT_LINE_file]), __file__, [], [m4_do([m4_define([_AT_LINE_file], __file__)], [m4_define([_AT_LINE_base], m4_bregexp(/__file__, [/\([^/]*\)$], [[\1]]))])])dnl m4_defn([_AT_LINE_base]):__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], [ eval 'while :; do case $$1 in #( '"$at_format"'*) break;; esac $1=0$$1 done' ]) # _AT_DEFINE_INIT(NAME, [DEFINITION]) # ----------------------------------- # Define macro NAME to die if invoked prior to AT_INIT, and to DEFINITION # after AT_INIT. m4_define([_AT_DEFINE_INIT], [m4_define($@)m4_pushdef([$1], [m4_fatal([$1: missing AT_INIT detected])])dnl m4_append([_AT_DEFINE_INIT_LIST], [[$1]], [,])]) # _AT_DEFINE_SETUP(NAME, [DEFINITION]) # ----------------------------------- # Define macro NAME to die if invoked outside AT_SETUP/AT_CLEANUP, and # to DEFINITION otherwise. m4_define([_AT_DEFINE_SETUP], [m4_define([$1], [m4_ifndef([AT_ingroup], [m4_fatal([$1: missing AT_SETUP detected])])$2])]) # AT_INIT([TESTSUITE-NAME]) # ------------------------- # Begin test suite. m4_define([AT_INIT], [m4_pushdef([AT_INIT], [m4_fatal([$0: invoked multiple times])]) m4_pattern_forbid([^_?AT_]) m4_pattern_allow([^_AT_T_EOF$]) m4_define([AT_TESTSUITE_NAME], m4_defn([AT_PACKAGE_STRING])[ test suite]m4_ifval([$1], [m4_expand([: $1])])) m4_define([AT_ordinal], 0) m4_define([AT_banner_ordinal], 0) m4_define([AT_groups_all], []) m4_define([AT_help_all], []) m4_foreach([AT_name], [_AT_DEFINE_INIT_LIST], [m4_popdef(m4_defn([AT_name]))]) m4_wrap([_AT_FINISH]) AS_INIT[]dnl m4_divert_push([DEFAULTS])dnl AT_COPYRIGHT( [Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 SHELL=${CONFIG_SHELL-/bin/sh} # How were we run? at_cli_args="$[@]" m4_divert_push([BANNERS])dnl # Should we print banners? at_groups is space-separated for entire test, # newline-separated if only a subset of the testsuite is run. case $at_groups in *' '*' '* | *"$as_nl"*"$as_nl"* ) at_print_banners=: ;; * ) at_print_banners=false ;; esac # Text for banner N, set to empty once printed. m4_divert_pop([BANNERS])dnl back to DEFAULTS m4_divert_push([PREPARE_TESTS])dnl ## --------------- ## ## Shell functions ## ## --------------- ## # at_func_banner NUMBER # --------------------- # Output banner NUMBER, provided the testsuite is running multiple groups # and this particular banner has not yet been printed. at_func_banner () { $at_print_banners || return 0 eval at_banner_text=\$at_banner_text_$[1] test "x$at_banner_text" = x && return 0 eval at_banner_text_$[1]= AS_ECHO(["$as_nl$at_banner_text$as_nl"]) } # at_func_banner # at_func_check_newline COMMAND # ----------------------------- # Test if COMMAND includes a newline and, if so, print a message and return # exit code 1 at_func_check_newline () { case "$[1]" in *' '*) echo 'Not enabling shell tracing (command contains an embedded newline)' return 1 ;; *) return 0 ;; esac } # at_func_filter_trace EXIT-CODE # ------------------------------ # Split the contents of file "$at_stder1" into the "set -x" trace (on stderr) # and the other lines (on file "$at_stderr"). Return the exit code EXIT-CODE. at_func_filter_trace () { grep '^ *+' "$at_stder1" >&2 grep -v '^ *+' "$at_stder1" >"$at_stderr" return $[1] } # at_func_log_failure FILE-LIST # ----------------------------- # Copy the files in the list on stdout with a "> " prefix, and exit the shell # with a failure exit code. at_func_log_failure () { for file do AS_ECHO(["$file:"]); sed 's/^/> /' "$file"; done echo 1 > "$at_status_file" exit 1 } # at_func_check_skip EXIT-CODE # ---------------------------- # Check whether EXIT-CODE is the special exit code 77, and if so exit the shell # with that same exit code. at_func_check_skip () { case $[1] in 77) echo 77 > "$at_status_file"; exit 77;; esac } # at_func_check_status EXPECTED EXIT-CODE LINE # -------------------------------------------- # Check whether EXIT-CODE is the expected exit code, and if so do nothing. # Otherwise, if it is 77 exit the shell with that same exit code; if it is # anything else print an error message and fail the test. at_func_check_status () { dnl This order ensures that we don't `skip' if we are precisely checking dnl $? = 77. case $[2] in $[1] ) ;; 77) echo 77 > "$at_status_file"; exit 77;; *) AS_ECHO(["$[3]: exit code was $[2], expected $[1]"]) at_failed=:;; esac } # at_func_diff_devnull FILE # ------------------------- # Emit a diff between /dev/null and FILE. Uses "test -s" to avoid useless # diff invocations. at_func_diff_devnull () { test -s "$[1]" || return 0 $at_diff "$at_devnull" "$[1]" } # at_func_test NUMBER # ------------------- # Parse out test NUMBER from the tail of this file. at_func_test () { eval at_sed=\$at_sed$[1] sed "$at_sed" "$at_myself" > "$at_test_source" } # at_func_create_debugging_script # ------------------------------- # Create the debugging script $at_group_dir/run which will reproduce the # current test group. at_func_create_debugging_script () { { echo "#! /bin/sh" && echo 'test "${ZSH_VERSION+set}" = set dnl && alias -g '\''${1+"$[@]"}'\''='\''"$[@]"'\''' && AS_ECHO(["cd '$at_dir'"]) && AS_ECHO(["exec \${CONFIG_SHELL-$SHELL} \"$at_myself\" -v -d ]dnl [$at_debug_args $at_group \${1+\"\$[@]\"}"]) && echo 'exit 1' } >"$at_group_dir/run" && chmod +x "$at_group_dir/run" } # at_func_arith # ------------- # Arithmetic evaluation, avoids expr if the shell is sane. # # subshell and eval are needed to keep Solaris sh from bailing out: if ( eval 'test $(( 1 + 1 )) = 2' ) 2>/dev/null; then [#] With "$[@]", bash does not split positional parameters: eval 'at_func_arith () { at_func_arith_result=$(( $[*] )) }' else at_func_arith () { at_func_arith_result=`expr "$[@]"` } fi ## ---------------------- ## ## End of shell functions ## ## ---------------------- ## m4_divert_pop([PREPARE_TESTS])dnl back to DEFAULTS # 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? ':' means no, empty means yes. at_verbose=: at_quiet= # 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 # --clean at_clean=false # Test groups to run at_groups= # Whether a write failure occurred at_write_fail=0 # The directory we run the suite in. Default to . if no -C option. at_dir=`pwd` # An absolute reference to this testsuite script. dnl m4-double quote, to preserve [] [case $as_myself in [\\/]* | ?:[\\/]* ) at_myself=$as_myself ;; * ) at_myself=$at_dir/$as_myself ;; esac] # Whether -C is in effect. at_change_dir=false m4_divert_pop([DEFAULTS])dnl m4_define([_AT_FINISH], [m4_ifdef([AT_ingroup], [m4_fatal([missing AT_CLEANUP detected])])dnl m4_divert_text([DEFAULTS], [ # List of the tested programs. at_tested='m4_ifdef([AT_tested], [m4_translit(m4_dquote(m4_defn([AT_tested])), [ ], m4_newline)])' # 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_dquote(m4_defn([AT_help_all])))" # at_func_validate_ranges [N...] # ------------------------------ # validate test group ranges at_func_validate_ranges () { for at_grp do if test $at_grp -lt 1 || test $at_grp -gt AT_ordinal; then AS_ECHO(["invalid test group: $at_grp"]) >&2 exit 1 fi done }])])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 ) at_clean=: ;; --debug | -d ) at_debug_p=: ;; --errexit | -e ) at_debug_p=: at_errexit_p=: ;; --verbose | -v ) at_verbose=; 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_func_validate_ranges $at_option 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_func_validate_ranges $at_range_start at_range=`AS_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_func_validate_ranges $at_range_end at_range=`AS_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_func_validate_ranges $at_range_start $at_range_end at_range=`AS_ECHO([" $at_groups_all "]) | \ sed -e 's/^.*\( '$at_range_start' \)/\1/' \ -e 's/\( '$at_range_end'\) .*$/\1/'` at_groups="$at_groups$at_range " ;; # Directory selection. --directory | -C ) at_prev=--directory ;; --directory=* ) at_change_dir=: at_dir=$at_optarg ;; # 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=`AS_ECHO(["$at_groups_selected"]) | grep -i $at_invert ["^[1-9][^;]*;.*[; ]$at_keyword[ ;]"]` done # Smash the newlines. at_groups_selected=`AS_ECHO(["$at_groups_selected"]) | sed 's/;.*//' | tr "$as_nl" ' ' ` at_groups="$at_groups$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. case $at_envvar in '' | [[0-9]]* | *[[!_$as_cr_alnum]]* ) AS_ERROR([invalid variable name: $at_envvar]) ;; esac at_value=`AS_ECHO(["$at_optarg"]) | sed "s/'/'\\\\\\\\''/g"` # Export now, but save eval for later and for debug scripts. export $at_envvar at_debug_args="$at_debug_args $at_envvar='$at_value'" ;; *) AS_ECHO(["$as_me: invalid option: $at_option"]) >&2 AS_ECHO(["Try \`$[0] --help' for more information."]) >&2 exit 1 ;; esac done # Verify our last option didn't require an argument AS_IF([test -n "$at_prev"], [AS_ERROR([`$at_prev' requires an argument.])]) # Selected test groups. if test -z "$at_groups"; then at_groups=$at_groups_all else # Sort the tests, removing duplicates. at_groups=`AS_ECHO(["$at_groups"]) | tr ' ' "$as_nl" | sort -nu` fi m4_divert_pop([PARSE_ARGS_END])dnl m4_divert_push([HELP])dnl # Help message. if $at_help_p; then cat <<_ATEOF || at_write_fail=1 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 || at_write_fail=1 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 || at_write_fail=1 dnl extra quoting prevents emacs whitespace mode from putting tabs in output Execution tuning: -C, --directory=DIR [ change to directory DIR before starting] -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 || at_write_fail=1 Report bugs to <AT_PACKAGE_BUGREPORT>. _ATEOF exit $at_write_fail fi # List of tests. if $at_list_p; then cat <<_ATEOF || at_write_fail=1 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'. # at_groups needs to be space-separated for this script to work. case $at_groups in *"$as_nl"* ) at_groups=`AS_ECHO(["$at_groups"]) | tr "$as_nl" ' '` ;; esac AS_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 } }' || at_write_fail=1 exit $at_write_fail fi m4_divert_pop([HELP_END])dnl m4_divert_push([VERSION])dnl if $at_version_p; then AS_ECHO(["$as_me (AT_PACKAGE_STRING)"]) && cat <<\_ACEOF || at_write_fail=1 m4_divert_pop([VERSION])dnl m4_divert_push([VERSION_END])dnl _ACEOF exit $at_write_fail fi m4_divert_pop([VERSION_END])dnl m4_divert_push([TESTS_BEGIN])dnl # Take any -C into account. if $at_change_dir ; then if test x- = "x$at_dir" ; then at_dir=./- fi test x != "x$at_dir" && cd "$at_dir" \ || AS_ERROR([unable to change directory]) at_dir=`pwd` fi # Load the config files for any default variable assignments. 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} # Perform any assignments requested during argument parsing. eval "$at_debug_args" # 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_var in srcdir top_srcdir top_build_prefix do at_val=AS_VAR_GET([at_$at_dir_var]) case $at_val in [[\\/$]]* | ?:[[\\/]]* ) at_prefix= ;; *) at_prefix=../../ ;; esac AS_VAR_SET([$at_dir_var], [$at_prefix$at_val]) done fi # The directory the whole suite works in. # Should be absolute 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 the function to run a test group. at_test_source=$at_suite_dir/at-test-source # The file containing dates. at_times_file=$at_suite_dir/at-times if $at_clean; then 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 $? fi # Don't take risks: use only absolute directories in PATH. # # For stand-alone test suites (ie. atconfig was not found), # 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=`AS_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. at_new_path= _AS_PATH_WALK([$at_path], [test -d "$as_dir" || continue case $as_dir in [[\\/]]* | ?:[[\\/]]* ) ;; * ) as_dir=`(cd "$as_dir" && pwd) 2>/dev/null` ;; esac case $PATH_SEPARATOR$at_new_path$PATH_SEPARATOR in *$PATH_SEPARATOR$as_dir$PATH_SEPARATOR*) ;; $PATH_SEPARATOR$PATH_SEPARATOR) at_new_path=$as_dir ;; *) at_new_path=$at_new_path$PATH_SEPARATOR$as_dir ;; esac]) PATH=$at_new_path 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 AS_ECHO(["$as_me: command line was:"]) AS_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. Prune directories # matching the package tarname, since they tend to be leftovers from # `make dist' or `make distcheck' and contain redundant or stale logs. if test -n "$at_top_srcdir"; then AS_BOX([ChangeLogs.]) echo for at_file in `find "$at_top_srcdir" m4_ifdef([AT_PACKAGE_TARNAME], [-name "AT_PACKAGE_TARNAME-*" -prune -o ])-name ChangeLog -print` do AS_ECHO(["$as_me: $at_file:"]) sed 's/^/| /;10q' $at_file echo done fi AS_UNAME echo # Contents of the config files. for at_file in atconfig atlocal do test -r $at_file || continue AS_ECHO(["$as_me: $at_file:"]) 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 # 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 { AS_ECHO(["$at_srcdir/AT_LINE: $as_dir/$at_program --version"]) "$as_dir/$at_program" --version </dev/null 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` AS_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 # Get the last needed group. for at_group in : $at_groups; do :; done # Extract the start and end lines of each test group at the tail # of this file awk ' BEGIN { FS="" } /^@%:@AT_START_/ { start = NR } /^@%:@AT_STOP_/ { test = substr ($ 0, 10) print "at_sed" test "=\"1," start "d;" (NR-1) "q\"" if (test == "'"$at_group"'") exit }' "$at_myself" > "$at_test_source" && . "$at_test_source" || AS_ERROR([cannot create test line number cache]) m4_text_box([Driver loop.]) for at_group in $at_groups do # Be sure to come back to the top test directory. cd "$at_suite_dir" # Clearly separate the test groups when verbose. test $at_group_count != 0 && $at_verbose echo 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" || AS_WARN([test directory could not be cleaned.]) fi # Be tolerant if the above `rm' was not able to remove the directory. AS_MKDIR_P(["$at_group_dir"]) cd "$at_group_dir" echo 0 > "$at_status_file" # In verbose mode, append to the log file *and* show on # the standard output; in quiet mode only write to the log if test -z "$at_verbose"; then at_tee_pipe='tee -a "$at_group_log"' else at_tee_pipe='cat >> "$at_group_log"' fi if at_func_test $at_group && . "$at_test_source"; then :; else AS_ECHO(["$as_me: unable to parse test group: $at_group"]) >&2 at_failed=: fi # 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" 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 AS_ECHO(["$at_setup_line"]) >"$at_check_line_file" fi at_func_arith 1 + $at_group_count at_group_count=$at_func_arith_result $at_verbose AS_ECHO_N(["$at_group. $at_setup_line: "]) AS_ECHO_N(["$at_group. $at_setup_line: "]) >> "$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. AS_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 AS_ECHO(["$at_log_msg"]) >> "$at_group_log" AS_ECHO(["$at_log_msg"]) >&AS_MESSAGE_LOG_FD # Cleanup the group directory, unless the user wants the files. if $at_debug_p ; then at_func_create_debugging_script else 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 rm -f "$at_test_source" 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. AS_ECHO(["$at_log_msg"]) >> "$at_group_log" # Upon failure, keep the group directory for autopsy, and # create the debugging script. at_func_create_debugging_script $at_errexit && break ;; 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` AS_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_func_arith $at_stop_time - $at_start_time at_duration_s=$at_func_arith_result at_func_arith $at_duration_s / 60 at_duration_m=$at_func_arith_result at_func_arith $at_duration_m / 60 at_duration_h=$at_func_arith_result at_func_arith $at_duration_s % 60 at_duration_s=$at_func_arith_result at_func_arith $at_duration_m % 60 at_duration_m=$at_func_arith_result at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s" AS_ECHO(["$as_me: test suite duration: $at_duration"]) >&AS_MESSAGE_LOG_FD ;; esac # Wrap up the test suite with summary statistics. set X $at_skip_list; shift; at_skip_count=$[@%:@] set X $at_fail_list; shift; at_fail_count=$[@%:@] set X $at_xpass_list; shift; at_xpass_count=$[@%:@] set X $at_xfail_list; shift; at_xfail_count=$[@%:@] at_func_arith $at_group_count - $at_skip_count at_run_count=$at_func_arith_result at_func_arith $at_xpass_count + $at_fail_count at_unexpected_count=$at_func_arith_result at_func_arith $at_xfail_count + $at_fail_count at_total_fail_count=$at_func_arith_result 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 dnl ($at_fail_count unexpected failure)." ;; *:*:0) at_result="$at_result $at_were run, $at_unexpected_count did not behave as expected dnl ($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 "$at_myself" $at_fail_list --list echo fi if test $at_skip_count != 0; then echo "Skipped tests:" $SHELL "$at_myself" $at_skip_list --list echo fi if test $at_xpass_count != 0; then echo "Unexpected passes:" $SHELL "$at_myself" $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 AS_ECHO(["Please send \`${at_testdir+${at_testdir}/}$as_me.log' ]dnl [and all information you think might help: To: <AT_PACKAGE_BUGREPORT> 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} "]) 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' AS_ECHO(["be found below \`${at_testdir+${at_testdir}/}$as_me.dir'."]) echo fi exit 1 fi exit 0 m4_text_box([Actual tests.]) m4_divert_pop([TESTS])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 || at_write_fail=1 Other options: _ATEOF ])dnl m4_divert_once HELP_OTHER m4_divert_text([HELP_OTHER], [cat <<_ATEOF || at_write_fail=1 $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_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_w([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. _AT_DEFINE_INIT([AT_SETUP], [m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])], [m4_define([AT_ingroup])]) m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])]) m4_define([AT_capture_files], []) m4_define([AT_line], AT_LINE) m4_define([AT_xfail], [at_xfail=no]) m4_define([AT_description], m4_expand([$1])) m4_define([AT_ordinal], m4_incr(AT_ordinal)) m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal])) m4_divert_push([TEST_GROUPS])dnl [#AT_START_]AT_ordinal @%:@ AT_ordinal. m4_defn([AT_line]): m4_defn([AT_description]) at_setup_line='m4_defn([AT_line])' m4_if(AT_banner_ordinal, [0], [], [at_func_banner AT_banner_ordinal ])dnl at_desc="AS_ESCAPE(m4_dquote(m4_defn([AT_description])))" $at_quiet AS_ECHO_N([m4_format(["%3d: $at_desc%*s"], AT_ordinal, m4_max(0, m4_eval(47 - m4_qlen(m4_defn([AT_description])))), [])]) 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). _AT_DEFINE_SETUP([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. # The list is stored in lower case, since the -k option is case-insensitive. _AT_DEFINE_SETUP([AT_KEYWORDS], [m4_append_uniq_w([AT_keywords], m4_tolower([[$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. _AT_DEFINE_SETUP([AT_CAPTURE_FILE], [m4_append_uniq([AT_capture_files], ["$1"], [ \ ])]) # AT_CLEANUP # ---------- # Complete a group of related tests. _AT_DEFINE_INIT([AT_CLEANUP], [m4_ifdef([AT_ingroup], [m4_undefine([AT_ingroup])], [m4_fatal([$0: missing AT_SETUP detected])])dnl m4_append([AT_help_all], m4_defn([AT_ordinal]);m4_defn([AT_line]);m4_defn([AT_description]);dnl m4_ifdef([AT_keywords], [m4_defn([AT_keywords])]); )dnl m4_divert_pop([TEST_SCRIPT])dnl Back to TEST_GROUPS AT_xfail echo "# -*- compilation -*-" >> "$at_group_log" ( AS_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"` [#AT_STOP_]AT_ordinal m4_divert_pop([TEST_GROUPS])dnl Back to KILL. ])# AT_CLEANUP # AT_BANNER([TEXT]) # ----------------- # Start a category of related test groups. If multiple groups are executed, # output TEXT as a banner without any shell expansion, prior to any test # from the category. If TEXT is empty, no banner is printed. _AT_DEFINE_INIT([AT_BANNER], [m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])])dnl m4_define([AT_banner_ordinal], m4_incr(AT_banner_ordinal)) m4_divert_text([BANNERS], [@%:@ Banner AT_banner_ordinal. AT_LINE @%:@ Category starts at test group m4_incr(AT_ordinal). at_banner_text_[]AT_banner_ordinal="AS_ESCAPE([$1])"])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. _AT_DEFINE_SETUP([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' # # You might wonder why you can't just use `ignore', then directly use stdout # and stderr left by the test suite: # # AT_CHECK([command], [], [ignore]) # AT_CHECK([check stdout]) # # If the test suite always captured data in the file `stdout', then the # second command would be trying to read and write from the same file, with # undefined behavior. Therefore, the test suite actually captures data in # an internal file of a different name, and only creates `stdout' when # explicitly requested. # # 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'. # _AT_DEFINE_SETUP([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. _AT_DEFINE_SETUP([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 evaluate to true. Otherwise, # the shell code will print a message stating an aspect of COMMANDS that makes # tracing them unsafe, and evaluate to false. # # 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 macro. dnl dnl Examine COMMANDS for a reason to never trace COMMANDS. [m4_pushdef([at_reason], m4_cond([m4_eval(m4_index([$1], [`]) >= 0)], [1], [[a `...` command substitution]], [m4_eval(m4_index([$1], [$(]) >= 0)], [1], [[a $(...) command substitution]], [m4_eval(m4_index([$1], [${]) >= 0)], [1], [[a ${...} parameter expansion]], [m4_eval(m4_index([$1], m4_newline) >= 0)], [1], [[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])[)' false; }], [m4_if(m4_index([$1], [$]), [-1], dnl We know at build time that tracing COMMANDS is always safe. [test -n "$at_traceon"], dnl COMMANDS may contain parameter expansions; expand them at runtime. [test -n "$at_traceon" \ && at_func_check_newline "AS_ESCAPE([$1], [`\"])"])])[]dnl m4_popdef([at_reason])]) # AT_DIFF_STDERR/AT_DIFF_STDOUT # ----------------------------- # These are subroutines of AT_CHECK. Using indirect dispatch is a tad # faster than using m4_case, and these are called very frequently. m4_define([AT_DIFF_STDERR(stderr)], [echo stderr:; tee stderr <"$at_stderr"]) m4_define([AT_DIFF_STDERR(ignore)], [echo stderr:; cat "$at_stderr"]) m4_define([AT_DIFF_STDERR(experr)], [$at_diff experr "$at_stderr" || at_failed=:]) m4_define([AT_DIFF_STDERR()], [at_func_diff_devnull "$at_stderr" || at_failed=:]) m4_define([AT_DIFF_STDOUT(stdout)], [echo stdout:; tee stdout <"$at_stdout"]) m4_define([AT_DIFF_STDOUT(ignore)], [echo stdout:; cat "$at_stdout"]) m4_define([AT_DIFF_STDOUT(expout)], [$at_diff expout "$at_stdout" || at_failed=:]) m4_define([AT_DIFF_STDOUT()], [at_func_diff_devnull "$at_stdout" || at_failed=:]) # _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 AS_ECHO(["$at_srcdir/AT_LINE: AS_ESCAPE([$1])"]) echo AT_LINE >"$at_check_line_file" if _AT_DECIDE_TRACEABLE([$1]); then ( $at_traceon; $1 ) >"$at_stdout" 2>"$at_stder1" at_func_filter_trace $? else ( :; $1 ) >"$at_stdout" 2>"$at_stderr" fi at_status=$? at_failed=false m4_ifdef([AT_DIFF_STDERR($4)], [m4_indir([AT_DIFF_STDERR($4)])], [echo >>"$at_stderr"; AS_ECHO(["m4_ifval([$7],[AS_ESCAPE([$4])],[$4])"]) | \ $at_diff - "$at_stderr" || at_failed=:]) m4_ifdef([AT_DIFF_STDOUT($3)], [m4_indir([AT_DIFF_STDOUT($3)])], [echo >>"$at_stdout"; AS_ECHO(["m4_ifval([$7],[AS_ESCAPE([$3])],[$3])"]) | \ $at_diff - "$at_stdout" || at_failed=:]) m4_if([$2], [ignore], [at_func_check_skip], [at_func_check_status m4_default([$2], [0])]) $at_status "$at_srcdir/AT_LINE" AS_IF($at_failed, [$5], [$6]) $at_failed && at_func_log_failure AT_capture_files $at_traceon; } ])# _AT_CHECK