revert previous push
[autoconf.git] / lib / autotest / general.m4
bloba032462b7e84fe964e38403686a4d807fa4c37a2
1 # This file is part of Autoconf.                          -*- Autoconf -*-
2 # M4 macros used in building test suites.
3 m4_define([_AT_COPYRIGHT_YEARS],
4 [Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
5 2009 Free Software Foundation, Inc.])
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2, or (at your option)
10 # any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 # 02110-1301, USA.
22 # As a special exception, the Free Software Foundation gives unlimited
23 # permission to copy, distribute and modify the configure scripts that
24 # are the output of Autoconf.  You need not follow the terms of the GNU
25 # General Public License when using or distributing such scripts, even
26 # though portions of the text of Autoconf appear in them.  The GNU
27 # General Public License (GPL) does govern all other use of the material
28 # that constitutes the Autoconf program.
30 # Certain portions of the Autoconf source text are designed to be copied
31 # (in certain cases, depending on the input) into the output of
32 # Autoconf.  We call these the "data" portions.  The rest of the Autoconf
33 # source text consists of comments plus executable code that decides which
34 # of the data portions to output in any given case.  We call these
35 # comments and executable code the "non-data" portions.  Autoconf never
36 # copies any of the non-data portions into its output.
38 # This special exception to the GPL applies to versions of Autoconf
39 # released by the Free Software Foundation.  When you make and
40 # distribute a modified version of Autoconf, you may extend this special
41 # exception to the GPL to apply to your modified version as well, *unless*
42 # your modified version has the potential to copy into its output some
43 # of the text that was the non-data portion of the version that you started
44 # with.  (In other words, unless your change moves or copies text from
45 # the non-data portions to the data portions.)  If your modification has
46 # such potential, you must delete any notice of this special exception
47 # to the GPL from your modified version.
49 # _m4_divert(DIVERSION-NAME)
50 # --------------------------
51 # Convert a diversion name into its number.  Otherwise, return
52 # DIVERSION-NAME which is supposed to be an actual diversion number.
53 # Of course it would be nicer to use m4_case here, instead of zillions
54 # of little macros, but it then takes twice longer to run `autoconf'!
56 # From M4sugar:
57 #    -1. KILL
58 # 10000. GROW
60 # From M4sh:
61 #    0. BINSH
62 #    1. HEADER-REVISION
63 #    2. HEADER-COMMENT
64 #    3. HEADER-COPYRIGHT
65 #    4. M4SH-SANITIZE
66 #    5. M4SH-INIT
67 # 1000. BODY
69 # Defined below:
70 #  - DEFAULTS
71 #    Overall initialization, value of $at_groups_all.
72 #  - PARSE_ARGS_BEGIN
73 #    Setup defaults required for option processing.
74 #  - PARSE_ARGS
75 #    Option processing.  After AT_INIT, user options can be entered here as
76 #    cases of a case statement.
77 #  - PARSE_ARGS_END
78 #    Finish up the option processing.
80 #  - HELP
81 #    Start printing the help message.
82 #  - HELP_MODES
83 #    Modes help text.  Additional modes can be appended as self-contained
84 #    cat'd here-docs as generated by AS_HELP_STRING.
85 #  - HELP_TUNING
86 #    Tuning help text.  Additional tuning options can be appended as
87 #    self-contained cat'd here-docs as generated by AS_HELP_STRING.
88 #  - HELP_OTHER
89 #    User help can be appended to this as self-contained cat'd here-docs.
90 #  - HELP_END
91 #    Finish up the help texts.
93 #  - VERSION
94 #    Head of the handling of --version.
95 #  - VERSION_NOTICES
96 #    Copyright notices for --version.
97 #  - VERSION_END
98 #    Tail of the handling of --version.
100 #  - BANNERS
101 #    Output shell initialization for the associative array of banner text.
102 #  - TESTS_BEGIN
103 #    Like DEFAULTS but run after argument processing for purposes of
104 #    optimization.  Do anything else that needs to be done to prepare for
105 #    tests.  Sets up verbose and log file descriptors.  Sets and logs PATH.
106 #  - PREPARE_TESTS
107 #    Declares functions shared among the tests.  Perform any user
108 #    initialization to be shared among all tests.
109 #  - TESTS
110 #    The core of the test suite.
112 #  - TEST_SCRIPT
113 #    The collector for code for each test, the ``normal'' diversion, but
114 #    undiverted into other locations before final output.
116 #  - TEST_GROUPS
117 #    Contents of each test group.  The tests deliberately occur after the
118 #    end of the shell script, so that the shell need not spend time parsing
119 #    commands it will not execute.
121 m4_define([_m4_divert(DEFAULTS)],           100)
122 m4_define([_m4_divert(PARSE_ARGS_BEGIN)],   200)
123 m4_define([_m4_divert(PARSE_ARGS)],         201)
124 m4_define([_m4_divert(PARSE_ARGS_END)],     202)
125 m4_define([_m4_divert(HELP)],               300)
126 m4_define([_m4_divert(HELP_MODES)],         301)
127 m4_define([_m4_divert(HELP_TUNING)],        302)
128 m4_define([_m4_divert(HELP_OTHER)],         303)
129 m4_define([_m4_divert(HELP_END)],           304)
130 m4_define([_m4_divert(VERSION)],            350)
131 m4_define([_m4_divert(VERSION_NOTICES)],    351)
132 m4_define([_m4_divert(VERSION_END)],        352)
133 m4_define([_m4_divert(BANNERS)],            400)
134 m4_define([_m4_divert(TESTS_BEGIN)],        401)
135 m4_define([_m4_divert(PREPARE_TESTS)],      402)
136 m4_define([_m4_divert(TESTS)],              403)
137 m4_define([_m4_divert(TEST_SCRIPT)],        450)
138 m4_define([_m4_divert(TEST_GROUPS)],        500)
141 # AT_LINE
142 # -------
143 # Return the current file sans directory, a colon, and the current
144 # line.  Be sure to return a _quoted_ file name, so if, for instance,
145 # the user is lunatic enough to have a file named `dnl' (and I, for
146 # one, love to be brainless and stubborn sometimes), then we return a
147 # quoted name.
149 # Gee, we can't use simply
151 #  m4_bpatsubst(__file__, [^.*/\(.*\)], [[\1]])
153 # since then, since `dnl' doesn't match the pattern, it is returned
154 # with once quotation level less, so you lose!  And since GNU M4
155 # is one of the biggest junk in the whole universe wrt regexp, don't
156 # even think about using `?' or `\?'.  Bah, `*' will do.
157 # Pleeeeeeeease, Gary, provide us with dirname and ERE!
159 # M4 recompiles the regular expression for every m4_bpatsubst, but __file__
160 # rarely changes.  Be fast - only compute the dirname when necessary; for
161 # autoconf alone, this shaves off several seconds in building testsuite.
162 m4_define([_AT_LINE_file])
163 m4_define([_AT_LINE_base])
164 m4_define([AT_LINE],
165 [m4_if(m4_defn([_AT_LINE_file]), __file__, [],
166        [m4_do([m4_define([_AT_LINE_file], __file__)],
167               [m4_define([_AT_LINE_base],
168                          m4_bregexp(/__file__, [/\([^/]*\)$], [[\1]]))])])dnl
169 m4_defn([_AT_LINE_base]):__line__])
172 # _AT_NORMALIZE_TEST_GROUP_NUMBER(SHELL-VAR)
173 # ------------------------------------------
174 # Normalize SHELL-VAR so that its value has the same number of digits as
175 # all the other test group numbers.
176 m4_define([_AT_NORMALIZE_TEST_GROUP_NUMBER],
178   eval 'while :; do
179     case $$1 in #(
180     '"$at_format"'*) break;;
181     esac
182     $1=0$$1
183   done'
186 # _AT_DEFINE_INIT(NAME, [DEFINITION])
187 # -----------------------------------
188 # Define macro NAME to die if invoked prior to AT_INIT, and to DEFINITION
189 # after AT_INIT.
190 m4_define([_AT_DEFINE_INIT],
191 [m4_define($@)m4_pushdef([$1], [m4_fatal([$1: missing AT_INIT detected])])dnl
192 m4_append([_AT_DEFINE_INIT_LIST], [[$1]], [,])])
194 # _AT_DEFINE_SETUP(NAME, [DEFINITION])
195 # -----------------------------------
196 # Define macro NAME to die if invoked outside AT_SETUP/AT_CLEANUP, and
197 # to DEFINITION otherwise.
198 m4_define([_AT_DEFINE_SETUP],
199 [m4_define([$1], [m4_ifndef([AT_ingroup],
200  [m4_fatal([$1: missing AT_SETUP detected])])$2])])
203 # AT_INIT([TESTSUITE-NAME])
204 # -------------------------
205 # Begin test suite.
206 m4_define([AT_INIT],
207 [m4_pushdef([AT_INIT], [m4_fatal([$0: invoked multiple times])])]
208 [m4_pattern_forbid([^_?AT_])]
209 [m4_pattern_allow([^_ATEOF$])]
210 [m4_ifndef([AT_PACKAGE_BUGREPORT], [m4_fatal(
211   [$1: AT_PACKAGE_BUGREPORT is missing, consider writing package.m4])])]
212 [m4_define([AT_TESTSUITE_NAME],
213   m4_defn([AT_PACKAGE_STRING])[ test suite]m4_ifval([$1],
214    [m4_expand([: $1])]))]
215 [m4_define([AT_ordinal], 0)]
216 [m4_define([AT_banner_ordinal], 0)]
217 [m4_define([AT_groups_all], [])]
218 [m4_define([AT_help_all], [])]
219 [m4_map_args([_m4_popdef], _AT_DEFINE_INIT_LIST)]
220 [m4_wrap([_AT_FINISH])]
221 [AS_INIT[]]dnl
222 dnl We don't use m4sh's BODY diversion, but AS_INIT sticks a banner there.
223 dnl This trick removes that banner, since it adds nothing to autotest.
224 [m4_cleardivert([BODY])]dnl
225 [AS_ME_PREPARE[]]dnl
226 [m4_divert_push([DEFAULTS])]dnl
227 [AT_COPYRIGHT(m4_defn([_AT_COPYRIGHT_YEARS]), [
228 m4_copyright_condense])]
229 [AT_COPYRIGHT(
230 [This test suite is free software; the Free Software Foundation gives
231 unlimited permission to copy, distribute and modify it.], [m4_echo])]
232 [AS_PREPARE
234 SHELL=${CONFIG_SHELL-/bin/sh}
236 # How were we run?
237 at_cli_args="$[@]"
239 m4_divert_push([BANNERS])dnl
241 # Should we print banners?  at_groups is space-separated for entire test,
242 # newline-separated if only a subset of the testsuite is run.
243 case $at_groups in
244   *' '*' '* | *"$as_nl"*"$as_nl"* )
245       at_print_banners=: ;;
246   * ) at_print_banners=false ;;
247 esac
248 # Text for banner N, set to empty once printed.
249 m4_divert_pop([BANNERS])dnl back to DEFAULTS
250 m4_divert_push([PREPARE_TESTS])dnl
252 m4_text_box([Autotest shell functions.])
254 AS_FUNCTION_DESCRIBE([at_fn_banner], [NUMBER],
255 [Output banner NUMBER, provided the testsuite is running multiple groups
256 and this particular banner has not yet been printed.])
257 at_fn_banner ()
259   $at_print_banners || return 0
260   eval at_banner_text=\$at_banner_text_$[1]
261   test "x$at_banner_text" = x && return 0
262   eval at_banner_text_$[1]=
263   AS_ECHO(["$as_nl$at_banner_text$as_nl"])
264 } # at_fn_banner
266 AS_FUNCTION_DESCRIBE([at_fn_check_prepare_notrace], [LINE],
267 [Perform AT_CHECK preparations for the command at LINE for an
268 untraceable command, or when tracing is disabled.])
269 at_fn_check_prepare_notrace ()
271   AS_ECHO(["$[1]"]) >"$at_check_line_file"
272   at_check_trace=: at_check_filter=:
273   : >"$at_stdout"; : >"$at_stderr"
276 AS_FUNCTION_DESCRIBE([at_fn_check_prepare_trace], [LINE],
277 [Perform AT_CHECK preparations for the command at LINE for a traceable
278 command.])
279 at_fn_check_prepare_trace ()
281   if test -n "$at_traceon"; then
282     AS_ECHO(["$[1]"]) >"$at_check_line_file"
283     at_check_trace=$at_traceon at_check_filter=at_fn_filter_trace
284     : >"$at_stdout"; : >"$at_stderr"
285   else
286     at_fn_check_prepare_notrace "$[1]"
287   fi
290 AS_FUNCTION_DESCRIBE([at_fn_check_prepare_dynamic], [COMMAND LINE],
291 [Decide if COMMAND at LINE is traceable at runtime, and call the
292 appropriate preparation function.])
293 at_fn_check_prepare_dynamic ()
295   case "$at_traceon:$[1]" in
296     :*$as_nl*)
297       at_fn_check_prepare_notrace "$[2]" ;;
298     *$as_nl*)
299       echo 'Not enabling shell tracing (command contains an embedded newline)'
300       at_fn_check_prepare_notrace "$[2]" ;;
301     *)
302       at_fn_check_prepare_trace "$[2]" ;;
303   esac
306 AS_FUNCTION_DESCRIBE([at_fn_filter_trace], [],
307 [Remove the lines in the file "$at_stderr" generated by "set -x" and print
308 them to stderr.])
309 at_fn_filter_trace ()
311   mv "$at_stderr" "$at_stder1"
312   grep '^ *+' "$at_stder1" >&2
313   grep -v '^ *+' "$at_stder1" >"$at_stderr"
316 AS_FUNCTION_DESCRIBE([at_fn_log_failure], [FILE-LIST],
317 [Copy the files in the list on stdout with a "> " prefix, and exit the shell
318 with a failure exit code.])
319 at_fn_log_failure ()
321   for file
322     do AS_ECHO(["$file:"]); sed 's/^/> /' "$file"; done
323   echo 1 > "$at_status_file"
324   exit 1
327 AS_FUNCTION_DESCRIBE([at_fn_check_skip], [EXIT-CODE LINE],
328 [Check whether EXIT-CODE is a special exit code (77 or 99), and if so exit
329 the test group subshell with that same exit code.  Use LINE in any report
330 about test failure.])
331 at_fn_check_skip ()
333   case $[1] in
334     99) echo 99 > "$at_status_file"; at_failed=:
335         AS_ECHO(["$[2]: hard failure"]); exit 99;;
336     77) echo 77 > "$at_status_file"; exit 77;;
337   esac
340 AS_FUNCTION_DESCRIBE([at_fn_check_status], [EXPECTED EXIT-CODE LINE],
341 [Check whether EXIT-CODE is the EXPECTED exit code, and if so do nothing.
342 Otherwise, if it is 77 or 99, exit the test group subshell with that same
343 exit code; if it is anything else print an error message referring to LINE,
344 and fail the test.])
345 at_fn_check_status ()
347 dnl This order ensures that we don't `skip' if we are precisely checking
348 dnl $? = 77 or $? = 99.
349   case $[2] in
350     $[1] ) ;;
351     77) echo 77 > "$at_status_file"; exit 77;;
352     99) echo 99 > "$at_status_file"; at_failed=:
353         AS_ECHO(["$[3]: hard failure"]); exit 99;;
354     *) AS_ECHO(["$[3]: exit code was $[2], expected $[1]"])
355       at_failed=:;;
356   esac
359 AS_FUNCTION_DESCRIBE([at_fn_diff_devnull], [FILE],
360 [Emit a diff between /dev/null and FILE.  Uses "test -s" to avoid useless
361 diff invocations.])
362 at_fn_diff_devnull ()
364   test -s "$[1]" || return 0
365   $at_diff "$at_devnull" "$[1]"
368 AS_FUNCTION_DESCRIBE([at_fn_test], [NUMBER],
369 [Parse out test NUMBER from the tail of this file.])
370 at_fn_test ()
372   eval at_sed=\$at_sed$[1]
373   sed "$at_sed" "$at_myself" > "$at_test_source"
376 AS_FUNCTION_DESCRIBE([at_fn_create_debugging_script], [],
377 [Create the debugging script $at_group_dir/run which will reproduce the
378 current test group.])
379 at_fn_create_debugging_script ()
381   {
382     echo "#! /bin/sh" &&
383     echo 'test "${ZSH_VERSION+set}" = set dnl
384 && alias -g '\''${1+"$[@]"}'\''='\''"$[@]"'\''' &&
385     AS_ECHO(["cd '$at_dir'"]) &&
386     AS_ECHO(["exec \${CONFIG_SHELL-$SHELL} \"$at_myself\" -v -d ]dnl
387 [$at_debug_args $at_group \${1+\"\$[@]\"}"]) &&
388     echo 'exit 1'
389   } >"$at_group_dir/run" &&
390   chmod +x "$at_group_dir/run"
393 m4_text_box([End of autotest shell functions.])
394 m4_divert_pop([PREPARE_TESTS])dnl back to DEFAULTS
396 # Not all shells have the 'times' builtin; the subshell is needed to make
397 # sure we discard the 'times: not found' message from the shell.
398 at_times_p=false
399 (times) >/dev/null 2>&1 && at_times_p=:
401 # CLI Arguments to pass to the debugging scripts.
402 at_debug_args=
403 # -e sets to true
404 at_errexit_p=false
405 # Shall we be verbose?  ':' means no, empty means yes.
406 at_verbose=:
407 at_quiet=
408 # Running several jobs in parallel, 0 means as many as test groups.
409 at_jobs=1
411 # Shall we keep the debug scripts?  Must be `:' when the suite is
412 # run by a debug script, so that the script doesn't remove itself.
413 at_debug_p=false
414 # Display help message?
415 at_help_p=false
416 # Display the version message?
417 at_version_p=false
418 # List test groups?
419 at_list_p=false
420 # --clean
421 at_clean=false
422 # Test groups to run
423 at_groups=
424 # Whether a write failure occurred
425 at_write_fail=0
427 # The directory we run the suite in.  Default to . if no -C option.
428 at_dir=`pwd`
429 # An absolute reference to this testsuite script.
430 dnl m4-double quote, to preserve []
431 [case $as_myself in
432   [\\/]* | ?:[\\/]* ) at_myself=$as_myself ;;
433   * ) at_myself=$at_dir/$as_myself ;;
434 esac]
435 # Whether -C is in effect.
436 at_change_dir=false
437 m4_divert_pop([DEFAULTS])dnl
438 m4_define([_AT_FINISH],
439 [m4_ifdef([AT_ingroup], [m4_fatal([missing AT_CLEANUP detected])])dnl
440 m4_divert_text([DEFAULTS],
442 # List of the tested programs.
443 at_tested='m4_ifdef([AT_tested],
444   [m4_translit(m4_dquote(m4_defn([AT_tested])), [ ], m4_newline)])'
445 # List of the all the test groups.
446 at_groups_all='AT_groups_all'
447 # As many question marks as there are digits in the last test group number.
448 # Used to normalize the test group numbers so that `ls' lists them in
449 # numerical order.
450 at_format='m4_bpatsubst(m4_defn([AT_ordinal]), [.], [?])'
451 # Description of all the test groups.
452 at_help_all="AS_ESCAPE(m4_dquote(m4_defn([AT_help_all])))"
454 AS_FUNCTION_DESCRIBE([at_fn_validate_ranges], [NAME...],
455 [Validate and normalize the test group number contained in each
456 variable NAME.  Leading zeroes are treated as decimal.])
457 at_fn_validate_ranges ()
459   for at_grp
460   do
461     eval at_value=\$$at_grp
462     if test $at_value -lt 1 || test $at_value -gt AT_ordinal; then
463       AS_ECHO(["invalid test group: $at_value"]) >&2
464       exit 1
465     fi
466     case $at_value in
467       0*) # We want to treat leading 0 as decimal, like expr and test, but
468           # AS_VAR_ARITH treats it as octal if it uses $(( )).
469           # With XSI shells, ${at_value#${at_value%%[1-9]*}} avoids the
470           # expr fork, but it is not worth the effort to determine if the
471           # shell supports XSI when the user can just avoid leading 0.
472           eval $at_grp='`expr $at_value + 0`' ;;
473     esac
474   done
475 }])])dnl
476 m4_divert_push([PARSE_ARGS])dnl
478 at_prev=
479 for at_option
481   # If the previous option needs an argument, assign it.
482   if test -n "$at_prev"; then
483     at_option=$at_prev=$at_option
484     at_prev=
485   fi
487   case $at_option in
488   *=*) at_optarg=`expr "x$at_option" : 'x[[^=]]*=\(.*\)'` ;;
489   *)   at_optarg= ;;
490   esac
492   # Accept the important Cygnus configure options, so we can diagnose typos.
494   case $at_option in
495     --help | -h )
496         at_help_p=:
497         ;;
499     --list | -l )
500         at_list_p=:
501         ;;
503     --version | -V )
504         at_version_p=:
505         ;;
507     --clean | -c )
508         at_clean=:
509         ;;
511     --debug | -d )
512         at_debug_p=:
513         ;;
515     --errexit | -e )
516         at_debug_p=:
517         at_errexit_p=:
518         ;;
520     --verbose | -v )
521         at_verbose=; at_quiet=:
522         ;;
524     --trace | -x )
525         at_traceon='set -x'; at_traceoff='set +x'
526         ;;
528     [[0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]])
529         at_fn_validate_ranges at_option
530         AS_VAR_APPEND([at_groups], ["$at_option "])
531         ;;
533     # Ranges
534     [[0-9]- | [0-9][0-9]- | [0-9][0-9][0-9]- | [0-9][0-9][0-9][0-9]-])
535         at_range_start=`echo $at_option |tr -d X-`
536         at_fn_validate_ranges at_range_start
537         at_range=`AS_ECHO([" $at_groups_all "]) | \
538           sed -e 's/^.* \('$at_range_start' \)/\1/'`
539         AS_VAR_APPEND([at_groups], ["$at_range "])
540         ;;
542     [-[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | -[0-9][0-9][0-9][0-9]])
543         at_range_end=`echo $at_option |tr -d X-`
544         at_fn_validate_ranges at_range_end
545         at_range=`AS_ECHO([" $at_groups_all "]) | \
546           sed -e 's/\( '$at_range_end'\) .*$/\1/'`
547         AS_VAR_APPEND([at_groups], ["$at_range "])
548         ;;
550     [[0-9]-[0-9] | [0-9]-[0-9][0-9] | [0-9]-[0-9][0-9][0-9]] | \
551     [[0-9]-[0-9][0-9][0-9][0-9] | [0-9][0-9]-[0-9][0-9]] | \
552     [[0-9][0-9]-[0-9][0-9][0-9] | [0-9][0-9]-[0-9][0-9][0-9][0-9]] | \
553     [[0-9][0-9][0-9]-[0-9][0-9][0-9]] | \
554     [[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]] | \
555     [[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]] )
556         at_range_start=`expr $at_option : '\(.*\)-'`
557         at_range_end=`expr $at_option : '.*-\(.*\)'`
558         if test $at_range_start -gt $at_range_end; then
559           at_tmp=$at_range_end
560           at_range_end=$at_range_start
561           at_range_start=$at_tmp
562         fi
563         at_fn_validate_ranges at_range_start at_range_end
564         at_range=`AS_ECHO([" $at_groups_all "]) | \
565           sed -e 's/^.*\( '$at_range_start' \)/\1/' \
566               -e 's/\( '$at_range_end'\) .*$/\1/'`
567         AS_VAR_APPEND([at_groups], ["$at_range "])
568         ;;
570     # Directory selection.
571     --directory | -C )
572         at_prev=--directory
573         ;;
574     --directory=* )
575         at_change_dir=:
576         at_dir=$at_optarg
577         ;;
579     # Parallel execution.
580     --jobs | -j )
581         at_jobs=0
582         ;;
583     --jobs=* | -j[[0-9]]* )
584         if test -n "$at_optarg"; then
585           at_jobs=$at_optarg
586         else
587           at_jobs=`expr X$at_option : 'X-j\(.*\)'`
588         fi
589         case $at_jobs in *[[!0-9]]*)
590           at_optname=`echo " $at_option" | sed 's/^ //; s/[[0-9=]].*//'`
591           AS_ERROR([non-numeric argument to $at_optname: $at_jobs]) ;;
592         esac
593         ;;
595     # Keywords.
596     --keywords | -k )
597         at_prev=--keywords
598         ;;
599     --keywords=* )
600         at_groups_selected=$at_help_all
601         at_save_IFS=$IFS
602         IFS=,
603         set X $at_optarg
604         shift
605         IFS=$at_save_IFS
606         for at_keyword
607         do
608           at_invert=
609           case $at_keyword in
610           '!'*)
611             at_invert="-v"
612             at_keyword=`expr "X$at_keyword" : 'X!\(.*\)'`
613             ;;
614           esac
615           # It is on purpose that we match the test group titles too.
616           at_groups_selected=`AS_ECHO(["$at_groups_selected"]) |
617               grep -i $at_invert ["^[1-9][^;]*;.*[; ]$at_keyword[ ;]"]`
618         done
619         # Smash the newlines.
620         at_groups_selected=`AS_ECHO(["$at_groups_selected"]) | sed 's/;.*//' |
621           tr "$as_nl" ' '
622         `
623         AS_VAR_APPEND([at_groups], ["$at_groups_selected "])
624         ;;
625 m4_divert_pop([PARSE_ARGS])dnl
626 dnl Process *=* last to allow for user specified --option=* type arguments.
627 m4_divert_push([PARSE_ARGS_END])dnl
629     *=*)
630         at_envvar=`expr "x$at_option" : 'x\([[^=]]*\)='`
631         # Reject names that are not valid shell variable names.
632         case $at_envvar in
633           '' | [[0-9]]* | *[[!_$as_cr_alnum]]* )
634             AS_ERROR([invalid variable name: `$at_envvar']) ;;
635         esac
636         at_value=`AS_ECHO(["$at_optarg"]) | sed "s/'/'\\\\\\\\''/g"`
637         # Export now, but save eval for later and for debug scripts.
638         export $at_envvar
639         AS_VAR_APPEND([at_debug_args], [" $at_envvar='$at_value'"])
640         ;;
642      *) AS_ECHO(["$as_me: invalid option: $at_option"]) >&2
643         AS_ECHO(["Try \`$[0] --help' for more information."]) >&2
644         exit 1
645         ;;
646   esac
647 done
649 # Verify our last option didn't require an argument
650 AS_IF([test -n "$at_prev"], [AS_ERROR([`$at_prev' requires an argument.])])
652 # Selected test groups.
653 if test -z "$at_groups"; then
654   at_groups=$at_groups_all
655 else
656   # Sort the tests, removing duplicates.
657   at_groups=`AS_ECHO(["$at_groups"]) | tr ' ' "$as_nl" | sort -nu`
659 m4_divert_pop([PARSE_ARGS_END])dnl
660 m4_divert_push([HELP])dnl
662 # Help message.
663 if $at_help_p; then
664   cat <<_ATEOF || at_write_fail=1
665 Usage: $[0] [[OPTION]... [VARIABLE=VALUE]... [TESTS]]
667 Run all the tests, or the selected TESTS, given by numeric ranges, and
668 save a detailed log file.  Upon failure, create debugging scripts.
670 Do not change environment variables directly.  Instead, set them via
671 command line arguments.  Set \`AUTOTEST_PATH' to select the executables
672 to exercise.  Each relative directory is expanded as build and source
673 directories relative to the top level of this distribution.
674 E.g., from within the build directory /tmp/foo-1.0, invoking this:
676   $ $[0] AUTOTEST_PATH=bin
678 is equivalent to the following, assuming the source directory is /src/foo-1.0:
680   PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:\$PATH $[0]
681 _ATEOF
682 m4_divert_pop([HELP])dnl
683 m4_divert_push([HELP_MODES])dnl
684 cat <<_ATEOF || at_write_fail=1
686 Operation modes:
687   -h, --help     print the help message, then exit
688   -V, --version  print version number, then exit
689   -c, --clean    remove all the files this test suite might create and exit
690   -l, --list     describes all the tests, or the selected TESTS
691 _ATEOF
692 m4_divert_pop([HELP_MODES])dnl
693 m4_divert_push([HELP_TUNING])dnl
694 cat <<_ATEOF || at_write_fail=1
696 dnl extra quoting prevents emacs whitespace mode from putting tabs in output
697 Execution tuning:
698   -C, --directory=DIR
699 [                 change to directory DIR before starting]
700   -j, --jobs[[=N]]
701 [                 Allow N jobs at once; infinite jobs with no arg (default 1)]
702   -k, --keywords=KEYWORDS
703 [                 select the tests matching all the comma-separated KEYWORDS]
704 [                 multiple \`-k' accumulate; prefixed \`!' negates a KEYWORD]
705   -e, --errexit  abort as soon as a test fails; implies --debug
706   -v, --verbose  force more detailed output
707 [                 default for debugging scripts]
708   -d, --debug    inhibit clean up and top-level logging
709 [                 default for debugging scripts]
710   -x, --trace    enable tests shell tracing
711 _ATEOF
712 m4_divert_pop([HELP_TUNING])dnl
713 m4_divert_push([HELP_END])dnl
714 cat <<_ATEOF || at_write_fail=1
716 Report bugs to <AT_PACKAGE_BUGREPORT>.dnl
717 m4_ifdef([AT_PACKAGE_NAME],
718 [m4_ifset([AT_PACKAGE_URL], [
719 m4_defn([AT_PACKAGE_NAME]) home page: <AT_PACKAGE_URL>.])dnl
720 m4_if(m4_index(m4_defn([AT_PACKAGE_NAME]), [GNU ]), [0], [
721 General help using GNU software: <http://www.gnu.org/gethelp/>.])])
722 _ATEOF
723   exit $at_write_fail
726 # List of tests.
727 if $at_list_p; then
728   cat <<_ATEOF || at_write_fail=1
729 AT_TESTSUITE_NAME test groups:
731  NUM: FILE-NAME:LINE     TEST-GROUP-NAME
732       KEYWORDS
734 _ATEOF
735   # Passing at_groups is tricky.  We cannot use it to form a literal string
736   # or regexp because of the limitation of AIX awk.  And Solaris' awk
737   # doesn't grok more than 99 fields in a record, so we have to use `split'.
738   # at_groups needs to be space-separated for this script to work.
739   case $at_groups in
740     *"$as_nl"* )
741       at_groups=`AS_ECHO(["$at_groups"]) | tr "$as_nl" ' '` ;;
742   esac
743   AS_ECHO(["$at_groups$as_nl$at_help_all"]) |
744     awk 'BEGIN { FS = ";" }
745          NR == 1 {
746            for (n = split ($ 0, a, " "); n; n--)
747              selected[[a[n]]] = 1
748            next
749          }
750          NF > 0 {
751            if (selected[[$ 1]]) {
752              printf " %3d: %-18s %s\n", $ 1, $ 2, $ 3
753              if ($ 4) {
754                lmax = 79
755                indent = "     "
756                line = indent
757                len = length (line)
758                n = split ($ 4, a, " ")
759                for (i = 1; i <= n; i++) {
760                  l = length (a[[i]]) + 1
761                  if (i > 1 && len + l > lmax) {
762                    print line
763                    line = indent " " a[[i]]
764                    len = length (line)
765                  } else {
766                    line = line " " a[[i]]
767                    len += l
768                  }
769                }
770                if (n)
771                  print line
772              }
773            }
774          }' || at_write_fail=1
775   exit $at_write_fail
777 m4_divert_pop([HELP_END])dnl
778 m4_divert_push([VERSION])dnl
779 if $at_version_p; then
780   AS_ECHO(["$as_me (AT_PACKAGE_STRING)"]) &&
781   cat <<\_ATEOF || at_write_fail=1
782 m4_divert_pop([VERSION])dnl
783 m4_divert_push([VERSION_END])dnl
784 _ATEOF
785   exit $at_write_fail
787 m4_divert_pop([VERSION_END])dnl
788 m4_divert_push([TESTS_BEGIN])dnl
790 # Take any -C into account.
791 if $at_change_dir ; then
792   if test x- = "x$at_dir" ; then
793     at_dir=./-
794   fi
795   test x != "x$at_dir" && cd "$at_dir" \
796     || AS_ERROR([unable to change directory])
797   at_dir=`pwd`
800 # Load the config files for any default variable assignments.
801 for at_file in atconfig atlocal
803   test -r $at_file || continue
804   . ./$at_file || AS_ERROR([invalid content: $at_file])
805 done
807 # Autoconf <=2.59b set at_top_builddir instead of at_top_build_prefix:
808 : ${at_top_build_prefix=$at_top_builddir}
810 # Perform any assignments requested during argument parsing.
811 eval "$at_debug_args"
813 # atconfig delivers names relative to the directory the test suite is
814 # in, but the groups themselves are run in testsuite-dir/group-dir.
815 if test -n "$at_top_srcdir"; then
816   builddir=../..
817   for at_dir_var in srcdir top_srcdir top_build_prefix
818   do
819     AS_VAR_COPY([at_val], [at_$at_dir_var])
820     case $at_val in
821       [[\\/$]]* | ?:[[\\/]]* ) at_prefix= ;;
822       *) at_prefix=../../ ;;
823     esac
824     AS_VAR_SET([$at_dir_var], [$at_prefix$at_val])
825   done
828 m4_text_box([Directory structure.])
830 # This is the set of directories and files used by this script
831 # (non-literals are capitalized):
833 # TESTSUITE         - the testsuite
834 # TESTSUITE.log     - summarizes the complete testsuite run
835 # TESTSUITE.dir/    - created during a run, remains after -d or failed test
836 # + at-groups/      - during a run: status of all groups in run
837 # | + NNN/          - during a run: meta-data about test group NNN
838 # | | + check-line  - location (source file and line) of current AT_CHECK
839 # | | + status      - exit status of current AT_CHECK
840 # | | + stdout      - stdout of current AT_CHECK
841 # | | + stder1      - stderr, including trace
842 # | | + stderr      - stderr, with trace filtered out
843 # | | + test-source - portion of testsuite that defines group
844 # | | + times       - timestamps for computing duration
845 # | | + pass        - created if group passed
846 # | | + xpass       - created if group xpassed
847 # | | + fail        - created if group failed
848 # | | + xfail       - created if group xfailed
849 # | | + skip        - created if group skipped
850 # + at-stop         - during a run: end the run if this file exists
851 # + at-source-lines - during a run: cache of TESTSUITE line numbers for extraction
852 # + 0..NNN/         - created for each group NNN, remains after -d or failed test
853 # | + TESTSUITE.log - summarizes the group results
854 # | + ...           - files created during the group
856 # The directory the whole suite works in.
857 # Should be absolute to let the user `cd' at will.
858 at_suite_dir=$at_dir/$as_me.dir
859 # The file containing the suite.
860 at_suite_log=$at_dir/$as_me.log
861 # The directory containing helper files per test group.
862 at_helper_dir=$at_suite_dir/at-groups
863 # Stop file: if it exists, do not start new jobs.
864 at_stop_file=$at_suite_dir/at-stop
865 # The fifo used for the job dispatcher.
866 at_job_fifo=$at_suite_dir/at-job-fifo
868 if $at_clean; then
869   test -d "$at_suite_dir" &&
870     find "$at_suite_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
871   rm -f -r "$at_suite_dir" "$at_suite_log"
872   exit $?
875 # Don't take risks: use only absolute directories in PATH.
877 # For stand-alone test suites (ie. atconfig was not found),
878 # AUTOTEST_PATH is relative to `.'.
880 # For embedded test suites, AUTOTEST_PATH is relative to the top level
881 # of the package.  Then expand it into build/src parts, since users
882 # may create executables in both places.
883 AUTOTEST_PATH=`AS_ECHO(["$AUTOTEST_PATH"]) | sed "s|:|$PATH_SEPARATOR|g"`
884 at_path=
885 _AS_PATH_WALK([$AUTOTEST_PATH $PATH],
886 [test -n "$at_path" && AS_VAR_APPEND([at_path], [$PATH_SEPARATOR])
887 case $as_dir in
888   [[\\/]]* | ?:[[\\/]]* )
889     AS_VAR_APPEND([at_path], ["$as_dir"])
890     ;;
891   * )
892     if test -z "$at_top_build_prefix"; then
893       # Stand-alone test suite.
894       AS_VAR_APPEND([at_path], ["$as_dir"])
895     else
896       # Embedded test suite.
897       AS_VAR_APPEND([at_path], ["$at_top_build_prefix$as_dir$PATH_SEPARATOR"])
898       AS_VAR_APPEND([at_path], ["$at_top_srcdir/$as_dir"])
899     fi
900     ;;
901 esac])
903 # Now build and simplify PATH.
905 # There might be directories that don't exist, but don't redirect
906 # builtins' (eg., cd) stderr directly: Ultrix's sh hates that.
907 at_new_path=
908 _AS_PATH_WALK([$at_path],
909 [test -d "$as_dir" || continue
910 case $as_dir in
911   [[\\/]]* | ?:[[\\/]]* ) ;;
912   * ) as_dir=`(cd "$as_dir" && pwd) 2>/dev/null` ;;
913 esac
914 case $PATH_SEPARATOR$at_new_path$PATH_SEPARATOR in
915   *$PATH_SEPARATOR$as_dir$PATH_SEPARATOR*) ;;
916   $PATH_SEPARATOR$PATH_SEPARATOR) at_new_path=$as_dir ;;
917   *) AS_VAR_APPEND([at_new_path], ["$PATH_SEPARATOR$as_dir"]) ;;
918 esac])
919 PATH=$at_new_path
920 export PATH
922 # Setting up the FDs.
923 m4_define([AS_MESSAGE_LOG_FD], [5])
924 m4_define([AT_JOB_FIFO_FD], [6])
925 [#] AS_MESSAGE_LOG_FD is the log file.  Not to be overwritten if `-d'.
926 if $at_debug_p; then
927   at_suite_log=/dev/null
928 else
929   : >"$at_suite_log"
931 exec AS_MESSAGE_LOG_FD>>"$at_suite_log"
933 # Banners and logs.
934 AS_BOX(m4_defn([AT_TESTSUITE_NAME])[.])
936   AS_BOX(m4_defn([AT_TESTSUITE_NAME])[.])
937   echo
939   AS_ECHO(["$as_me: command line was:"])
940   AS_ECHO(["  \$ $[0] $at_cli_args"])
941   echo
943   # Try to find a few ChangeLogs in case it might help determining the
944   # exact version.  Use the relative dir: if the top dir is a symlink,
945   # find will not follow it (and options to follow the links are not
946   # portable), which would result in no output here.  Prune directories
947   # matching the package tarname, since they tend to be leftovers from
948   # `make dist' or `make distcheck' and contain redundant or stale logs.
949   if test -n "$at_top_srcdir"; then
950     AS_BOX([ChangeLogs.])
951     echo
952     for at_file in `find "$at_top_srcdir" m4_ifdef([AT_PACKAGE_TARNAME],
953 [-name "AT_PACKAGE_TARNAME-*" -prune -o ])-name ChangeLog -print`
954     do
955       AS_ECHO(["$as_me: $at_file:"])
956       sed 's/^/| /;10q' $at_file
957       echo
958     done
960   fi
962   AS_UNAME
963   echo
965   # Contents of the config files.
966   for at_file in atconfig atlocal
967   do
968     test -r $at_file || continue
969     AS_ECHO(["$as_me: $at_file:"])
970     sed 's/^/| /' $at_file
971     echo
972   done
973 } >&AS_MESSAGE_LOG_FD
975 m4_divert_pop([TESTS_BEGIN])dnl
976 m4_divert_push([PREPARE_TESTS])dnl
978   AS_BOX([Tested programs.])
979   echo
980 } >&AS_MESSAGE_LOG_FD
982 # Report what programs are being tested.
983 for at_program in : $at_tested
985   test "$at_program" = : && continue
986   _AS_PATH_WALK([$PATH], [test -f "$as_dir/$at_program" && break])
987   if test -f "$as_dir/$at_program"; then
988     {
989       AS_ECHO(["$at_srcdir/AT_LINE: $as_dir/$at_program --version"])
990       "$as_dir/$at_program" --version </dev/null
991       echo
992     } >&AS_MESSAGE_LOG_FD 2>&1
993   else
994     AS_ERROR([cannot find $at_program])
995   fi
996 done
999   AS_BOX([Running the tests.])
1000 } >&AS_MESSAGE_LOG_FD
1002 at_start_date=`date`
1003 at_start_time=`date +%s 2>/dev/null`
1004 AS_ECHO(["$as_me: starting at: $at_start_date"]) >&AS_MESSAGE_LOG_FD
1005 m4_divert_pop([PREPARE_TESTS])dnl
1006 m4_divert_push([TESTS])dnl
1008 # Create the master directory if it doesn't already exist.
1009 AS_MKDIR_P(["$at_suite_dir"]) ||
1010   AS_ERROR([cannot create `$at_suite_dir'])
1012 # Can we diff with `/dev/null'?  DU 5.0 refuses.
1013 if diff /dev/null /dev/null >/dev/null 2>&1; then
1014   at_devnull=/dev/null
1015 else
1016   at_devnull=$at_suite_dir/devnull
1017   >"$at_devnull"
1020 # Use `diff -u' when possible.
1021 if at_diff=`diff -u "$at_devnull" "$at_devnull" 2>&1` && test -z "$at_diff"
1022 then
1023   at_diff='diff -u'
1024 else
1025   at_diff=diff
1028 # Get the last needed group.
1029 for at_group in : $at_groups; do :; done
1031 # Extract the start and end lines of each test group at the tail
1032 # of this file
1033 awk '
1034 BEGIN { FS="\a" }
1035 /^@%:@AT_START_/ {
1036   start = NR
1038 /^@%:@AT_STOP_/ {
1039   test = substr ($ 0, 10)
1040   print "at_sed" test "=\"1," start "d;" (NR-1) "q\""
1041   if (test == "'"$at_group"'") exit
1042 }' "$at_myself" > "$at_suite_dir/at-source-lines" &&
1043 . "$at_suite_dir/at-source-lines" ||
1044   AS_ERROR([cannot create test line number cache])
1045 rm -f "$at_suite_dir/at-source-lines"
1047 # Set number of jobs for `-j'; avoid more jobs than test groups.
1048 set X $at_groups; shift; at_max_jobs=$[@%:@]
1049 if test $at_max_jobs -eq 0; then
1050   at_jobs=1
1052 if test $at_jobs -ne 1 &&
1053    { test $at_jobs -eq 0 || test $at_jobs -gt $at_max_jobs; }; then
1054   at_jobs=$at_max_jobs
1057 # If parallel mode, don't output banners, don't split summary lines.
1058 if test $at_jobs -ne 1; then
1059   at_print_banners=false
1060   at_quiet=:
1063 # Set up helper dirs.
1064 rm -rf "$at_helper_dir" &&
1065 mkdir "$at_helper_dir" &&
1066 cd "$at_helper_dir" &&
1067 { test -z "$at_groups" || mkdir $at_groups; } ||
1068 AS_ERROR([testsuite directory setup failed])
1070 # Functions for running a test group.  We leave the actual
1071 # test group execution outside of a shell function in order
1072 # to avoid hitting zsh 4.x exit status bugs.
1074 AS_FUNCTION_DESCRIBE([at_fn_group_prepare], [],
1075 [Prepare running a test group.])
1076 at_fn_group_prepare ()
1078   # The directory for additional per-group helper files.
1079   at_job_dir=$at_helper_dir/$at_group
1080   # The file containing the location of the last AT_CHECK.
1081   at_check_line_file=$at_job_dir/check-line
1082   # The file containing the exit status of the last command.
1083   at_status_file=$at_job_dir/status
1084   # The files containing the output of the tested commands.
1085   at_stdout=$at_job_dir/stdout
1086   at_stder1=$at_job_dir/stder1
1087   at_stderr=$at_job_dir/stderr
1088   # The file containing the code for a test group.
1089   at_test_source=$at_job_dir/test-source
1090   # The file containing dates.
1091   at_times_file=$at_job_dir/times
1093   # Be sure to come back to the top test directory.
1094   cd "$at_suite_dir"
1096   # Clearly separate the test groups when verbose.
1097   $at_first || $at_verbose echo
1099   at_group_normalized=$at_group
1100   _AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
1102   # Create a fresh directory for the next test group, and enter.
1103   # If one already exists, the user may have invoked ./run from
1104   # within that directory; we remove the contents, but not the
1105   # directory itself, so that we aren't pulling the rug out from
1106   # under the shell's notion of the current directory.
1107   at_group_dir=$at_suite_dir/$at_group_normalized
1108   at_group_log=$at_group_dir/$as_me.log
1109   _AS_CLEAN_DIR("$at_group_dir") ||
1110     AS_WARN([test directory for $at_group_normalized could not be cleaned.])
1111   # Be tolerant if the above `rm' was not able to remove the directory.
1112   AS_MKDIR_P(["$at_group_dir"])
1114   echo 0 > "$at_status_file"
1116   # In verbose mode, append to the log file *and* show on
1117   # the standard output; in quiet mode only write to the log.
1118   if test -z "$at_verbose"; then
1119     at_tee_pipe='tee -a "$at_group_log"'
1120   else
1121     at_tee_pipe='cat >> "$at_group_log"'
1122   fi
1125 AS_FUNCTION_DESCRIBE([at_fn_group_postprocess], [],
1126 [Perform cleanup after running a test group.])
1127 at_fn_group_postprocess ()
1129   # Be sure to come back to the suite directory, in particular
1130   # since below we might `rm' the group directory we are in currently.
1131   cd "$at_suite_dir"
1133   if test ! -f "$at_check_line_file"; then
1134     sed "s/^ */$as_me: WARNING: /" <<_ATEOF
1135       A failure happened in a test group before any test could be
1136       run. This means that test suite is improperly designed.  Please
1137       report this failure to <AT_PACKAGE_BUGREPORT>.
1138 _ATEOF
1139     AS_ECHO(["$at_setup_line"]) >"$at_check_line_file"
1140     at_status=99
1141   fi
1142   $at_verbose AS_ECHO_N(["$at_group. $at_setup_line: "])
1143   AS_ECHO_N(["$at_group. $at_setup_line: "]) >> "$at_group_log"
1144   case $at_xfail:$at_status in
1145     *:99)
1146         at_msg='FAILED ('`cat "$at_check_line_file"`')'
1147         at_res=fail
1148         at_errexit=$at_errexit_p
1149         ;;
1150     yes:0)
1151         at_msg="UNEXPECTED PASS"
1152         at_res=xpass
1153         at_errexit=$at_errexit_p
1154         ;;
1155     no:0)
1156         at_msg="ok"
1157         at_res=pass
1158         at_errexit=false
1159         ;;
1160     *:77)
1161         at_msg='skipped ('`cat "$at_check_line_file"`')'
1162         at_res=skip
1163         at_errexit=false
1164         ;;
1165     yes:*)
1166         at_msg='expected failure ('`cat "$at_check_line_file"`')'
1167         at_res=xfail
1168         at_errexit=false
1169         ;;
1170     no:*)
1171         at_msg='FAILED ('`cat "$at_check_line_file"`')'
1172         at_res=fail
1173         at_errexit=$at_errexit_p
1174         ;;
1175   esac
1176   echo "$at_res" > "$at_job_dir/$at_res"
1177   # In parallel mode, output the summary line only afterwards.
1178   if test $at_jobs -ne 1 && test -n "$at_verbose"; then
1179     AS_ECHO(["$at_desc_line $at_msg"])
1180   else
1181     # Make sure there is a separator even with long titles.
1182     AS_ECHO([" $at_msg"])
1183   fi
1184   at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg"
1185   case $at_status in
1186     0|77)
1187       # $at_times_file is only available if the group succeeded.
1188       # We're not including the group log, so the success message
1189       # is written in the global log separately.  But we also
1190       # write to the group log in case they're using -d.
1191       if test -f "$at_times_file"; then
1192         at_log_msg="$at_log_msg     ("`sed 1d "$at_times_file"`')'
1193         rm -f "$at_times_file"
1194       fi
1195       AS_ECHO(["$at_log_msg"]) >> "$at_group_log"
1196       AS_ECHO(["$at_log_msg"]) >&AS_MESSAGE_LOG_FD
1198       # Cleanup the group directory, unless the user wants the files.
1199       if $at_debug_p; then
1200         at_fn_create_debugging_script
1201       else
1202         if test -d "$at_group_dir"; then
1203           find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
1204           rm -fr "$at_group_dir"
1205         fi
1206         rm -f "$at_test_source"
1207       fi
1208       ;;
1209     *)
1210       # Upon failure, include the log into the testsuite's global
1211       # log.  The failure message is written in the group log.  It
1212       # is later included in the global log.
1213       AS_ECHO(["$at_log_msg"]) >> "$at_group_log"
1215       # Upon failure, keep the group directory for autopsy, and create
1216       # the debugging script.  With -e, do not start any further tests.
1217       at_fn_create_debugging_script
1218       if $at_errexit; then
1219         echo stop > "$at_stop_file"
1220       fi
1221       ;;
1222   esac
1226 m4_text_box([Driver loop.])
1228 dnl Catching signals correctly:
1230 dnl The first idea was: trap the signal, send it to all spawned jobs,
1231 dnl then reset the handler and reraise the signal for ourselves.
1232 dnl However, before exiting, ksh will then send the signal to all
1233 dnl process group members, potentially killing the outer testsuite
1234 dnl and/or the 'make' process driving us.
1235 dnl So now the strategy is: trap the signal, send it to all spawned jobs,
1236 dnl then exit the script with the right status.
1238 dnl In order to let the jobs know about the signal, we cannot just send it
1239 dnl to the current process group (kill $SIG 0), for the same reason as above.
1240 dnl Also, it does not reliably stop the suite to send the signal to the
1241 dnl spawned processes, because they might not transport it further
1242 dnl (maybe this can be fixed?).
1244 dnl So what we do is enable shell job control if available, which causes the
1245 dnl shell to start each parallel task as its own shell job, thus as a new
1246 dnl process group leader.  We then send the signal to all new process groups.
1248 dnl Do we have job control?
1249 if (set -m && set +m) >/dev/null 2>&1; then
1250   at_job_control_on='set -m' at_job_control_off='set +m' at_job_group=-
1251 else
1252   at_job_control_on=: at_job_control_off=: at_job_group=
1255 for at_signal in 1 2 15; do
1256 dnl This signal handler is not suitable for PIPE: it causes writes.
1257 dnl The code that was interrupted may have the errexit, monitor, or xtrace
1258 dnl flags enabled, so sanitize.
1259   trap 'set +x; set +e
1260         $at_job_control_off
1261         at_signal='"$at_signal"'
1262 dnl Safety belt: even with runaway processes, prevent starting new jobs.
1263         echo stop > "$at_stop_file"
1264 dnl Do not enter this area multiple times, do not kill self prematurely.
1265         trap "" $at_signal
1266 dnl Gather process group IDs of currently running jobs.
1267         at_pgids=
1268         for at_pgid in `jobs -p 2>/dev/null`; do
1269           at_pgids="$at_pgids $at_job_group$at_pgid"
1270         done
1271 dnl Ignore `kill' errors, as some jobs may have finished in the meantime.
1272         test -z "$at_pgids" || kill -$at_signal $at_pgids 2>/dev/null
1273 dnl wait until all jobs have exited.
1274         wait
1275 dnl Status output.  Do this after waiting for the jobs, for ordered output.
1276 dnl Avoid scribbling onto the end of a possibly incomplete line.
1277         if test "$at_jobs" -eq 1 || test -z "$at_verbose"; then
1278           echo >&2
1279         fi
1280         at_signame=`kill -l $at_signal 2>&1 || echo $at_signal`
1281         set x $at_signame
1282         test $# -gt 2 && at_signame=$at_signal
1283         AS_WARN([caught signal $at_signame, bailing out])
1284 dnl Do not reinstall the default handler here and reraise the signal to
1285 dnl let the default handler do its job, see the note about ksh above.
1286 dnl     trap - $at_signal
1287 dnl     kill -$at_signal $$
1288 dnl Instead, exit with appropriate status.
1289         AS_VAR_ARITH([exit_status], [128 + $at_signal])
1290         AS_EXIT([$exit_status])' $at_signal
1291 done
1293 rm -f "$at_stop_file"
1294 at_first=:
1296 if test $at_jobs -ne 1 &&
1297      rm -f "$at_job_fifo" &&
1298      test -n "$at_job_group" &&
1299      ( mkfifo "$at_job_fifo" && trap 'exit 1' PIPE STOP TSTP ) 2>/dev/null
1300 then
1301   # FIFO job dispatcher.
1303 dnl Since we use job control, we need to propagate TSTP.
1304 dnl This handler need not be used for serial execution.
1305 dnl Again, we should stop all processes in the job groups, otherwise
1306 dnl the stopping will not be effective while one test group is running.
1307 dnl Apparently ksh does not honor the TSTP trap.
1308 dnl As a safety measure, not use the same variable names as in the
1309 dnl termination handlers above, one might get called during execution
1310 dnl of the other.
1311   trap 'at_pids=
1312         for at_pid in `jobs -p`; do
1313           at_pids="$at_pids $at_job_group$at_pid"
1314         done
1315 dnl Send it to all spawned jobs, ignoring those finished meanwhile.
1316         if test -n "$at_pids"; then
1317 dnl Unfortunately, ksh93 fork-bombs when we send TSTP, so send STOP
1318 dnl if this might be ksh (STOP prevents possible TSTP handlers inside
1319 dnl AT_CHECKs from running).  Then stop ourselves.
1320           at_sig=TSTP
1321           test "${TMOUT+set}" = set && at_sig=STOP
1322           kill -$at_sig $at_pids 2>/dev/null
1323         fi
1324         kill -STOP $$
1325 dnl We got a CONT, so let's go again.  Passing this to all processes
1326 dnl in the groups is necessary (because we stopped them), but it may
1327 dnl cause changed test semantics; e.g., a sleep will be interrupted.
1328         test -z "$at_pids" || kill -CONT $at_pids 2>/dev/null' TSTP
1330   echo
1331   # Turn jobs into a list of numbers, starting from 1.
1332   at_joblist=`AS_ECHO([" $at_groups_all "]) | \
1333     sed 's/\( '$at_jobs'\) .*/\1/'`
1335   set X $at_joblist
1336   shift
1337   for at_group in $at_groups; do
1338 dnl Enable job control only for spawning the test group:
1339 dnl Let the jobs to run in separate process groups, but
1340 dnl avoid all the status output by the shell.
1341     $at_job_control_on 2>/dev/null
1342     (
1343       # Start one test group.
1344       $at_job_control_off
1345       exec AT_JOB_FIFO_FD>"$at_job_fifo"
1346 dnl When a child receives PIPE, be sure to write back the token,
1347 dnl so the master does not hang waiting for it.
1348 dnl errexit and xtrace should not be set in this shell instance,
1349 dnl except as debug measures.  However, shells such as dash may
1350 dnl optimize away the _AT_CHECK subshell, so normalize here.
1351       trap 'set +x; set +e
1352 dnl Ignore PIPE signals that stem from writing back the token.
1353             trap "" PIPE
1354             echo stop > "$at_stop_file"
1355             echo token >&AT_JOB_FIFO_FD
1356 dnl Do not reraise the default PIPE handler.
1357 dnl It wreaks havoc with ksh, see above.
1358 dnl         trap - 13
1359 dnl         kill -13 $$
1360             AS_EXIT([141])' PIPE
1361       at_fn_group_prepare
1362       if cd "$at_group_dir" &&
1363          at_fn_test $at_group &&
1364          . "$at_test_source" # AT_JOB_FIFO_FD>&-
1365       then :; else
1366         AS_WARN([unable to parse test group: $at_group])
1367         at_failed=:
1368       fi
1369       at_fn_group_postprocess
1370       echo token >&AT_JOB_FIFO_FD
1371     ) &
1372     $at_job_control_off
1373     if $at_first; then
1374       at_first=false
1375       exec AT_JOB_FIFO_FD<"$at_job_fifo"
1376     fi
1377     shift # Consume one token.
1378     if test $[@%:@] -gt 0; then :; else
1379       read at_token <&AT_JOB_FIFO_FD || break
1380       set x $[*]
1381     fi
1382     test -f "$at_stop_file" && break
1383   done
1384   # Read back the remaining ($at_jobs - 1) tokens.
1385   set X $at_joblist
1386   shift
1387   if test $[@%:@] -gt 0; then
1388     shift
1389     for at_job
1390     do
1391       read at_token
1392     done <&AT_JOB_FIFO_FD
1393   fi
1394   exec AT_JOB_FIFO_FD<&-
1395   wait
1396 else
1397   # Run serially, avoid forks and other potential surprises.
1398   for at_group in $at_groups; do
1399     at_fn_group_prepare
1400     if cd "$at_group_dir" &&
1401        at_fn_test $at_group &&
1402        . "$at_test_source"; then :; else
1403       AS_WARN([unable to parse test group: $at_group])
1404       at_failed=:
1405     fi
1406     at_fn_group_postprocess
1407     test -f "$at_stop_file" && break
1408     at_first=false
1409   done
1412 # Wrap up the test suite with summary statistics.
1413 cd "$at_helper_dir"
1415 # Use ?..???? when the list must remain sorted, the faster * otherwise.
1416 at_pass_list=`for f in */pass; do echo $f; done | sed '/\*/d; s,/pass,,'`
1417 at_skip_list=`for f in */skip; do echo $f; done | sed '/\*/d; s,/skip,,'`
1418 at_xfail_list=`for f in */xfail; do echo $f; done | sed '/\*/d; s,/xfail,,'`
1419 at_xpass_list=`for f in ?/xpass ??/xpass ???/xpass ????/xpass; do
1420                  echo $f; done | sed '/?/d; s,/xpass,,'`
1421 at_fail_list=`for f in ?/fail ??/fail ???/fail ????/fail; do
1422                 echo $f; done | sed '/?/d; s,/fail,,'`
1424 set X $at_pass_list $at_xpass_list $at_xfail_list $at_fail_list $at_skip_list
1425 shift; at_group_count=$[@%:@]
1426 set X $at_xpass_list; shift; at_xpass_count=$[@%:@]; at_xpass_list=$[*]
1427 set X $at_xfail_list; shift; at_xfail_count=$[@%:@]
1428 set X $at_fail_list; shift; at_fail_count=$[@%:@]; at_fail_list=$[*]
1429 set X $at_skip_list; shift; at_skip_count=$[@%:@]
1431 AS_VAR_ARITH([at_run_count], [$at_group_count - $at_skip_count])
1432 AS_VAR_ARITH([at_unexpected_count], [$at_xpass_count + $at_fail_count])
1433 AS_VAR_ARITH([at_total_fail_count], [$at_xfail_count + $at_fail_count])
1435 # Back to the top directory.
1436 cd "$at_dir"
1437 rm -rf "$at_helper_dir"
1439 # Compute the duration of the suite.
1440 at_stop_date=`date`
1441 at_stop_time=`date +%s 2>/dev/null`
1442 AS_ECHO(["$as_me: ending at: $at_stop_date"]) >&AS_MESSAGE_LOG_FD
1443 case $at_start_time,$at_stop_time in
1444   [[0-9]*,[0-9]*])
1445     AS_VAR_ARITH([at_duration_s], [$at_stop_time - $at_start_time])
1446     AS_VAR_ARITH([at_duration_m], [$at_duration_s / 60])
1447     AS_VAR_ARITH([at_duration_h], [$at_duration_m / 60])
1448     AS_VAR_ARITH([at_duration_s], [$at_duration_s % 60])
1449     AS_VAR_ARITH([at_duration_m], [$at_duration_m % 60])
1450     at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s"
1451     AS_ECHO(["$as_me: test suite duration: $at_duration"]) >&AS_MESSAGE_LOG_FD
1452     ;;
1453 esac
1455 echo
1456 AS_BOX([Test results.])
1457 echo
1459   echo
1460   AS_BOX([Test results.])
1461   echo
1462 } >&AS_MESSAGE_LOG_FD
1465 dnl FIXME: this code is as far from i18n-cleanness as man
1466 dnl could imagine...
1468 if test $at_run_count = 1; then
1469   at_result="1 test"
1470   at_were=was
1471 else
1472   at_result="$at_run_count tests"
1473   at_were=were
1475 if $at_errexit_p && test $at_unexpected_count != 0; then
1476   if test $at_xpass_count = 1; then
1477     at_result="$at_result $at_were run, one passed"
1478   else
1479     at_result="$at_result $at_were run, one failed"
1480   fi
1481   at_result="$at_result unexpectedly and inhibited subsequent tests."
1482 else
1483   # Don't you just love exponential explosion of the number of cases?
1484   case $at_xpass_count:$at_fail_count:$at_xfail_count in
1485     # So far, so good.
1486     0:0:0) at_result="$at_result $at_were successful." ;;
1487     0:0:*) at_result="$at_result behaved as expected." ;;
1489     # Some unexpected failures
1490     0:*:0) at_result="$at_result $at_were run,
1491 $at_fail_count failed unexpectedly." ;;
1493     # Some failures, both expected and unexpected
1494     0:*:1) at_result="$at_result $at_were run,
1495 $at_total_fail_count failed ($at_xfail_count expected failure)." ;;
1496     0:*:*) at_result="$at_result $at_were run,
1497 $at_total_fail_count failed ($at_xfail_count expected failures)." ;;
1499     # No unexpected failures, but some xpasses
1500     *:0:*) at_result="$at_result $at_were run,
1501 $at_xpass_count passed unexpectedly." ;;
1503     # No expected failures, but failures and xpasses
1504     *:1:0) at_result="$at_result $at_were run,
1505 $at_unexpected_count did not behave as expected dnl
1506 ($at_fail_count unexpected failure)." ;;
1507     *:*:0) at_result="$at_result $at_were run,
1508 $at_unexpected_count did not behave as expected dnl
1509 ($at_fail_count unexpected failures)." ;;
1511     # All of them.
1512     *:*:1) at_result="$at_result $at_were run,
1513 $at_xpass_count passed unexpectedly,
1514 $at_total_fail_count failed ($at_xfail_count expected failure)." ;;
1515     *:*:*) at_result="$at_result $at_were run,
1516 $at_xpass_count passed unexpectedly,
1517 $at_total_fail_count failed ($at_xfail_count expected failures)." ;;
1518   esac
1520   if test $at_skip_count = 0 && test $at_run_count -gt 1; then
1521     at_result="All $at_result"
1522   fi
1525 # Now put skips in the mix.
1526 case $at_skip_count in
1527   0) ;;
1528   1) at_result="$at_result
1529 1 test was skipped." ;;
1530   *) at_result="$at_result
1531 $at_skip_count tests were skipped." ;;
1532 esac
1534 if test $at_unexpected_count = 0; then
1535   echo "$at_result"
1536   echo "$at_result" >&AS_MESSAGE_LOG_FD
1537 else
1538   echo "ERROR: $at_result" >&2
1539   echo "ERROR: $at_result" >&AS_MESSAGE_LOG_FD
1540   {
1541     echo
1542     AS_BOX([Summary of the failures.])
1544     # Summary of failed and skipped tests.
1545     if test $at_fail_count != 0; then
1546       echo "Failed tests:"
1547       $SHELL "$at_myself" $at_fail_list --list
1548       echo
1549     fi
1550     if test $at_skip_count != 0; then
1551       echo "Skipped tests:"
1552       $SHELL "$at_myself" $at_skip_list --list
1553       echo
1554     fi
1555     if test $at_xpass_count != 0; then
1556       echo "Unexpected passes:"
1557       $SHELL "$at_myself" $at_xpass_list --list
1558       echo
1559     fi
1560     if test $at_fail_count != 0; then
1561       AS_BOX([Detailed failed tests.])
1562       echo
1563       for at_group in $at_fail_list
1564       do
1565         at_group_normalized=$at_group
1566         _AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
1567         cat "$at_suite_dir/$at_group_normalized/$as_me.log"
1568         echo
1569       done
1570       echo
1571     fi
1572     if test -n "$at_top_srcdir"; then
1573       AS_BOX([${at_top_build_prefix}config.log])
1574       sed 's/^/| /' ${at_top_build_prefix}config.log
1575       echo
1576     fi
1577   } >&AS_MESSAGE_LOG_FD
1579   AS_BOX([$as_me.log was created.])
1581   echo
1582   AS_ECHO(["Please send \`${at_testdir+${at_testdir}/}$as_me.log' ]dnl
1583 [and all information you think might help:
1585    To: <AT_PACKAGE_BUGREPORT>
1586    Subject: @<:@AT_PACKAGE_STRING@:>@ $as_me: dnl
1587 $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}dnl
1588 $at_xpass_list${at_xpass_list:+ passed unexpectedly}
1590   if test $at_debug_p = false; then
1591     echo
1592     echo 'You may investigate any problem if you feel able to do so, in which'
1593     echo 'case the test suite provides a good starting point.  Its output may'
1594     AS_ECHO(["be found below \`${at_testdir+${at_testdir}/}$as_me.dir'."])
1595     echo
1596   fi
1597     exit 1
1600 exit 0
1602 m4_text_box([Actual tests.])
1603 m4_divert_pop([TESTS])dnl
1604 dnl End of AT_INIT: divert to KILL, only test groups are to be
1605 dnl output, the rest is ignored.  Current diversion is BODY, inherited
1606 dnl from M4sh.
1607 m4_divert([KILL])
1608 ])# AT_INIT
1611 # _AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ARGS],[ACTION-IF-GIVEN],
1612 #                [ACTION-IF-NOT-GIVEN])
1613 # ---------------------------------------------------------------------------
1614 # Internal implementation of AT_ARG_OPTION & AT_ARG_OPTION_ARG
1615 m4_defun([_AT_ARG_OPTION],
1616 [m4_divert_once([HELP_OTHER],
1617 [cat <<_ATEOF || at_write_fail=1
1619 Other options:
1620 _ATEOF
1621 ])dnl m4_divert_once HELP_OTHER
1622 m4_divert_text([HELP_OTHER],
1623 [cat <<_ATEOF || at_write_fail=1
1625 _ATEOF])dnl
1626 dnl Turn our options into our desired strings
1627 m4_ifdef([AT_first_option],[m4_undefine([AT_first_option])])dnl
1628 m4_ifdef([AT_case],[m4_undefine([AT_case])])dnl
1629 m4_ifdef([AT_case_no],[m4_undefine([AT_case_no])])dnl
1630 m4_ifdef([AT_case_arg],[m4_undefine([AT_case_arg])])dnl
1631 m4_foreach([AT_option], m4_split(m4_normalize([$1]),[[ \|]+]),
1632 [m4_define_default([AT_first_option],AT_option)dnl
1633 m4_append([AT_case],m4_if(m4_len(AT_option),1,[],[-])[-]AT_option, [ | ])dnl
1634 m4_append([AT_case_no],[--no]AT_option, [ | ])dnl
1635 m4_append([AT_case_arg],
1636           m4_if(m4_len(AT_option),1,[],[-])[-]AT_option[=*], [ | ])dnl
1637 ])dnl m4_foreach AT_option
1638 dnl keep track so we or the user may process ACTION-IF-NOT-GIVEN
1639 m4_divert_once([PARSE_ARGS_BEGIN],
1642 ## Set up package specific options.
1644 ])dnl
1645 m4_divert_text([PARSE_ARGS_BEGIN],
1646 [dnl Provide a default value for options without arguments.
1647 m4_ifvaln([$3],,[at_arg_[]m4_bpatsubst([AT_first_option], -, _)=false])dnl
1648 at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=false
1649 ])dnl m4_divert_text DEFAULTS
1650 m4_divert_text([PARSE_ARGS],
1651 [dnl Parse the options and args when necessary.
1652 m4_ifvaln([$3],
1653 [    AT_case )
1654         at_prev=--m4_bpatsubst([AT_first_option], -, _)
1655         ;;
1656     AT_case_arg )
1657         at_arg_[]m4_bpatsubst([AT_first_option], -, _)=$at_optarg
1658         at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
1659         $4
1660         ;;],
1661 [    AT_case )
1662         at_optarg=:
1663         at_arg_[]m4_bpatsubst([AT_first_option], -, _)=:
1664         at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
1665         m4_ifval([$4],[$4])dnl
1666         ;;
1667     AT_case_no )
1668         at_optarg=false
1669         at_arg_[]m4_bpatsubst([AT_first_option], -, _)=false
1670         at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
1671         m4_ifval([$4],[$4])dnl
1672         ;;])dnl m4_ifvaln $3
1673 ])dnl m4_divert_text PARSE_ARGS
1674 m4_ifvaln([$5],
1675 [m4_divert_once([PARSE_ARGS_END],
1678 ## Process package specific options when _not_ supplied.
1679 ##])dnl m4_divert_once PARSE_ARGS_END
1680 m4_divert_text([PARSE_ARGS_END],
1682 AS_IF([$at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)],,[$5])dnl
1683 ])dnl m4_divert_text PARSE_ARGS_END
1684 ])dnl m4_ifvaln $5
1685 ])dnl _AT_ARG_OPTION
1688 # AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
1689 # ------------------------------------------------------------------------
1690 # Accept a set of OPTIONS with arguments.  Add HELP-TEXT to the HELP_OTHER
1691 # diversion.
1693 # Preceding dashes should not be passed into OPTIONS.  Users will be required
1694 # to pass `--' before long options and `-' before single character options.
1696 # $at_arg_OPTION will be set to `:' if this option is received, `false' if
1697 # if --noOPTION is received, and `false' by default.
1699 # Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered with
1700 # $at_optarg set to `:' or `false' as appropriate.  $at_optarg is actually
1701 # just a copy of $at_arg_OPTION.
1703 # ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
1704 # if no option from OPTIONS was found.
1705 m4_defun([AT_ARG_OPTION],[_AT_ARG_OPTION([$1],[$2],,[$3],[$4])])
1708 # AT_ARG_OPTION_ARG(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
1709 # ---------------------------------------------------------------------------
1710 # Accept a set of OPTIONS with arguments, seperated by commas.  Add HELP-TEXT
1711 # to the HELP_OTHER diversion.
1713 # Preceding dashes should not be passed into OPTIONS.  Users will be required
1714 # to pass `--' before long options and `-' before single character options.
1716 # By default, any argument to these options will be assigned to the shell
1717 # variable $at_arg_OPTION, where OPTION is the first option in OPTIONS with
1718 # any `-' characters replaced with `_'.
1720 # Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered with
1721 # $at_optarg set.  $at_optarg is actually just a copy of $at_arg_OPTION.
1723 # ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
1724 # if no option from OPTIONS was found.
1725 m4_defun([AT_ARG_OPTION_ARG],[_AT_ARG_OPTION([$1],[$2],1,[$3],[$4])])
1728 # AT_TESTED(PROGRAMS)
1729 # -------------------
1730 # Specify the list of programs exercised by the test suite.  Their
1731 # versions are logged, and in the case of embedded test suite, they
1732 # must correspond to the version of the package.  PATH should be
1733 # already preset so the proper executable will be selected.
1734 m4_define([AT_TESTED],
1735 [m4_append_uniq_w([AT_tested], [$1])])
1738 # AT_COPYRIGHT(TEXT, [FILTER = m4_newline])
1739 # -----------------------------------------
1740 # Emit TEXT, a copyright notice, in the top of the test suite and in
1741 # --version output.  Macros in TEXT are evaluated once.  Process
1742 # the --version output through FILTER (m4_newline, m4_do, and
1743 # m4_copyright_condense are common filters).
1744 m4_define([AT_COPYRIGHT],
1745 [AS_COPYRIGHT([$1])[]]dnl
1746 [m4_divert_text([VERSION_NOTICES],
1747 [m4_default([$2], [m4_newline])([$1])])])# AT_COPYRIGHT
1750 # AT_SETUP(DESCRIPTION)
1751 # ---------------------
1752 # Start a group of related tests, all to be executed in the same subshell.
1753 # The group is testing what DESCRIPTION says.
1754 _AT_DEFINE_INIT([AT_SETUP],
1755 [m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])],
1756   [m4_define([AT_ingroup], [AS_ECHO(["$at_setup_line"]) >"$at_check_line_file"
1757 ])])
1758 m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])])
1759 m4_define([AT_capture_files], [])
1760 m4_define([AT_line], AT_LINE)
1761 m4_define([AT_xfail], [at_xfail=no])
1762 m4_define([AT_description], m4_expand([$1]))
1763 m4_define([AT_ordinal], m4_incr(AT_ordinal))
1764 m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal]))
1765 m4_divert_push([TEST_GROUPS])dnl
1766 [#AT_START_]AT_ordinal
1767 @%:@ AT_ordinal. m4_defn([AT_line]): m4_defn([AT_description])
1768 at_setup_line='m4_defn([AT_line])'
1769 m4_if(AT_banner_ordinal, [0], [], [at_fn_banner AT_banner_ordinal
1770 ])dnl
1771 at_desc="AS_ESCAPE(m4_dquote(m4_defn([AT_description])))"
1772 at_desc_line=m4_format(["%3d: $at_desc%*s"], AT_ordinal,
1773   m4_max(0, m4_eval(47 - m4_qlen(m4_defn([AT_description])))), [])
1774 $at_quiet AS_ECHO_N(["$at_desc_line"])
1775 m4_divert_push([TEST_SCRIPT])dnl
1779 # AT_XFAIL_IF(SHELL-EXPRESSION)
1780 # -----------------------------
1781 # Set up the test to be expected to fail if SHELL-EXPRESSION evaluates to
1782 # true (exitcode = 0).
1783 _AT_DEFINE_SETUP([AT_XFAIL_IF],
1784 [dnl
1785 dnl Try to limit the amount of conditionals that we emit.
1786 m4_case([$1],
1787       [], [],
1788       [false], [],
1789       [:], [m4_define([AT_xfail], [at_xfail=yes])],
1790       [true], [m4_define([AT_xfail], [at_xfail=yes])],
1791       [m4_append([AT_xfail], [
1792       $1 && at_xfail=yes])])])
1795 # AT_KEYWORDS(KEYWORDS)
1796 # ---------------------
1797 # Declare a list of keywords associated to the current test group.
1798 # Since the -k option is case-insensitive, the list is stored in lower case
1799 # to avoid duplicates that differ only by case.
1800 _AT_DEFINE_SETUP([AT_KEYWORDS],
1801 [m4_append_uniq_w([AT_keywords], m4_tolower(m4_dquote(_m4_expand([$1
1802 ]))))])
1805 # AT_CAPTURE_FILE(FILE)
1806 # ---------------------
1807 # If the current test group does not behave as expected, save the contents of
1808 # FILE in the test suite log.
1809 _AT_DEFINE_SETUP([AT_CAPTURE_FILE],
1810 [m4_append_uniq([AT_capture_files], ["$1"], [ \
1811 ])])
1814 # AT_CLEANUP
1815 # ----------
1816 # Complete a group of related tests.
1817 _AT_DEFINE_INIT([AT_CLEANUP],
1818 [m4_ifdef([AT_ingroup], [AT_ingroup[]_m4_undefine([AT_ingroup])],
1819   [m4_fatal([$0: missing AT_SETUP detected])])dnl
1820 m4_append([AT_help_all],
1821 m4_defn([AT_ordinal]);m4_defn([AT_line]);m4_defn([AT_description]);dnl
1822 m4_ifdef([AT_keywords], [m4_defn([AT_keywords])]);
1823 )dnl
1824 m4_divert_pop([TEST_SCRIPT])dnl Back to TEST_GROUPS
1825 AT_xfail
1826 echo "#                             -*- compilation -*-" >> "$at_group_log"
1828   AS_ECHO(["AT_ordinal. m4_defn([AT_line]): testing $1..."])
1829   $at_traceon
1830 m4_undivert([TEST_SCRIPT])dnl Insert the code here
1831   $at_traceoff
1832   $at_times_p && times >"$at_times_file"
1833 ) AS_MESSAGE_LOG_FD>&1 2>&1 | eval $at_tee_pipe
1834 read at_status <"$at_status_file"
1835 [#AT_STOP_]AT_ordinal
1836 m4_divert_pop([TEST_GROUPS])dnl Back to KILL.
1837 ])# AT_CLEANUP
1840 # AT_BANNER([TEXT])
1841 # -----------------
1842 # Start a category of related test groups.  If multiple groups are executed,
1843 # output TEXT as a banner without any shell expansion, prior to any test
1844 # from the category.  If TEXT is empty, no banner is printed.
1845 _AT_DEFINE_INIT([AT_BANNER],
1846 [m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])])dnl
1847 m4_define([AT_banner_ordinal], m4_incr(AT_banner_ordinal))
1848 m4_divert_text([BANNERS],
1849 [@%:@ Banner AT_banner_ordinal. AT_LINE
1850 @%:@ Category starts at test group m4_incr(AT_ordinal).
1851 at_banner_text_[]AT_banner_ordinal="AS_ESCAPE([$1])"])dnl
1852 ])# AT_BANNER
1855 # AT_DATA(FILE, CONTENTS)
1856 # -----------------------
1857 # Initialize an input data FILE with given CONTENTS, which should end with
1858 # an end of line.
1859 # This macro is not robust to active symbols in CONTENTS *on purpose*.
1860 # If you don't want CONTENTS to be evaluated, quote it twice.
1861 _AT_DEFINE_SETUP([AT_DATA],
1862 [cat >$1 <<'_ATEOF'
1863 $2[]_ATEOF
1867 # AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,
1868 #          [RUN-IF-FAIL], [RUN-IF-PASS])
1869 # ------------------------------------------------
1870 # Execute a test by performing given shell COMMANDS.  These commands
1871 # should normally exit with STATUS, while producing expected STDOUT and
1872 # STDERR contents.  Shell metacharacters in STDOUT and STDERR are
1873 # _not_ processed by the shell, but are treated as string literals.
1875 # STATUS, STDOUT, and STDERR are not checked if equal to `ignore'.
1877 # If STDOUT is `expout', then stdout is compared to the content of the file
1878 # `expout'.  Likewise for STDERR and `experr'.
1880 # If STDOUT is `stdout', then the stdout is left in the file `stdout',
1881 # likewise for STDERR and `stderr'.  Don't do this:
1883 #    AT_CHECK([command >out])
1884 #    # Some checks on `out'
1886 # do this instead:
1888 #    AT_CHECK([command], [], [stdout])
1889 #    # Some checks on `stdout'
1891 # You might wonder why you can't just use `ignore', then directly use stdout
1892 # and stderr left by the test suite:
1894 #    AT_CHECK([command], [], [ignore])
1895 #    AT_CHECK([check stdout])
1897 # If the test suite always captured data in the file `stdout', then the
1898 # second command would be trying to read and write from the same file, with
1899 # undefined behavior.  Therefore, the test suite actually captures data in
1900 # an internal file of a different name, and only creates `stdout' when
1901 # explicitly requested.
1903 # Any line of stderr starting with leading blanks and a `+' are filtered
1904 # out, since most shells when tracing include subshell traces in stderr.
1905 # This may cause spurious failures when the test suite is run with `-x'.
1907 _AT_DEFINE_SETUP([AT_CHECK],
1908 [_AT_CHECK(m4_expand([$1]), [$2], AS_ESCAPE(m4_dquote(m4_expand([$3]))),
1909   AS_ESCAPE(m4_dquote(m4_expand([$4]))), [$5], [$6])])
1911 # AT_CHECK_UNQUOTED(COMMANDS, [STATUS = 0], STDOUT, STDERR,
1912 #                   [RUN-IF-FAIL], [RUN-IF-PASS])
1913 # ---------------------------------------------------------
1914 # Like AT_CHECK, but do not AS_ESCAPE shell metacharacters in the STDOUT
1915 # and STDERR arguments before running the comparison.
1916 _AT_DEFINE_SETUP([AT_CHECK_UNQUOTED],
1917 [_AT_CHECK(m4_expand([$1]), [$2], AS_ESCAPE(m4_dquote(m4_expand([$3])), [""]),
1918   AS_ESCAPE(m4_dquote(m4_expand([$4])), [""]), [$5], [$6])])
1920 # AT_CHECK_NOESCAPE(COMMANDS, [STATUS = 0], STDOUT, STDERR,
1921 #                   [RUN-IF-FAIL], [RUN-IF-PASS])
1922 # ---------------------------------------------------------
1923 # Obsolete spelling of AT_CHECK_UNQUOTED.
1924 m4_define([AT_CHECK_NOESCAPE],
1925 [m4_warn([obsolete], [consider using AT_CHECK_UNQUOTED instead of $0])]dnl
1926 [_AT_CHECK(m4_expand([$1]), [$2], m4_expand([$3]),
1927   m4_expand([$4]), [$5], [$6])])
1930 # _AT_DECIDE_TRACEABLE(COMMANDS)
1931 # ------------------------------
1932 # Worker for _AT_CHECK that expands to shell code.  If COMMANDS are safe to
1933 # trace with `set -x', the shell code will evaluate to true.  Otherwise,
1934 # the shell code will print a message stating an aspect of COMMANDS that makes
1935 # tracing them unsafe, and evaluate to false.
1937 # Tracing COMMANDS is not safe if they contain a command that spans multiple
1938 # lines.  When the test suite user passes `-x' or `--trace', the test suite
1939 # precedes every command with a `set -x'.  Since most tests expect a specific
1940 # stderr, if only to confirm that it is empty, the test suite filters ^+ from
1941 # the captured stderr before comparing with the expected stderr.  If a command
1942 # spans multiple lines, so will its trace, but a `+' only prefixes the first
1943 # line of that trace:
1945 # $ echo 'foo
1946 # bar'
1947 # => stdout
1948 # foo
1949 # bar
1950 # => stderr
1951 # + foo
1952 # bar
1954 # In a subset of cases, one could filter such extended shell traces from
1955 # stderr.  Since test commands spanning several lines are rare, I chose
1956 # instead to simply not trace COMMANDS that could yield multiple trace lines.
1957 # Distinguishing such COMMANDS became the task at hand.
1959 # These features may cause a shell command to span multiple lines:
1961 # (a) A quoted literal newline.
1962 # Example:
1963 #   echo foo'
1964 #   'bar
1965 # M4 is a hostile language for the job of parsing COMMANDS to determine whether
1966 # each literal newline is quoted, so we simply disable tracing for all COMMANDS
1967 # that bear literal newlines.
1969 # (b) A command substitution not subject to word splitting.
1970 # Example:
1971 #   var=$(printf 'foo\nbar')
1972 # Example:
1973 #   echo "`printf 'foo\\nbar`"
1974 # One cannot know in general the number of lines a command substitution will
1975 # yield without executing the substituted command.  As such, we disable tracing
1976 # for all COMMANDS containing these constructs.
1978 # (c) A parameter expansion not subject to word splitting.
1979 # Example:
1980 #   var=foo'
1981 #   'bar
1982 #   echo "$var"
1983 # Parameter expansions appear in COMMANDS with much greater frequency than do
1984 # newlines and command substitutions, so disabling tracing for all such
1985 # COMMANDS would much more substantially devalue `testsuite -x'.  To determine
1986 # which parameter expansions yield multiple lines, we escape all ``', `"',
1987 # and `\' in a copy of COMMANDS and expand that string within double quotes
1988 # at runtime.  If the result of that expansion contains multiple lines, the
1989 # test suite disables tracing for the command in question.
1991 # This method leads the test suite to expand some parameters that the shell
1992 # itself will never expand due to single-quotes or backslash escapes.  This is
1993 # not a problem for `$foo' expansions, which will simply yield the empty string
1994 # or some unrelated value.  A `${...}' expansion could actually form invalid
1995 # shell code, however; consider `${=foo}'.  Therefore, we disable tracing for
1996 # all COMMANDS containing `${...}'.  This affects few COMMANDS.
1998 # This macro falls in a very hot path; the Autoconf test suite expands it 1640
1999 # times as of this writing.  To give a sense of the impact of the heuristics I
2000 # just described, the test suite preemptively disables tracing for 31 of those,
2001 # and 268 contain parameter expansions that require runtime evaluation.  The
2002 # balance are always safe to trace.
2003 m4_define([_AT_DECIDE_TRACEABLE],
2004 dnl Utility macro.
2006 dnl Examine COMMANDS for a reason to never trace COMMANDS.
2007 [m4_pushdef([at_reason],
2008 m4_cond([m4_eval(m4_index([$1], [`]) >= 0)], [1],
2009                 [[a `...` command substitution]],
2010         [m4_eval(m4_index([$1], [$(]) >= 0)], [1],
2011                 [[a $(...) command substitution]],
2012         [m4_eval(m4_index([$1], [${]) >= 0)], [1],
2013                 [[a ${...} parameter expansion]],
2014         [m4_eval(m4_index([$1], m4_newline) >= 0)], [1],
2015                 [[an embedded newline]],
2016         []))]dnl No reason.
2017 [m4_if(m4_index(_m4_defn([at_reason]), [a]), [0],]dnl
2018 dnl We know at build time that tracing COMMANDS is never safe.
2019 [[echo 'Not enabling shell tracing (command contains ]m4_defn([at_reason])[)'
2020 at_fn_check_prepare_notrace],
2021        m4_index([$1], [$]), [-1],]dnl
2022 dnl We know at build time that tracing COMMANDS is always safe.
2023 [[at_fn_check_prepare_trace],]dnl
2024 dnl COMMANDS may contain parameter expansions; expand them at runtime.
2025 [[at_fn_check_prepare_dynamic "AS_ESCAPE([[$1]], [`\"])"])[]]dnl
2026 [_m4_popdef([at_reason])])
2029 # AT_DIFF_STDERR/AT_DIFF_STDOUT
2030 # -----------------------------
2031 # These are subroutines of AT_CHECK.  Using indirect dispatch is a tad
2032 # faster than using m4_case, and these are called very frequently.
2033 m4_define([AT_DIFF_STDERR(stderr)],
2034           [echo stderr:; tee stderr <"$at_stderr"])
2035 m4_define([AT_DIFF_STDERR(stderr-nolog)],
2036           [echo stderr captured; cp "$at_stderr" stderr])
2037 m4_define([AT_DIFF_STDERR(ignore)],
2038           [echo stderr:; cat "$at_stderr"])
2039 m4_define([AT_DIFF_STDERR(ignore-nolog)])
2040 m4_define([AT_DIFF_STDERR(experr)],
2041           [$at_diff experr "$at_stderr" || at_failed=:])
2042 m4_define([AT_DIFF_STDERR()],
2043           [at_fn_diff_devnull "$at_stderr" || at_failed=:])
2045 m4_define([AT_DIFF_STDOUT(stdout)],
2046           [echo stdout:; tee stdout <"$at_stdout"])
2047 m4_define([AT_DIFF_STDOUT(stdout-nolog)],
2048           [echo stdout captured; cp "$at_stdout" stdout])
2049 m4_define([AT_DIFF_STDOUT(ignore)],
2050           [echo stdout:; cat "$at_stdout"])
2051 m4_define([AT_DIFF_STDOUT(ignore-nolog)])
2052 m4_define([AT_DIFF_STDOUT(expout)],
2053           [$at_diff expout "$at_stdout" || at_failed=:])
2054 m4_define([AT_DIFF_STDOUT()],
2055           [at_fn_diff_devnull "$at_stdout" || at_failed=:])
2057 # _AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,
2058 #           [RUN-IF-FAIL], [RUN-IF-PASS])
2059 # -------------------------------------------------
2060 # Worker for AT_CHECK and AT_CHECK_UNQUOTED, with COMMANDS, STDOUT, and
2061 # STDERR pre-expanded.
2063 # Implementation Details
2064 # ----------------------
2065 # Ideally, we would like to run
2067 #    ( $at_traceon; COMMANDS >at-stdout 2> at-stderr )
2069 # but we must group COMMANDS as it is not limited to a single command, and
2070 # then the shells will save the traces in at-stderr. So we have to filter
2071 # them out when checking stderr, and we must send them into the test suite's
2072 # stderr to honor -x properly. Since only the first line of the trace of a
2073 # multiline command starts with a `+', and I know of no straightforward way to
2074 # filter out the unadorned trace lines, we disable shell tracing entirely for
2075 # commands that could span multiple lines.
2077 # Limiting COMMANDS to a single command is not good either, since then
2078 # the user herself would use {} or (), and then we face the same problem.
2080 # But then, there is no point in running
2082 #   ( $at_traceon { $1 ; } >at-stdout 2>at-stder1 )
2084 # instead of the simpler
2086 #  ( $at_traceon; $1 ) >at-stdout 2>at-stder1
2088 # Note that we truncate and append to the output files, to avoid losing
2089 # output from multiple concurrent processes, e.g., an inner testsuite
2090 # with parallel jobs.
2091 m4_define([_AT_CHECK],
2092 [m4_define([AT_ingroup])]dnl
2093 [{ $at_traceoff
2094 AS_ECHO(["$at_srcdir/AT_LINE: AS_ESCAPE([[$1]])"])
2095 _AT_DECIDE_TRACEABLE([$1]) "AS_ESCAPE(m4_dquote(AT_LINE))"
2096 ( $at_check_trace; [$1]
2097 ) >>"$at_stdout" 2>>"$at_stderr"
2098 at_status=$? at_failed=false
2099 $at_check_filter
2100 m4_ifdef([AT_DIFF_STDERR($4)], [m4_indir([AT_DIFF_STDERR($4)])],
2101   [echo >>"$at_stderr"; AS_ECHO([["$4"]]) | \
2102   $at_diff - "$at_stderr" || at_failed=:])
2103 m4_ifdef([AT_DIFF_STDOUT($3)], [m4_indir([AT_DIFF_STDOUT($3)])],
2104   [echo >>"$at_stdout"; AS_ECHO([["$3"]]) | \
2105   $at_diff - "$at_stdout" || at_failed=:])
2106 m4_if([$2], [ignore], [at_fn_check_skip],
2107   [at_fn_check_status m4_default([$2], [0])]) $at_status "$at_srcdir/AT_LINE"
2108 m4_ifvaln([$5$6], [AS_IF($at_failed, [$5], [$6])])]dnl
2109 [$at_failed && at_fn_log_failure AT_capture_files
2110 $at_traceon; }
2111 ])# _AT_CHECK