Simplify handling of autotest tracing
[autoconf.git] / lib / autotest / general.m4
blob59cce958e6c86cdef2b6e09dc2d6914c1d8183de
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], [REASON LINE],
267 [Perform AT_CHECK preparations for the command at LINE for an
268 untraceable command; REASON is the reason for disabling tracing.])
269 at_fn_check_prepare_notrace ()
271   $at_trace_echo "Not enabling shell tracing (command contains $1)"
272   AS_ECHO(["$[2]"]) >"$at_check_line_file"
273   at_check_trace=: at_check_filter=:
274   : >"$at_stdout"; : >"$at_stderr"
277 AS_FUNCTION_DESCRIBE([at_fn_check_prepare_trace], [LINE],
278 [Perform AT_CHECK preparations for the command at LINE for a traceable
279 command.])
280 at_fn_check_prepare_trace ()
282   AS_ECHO(["$[1]"]) >"$at_check_line_file"
283   at_check_trace=$at_traceon at_check_filter=$at_check_filter_trace
284   : >"$at_stdout"; : >"$at_stderr"
287 AS_FUNCTION_DESCRIBE([at_fn_check_prepare_dynamic], [COMMAND LINE],
288 [Decide if COMMAND at LINE is traceable at runtime, and call the
289 appropriate preparation function.])
290 at_fn_check_prepare_dynamic ()
292   case $[1] in
293     *$as_nl*)
294       at_fn_check_prepare_notrace 'an embedded newline' "$[2]" ;;
295     *)
296       at_fn_check_prepare_trace "$[2]" ;;
297   esac
300 AS_FUNCTION_DESCRIBE([at_fn_filter_trace], [],
301 [Remove the lines in the file "$at_stderr" generated by "set -x" and print
302 them to stderr.])
303 at_fn_filter_trace ()
305   mv "$at_stderr" "$at_stder1"
306   grep '^ *+' "$at_stder1" >&2
307   grep -v '^ *+' "$at_stder1" >"$at_stderr"
310 AS_FUNCTION_DESCRIBE([at_fn_log_failure], [FILE-LIST],
311 [Copy the files in the list on stdout with a "> " prefix, and exit the shell
312 with a failure exit code.])
313 at_fn_log_failure ()
315   for file
316     do AS_ECHO(["$file:"]); sed 's/^/> /' "$file"; done
317   echo 1 > "$at_status_file"
318   exit 1
321 AS_FUNCTION_DESCRIBE([at_fn_check_skip], [EXIT-CODE LINE],
322 [Check whether EXIT-CODE is a special exit code (77 or 99), and if so exit
323 the test group subshell with that same exit code.  Use LINE in any report
324 about test failure.])
325 at_fn_check_skip ()
327   case $[1] in
328     99) echo 99 > "$at_status_file"; at_failed=:
329         AS_ECHO(["$[2]: hard failure"]); exit 99;;
330     77) echo 77 > "$at_status_file"; exit 77;;
331   esac
334 AS_FUNCTION_DESCRIBE([at_fn_check_status], [EXPECTED EXIT-CODE LINE],
335 [Check whether EXIT-CODE is the EXPECTED exit code, and if so do nothing.
336 Otherwise, if it is 77 or 99, exit the test group subshell with that same
337 exit code; if it is anything else print an error message referring to LINE,
338 and fail the test.])
339 at_fn_check_status ()
341 dnl This order ensures that we don't `skip' if we are precisely checking
342 dnl $? = 77 or $? = 99.
343   case $[2] in
344     $[1] ) ;;
345     77) echo 77 > "$at_status_file"; exit 77;;
346     99) echo 99 > "$at_status_file"; at_failed=:
347         AS_ECHO(["$[3]: hard failure"]); exit 99;;
348     *) AS_ECHO(["$[3]: exit code was $[2], expected $[1]"])
349       at_failed=:;;
350   esac
353 AS_FUNCTION_DESCRIBE([at_fn_diff_devnull], [FILE],
354 [Emit a diff between /dev/null and FILE.  Uses "test -s" to avoid useless
355 diff invocations.])
356 at_fn_diff_devnull ()
358   test -s "$[1]" || return 0
359   $at_diff "$at_devnull" "$[1]"
362 AS_FUNCTION_DESCRIBE([at_fn_test], [NUMBER],
363 [Parse out test NUMBER from the tail of this file.])
364 at_fn_test ()
366   eval at_sed=\$at_sed$[1]
367   sed "$at_sed" "$at_myself" > "$at_test_source"
370 AS_FUNCTION_DESCRIBE([at_fn_create_debugging_script], [],
371 [Create the debugging script $at_group_dir/run which will reproduce the
372 current test group.])
373 at_fn_create_debugging_script ()
375   {
376     echo "#! /bin/sh" &&
377     echo 'test "${ZSH_VERSION+set}" = set dnl
378 && alias -g '\''${1+"$[@]"}'\''='\''"$[@]"'\''' &&
379     AS_ECHO(["cd '$at_dir'"]) &&
380     AS_ECHO(["exec \${CONFIG_SHELL-$SHELL} \"$at_myself\" -v -d ]dnl
381 [$at_debug_args $at_group \${1+\"\$[@]\"}"]) &&
382     echo 'exit 1'
383   } >"$at_group_dir/run" &&
384   chmod +x "$at_group_dir/run"
387 m4_text_box([End of autotest shell functions.])
388 m4_divert_pop([PREPARE_TESTS])dnl back to DEFAULTS
390 # Not all shells have the 'times' builtin; the subshell is needed to make
391 # sure we discard the 'times: not found' message from the shell.
392 at_times_p=false
393 (times) >/dev/null 2>&1 && at_times_p=:
395 # CLI Arguments to pass to the debugging scripts.
396 at_debug_args=
397 # -e sets to true
398 at_errexit_p=false
399 # Shall we be verbose?  ':' means no, empty means yes.
400 at_verbose=:
401 at_quiet=
402 # Running several jobs in parallel, 0 means as many as test groups.
403 at_jobs=1
404 at_traceon=:
405 at_trace_echo=:
406 at_check_filter_trace=:
408 # Shall we keep the debug scripts?  Must be `:' when the suite is
409 # run by a debug script, so that the script doesn't remove itself.
410 at_debug_p=false
411 # Display help message?
412 at_help_p=false
413 # Display the version message?
414 at_version_p=false
415 # List test groups?
416 at_list_p=false
417 # --clean
418 at_clean=false
419 # Test groups to run
420 at_groups=
421 # Whether a write failure occurred
422 at_write_fail=0
424 # The directory we run the suite in.  Default to . if no -C option.
425 at_dir=`pwd`
426 # An absolute reference to this testsuite script.
427 dnl m4-double quote, to preserve []
428 [case $as_myself in
429   [\\/]* | ?:[\\/]* ) at_myself=$as_myself ;;
430   * ) at_myself=$at_dir/$as_myself ;;
431 esac]
432 # Whether -C is in effect.
433 at_change_dir=false
434 m4_divert_pop([DEFAULTS])dnl
435 m4_define([_AT_FINISH],
436 [m4_ifdef([AT_ingroup], [m4_fatal([missing AT_CLEANUP detected])])dnl
437 m4_divert_text([DEFAULTS],
439 # List of the tested programs.
440 at_tested='m4_ifdef([AT_tested],
441   [m4_translit(m4_dquote(m4_defn([AT_tested])), [ ], m4_newline)])'
442 # List of the all the test groups.
443 at_groups_all='AT_groups_all'
444 # As many question marks as there are digits in the last test group number.
445 # Used to normalize the test group numbers so that `ls' lists them in
446 # numerical order.
447 at_format='m4_bpatsubst(m4_defn([AT_ordinal]), [.], [?])'
448 # Description of all the test groups.
449 at_help_all="AS_ESCAPE(m4_dquote(m4_defn([AT_help_all])))"
451 AS_FUNCTION_DESCRIBE([at_fn_validate_ranges], [NAME...],
452 [Validate and normalize the test group number contained in each
453 variable NAME.  Leading zeroes are treated as decimal.])
454 at_fn_validate_ranges ()
456   for at_grp
457   do
458     eval at_value=\$$at_grp
459     if test $at_value -lt 1 || test $at_value -gt AT_ordinal; then
460       AS_ECHO(["invalid test group: $at_value"]) >&2
461       exit 1
462     fi
463     case $at_value in
464       0*) # We want to treat leading 0 as decimal, like expr and test, but
465           # AS_VAR_ARITH treats it as octal if it uses $(( )).
466           # With XSI shells, ${at_value#${at_value%%[1-9]*}} avoids the
467           # expr fork, but it is not worth the effort to determine if the
468           # shell supports XSI when the user can just avoid leading 0.
469           eval $at_grp='`expr $at_value + 0`' ;;
470     esac
471   done
472 }])])dnl
473 m4_divert_push([PARSE_ARGS])dnl
475 at_prev=
476 for at_option
478   # If the previous option needs an argument, assign it.
479   if test -n "$at_prev"; then
480     at_option=$at_prev=$at_option
481     at_prev=
482   fi
484   case $at_option in
485   *=*) at_optarg=`expr "x$at_option" : 'x[[^=]]*=\(.*\)'` ;;
486   *)   at_optarg= ;;
487   esac
489   # Accept the important Cygnus configure options, so we can diagnose typos.
491   case $at_option in
492     --help | -h )
493         at_help_p=:
494         ;;
496     --list | -l )
497         at_list_p=:
498         ;;
500     --version | -V )
501         at_version_p=:
502         ;;
504     --clean | -c )
505         at_clean=:
506         ;;
508     --debug | -d )
509         at_debug_p=:
510         ;;
512     --errexit | -e )
513         at_debug_p=:
514         at_errexit_p=:
515         ;;
517     --verbose | -v )
518         at_verbose=; at_quiet=:
519         ;;
521     --trace | -x )
522         at_traceon='set -x'
523         at_trace_echo=echo
524         at_check_filter_trace=at_fn_filter_trace
525         ;;
527     [[0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]])
528         at_fn_validate_ranges at_option
529         AS_VAR_APPEND([at_groups], ["$at_option "])
530         ;;
532     # Ranges
533     [[0-9]- | [0-9][0-9]- | [0-9][0-9][0-9]- | [0-9][0-9][0-9][0-9]-])
534         at_range_start=`echo $at_option |tr -d X-`
535         at_fn_validate_ranges at_range_start
536         at_range=`AS_ECHO([" $at_groups_all "]) | \
537           sed -e 's/^.* \('$at_range_start' \)/\1/'`
538         AS_VAR_APPEND([at_groups], ["$at_range "])
539         ;;
541     [-[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | -[0-9][0-9][0-9][0-9]])
542         at_range_end=`echo $at_option |tr -d X-`
543         at_fn_validate_ranges at_range_end
544         at_range=`AS_ECHO([" $at_groups_all "]) | \
545           sed -e 's/\( '$at_range_end'\) .*$/\1/'`
546         AS_VAR_APPEND([at_groups], ["$at_range "])
547         ;;
549     [[0-9]-[0-9] | [0-9]-[0-9][0-9] | [0-9]-[0-9][0-9][0-9]] | \
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][0-9][0-9]] | \
552     [[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][0-9]] | \
554     [[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]] )
555         at_range_start=`expr $at_option : '\(.*\)-'`
556         at_range_end=`expr $at_option : '.*-\(.*\)'`
557         if test $at_range_start -gt $at_range_end; then
558           at_tmp=$at_range_end
559           at_range_end=$at_range_start
560           at_range_start=$at_tmp
561         fi
562         at_fn_validate_ranges at_range_start at_range_end
563         at_range=`AS_ECHO([" $at_groups_all "]) | \
564           sed -e 's/^.*\( '$at_range_start' \)/\1/' \
565               -e 's/\( '$at_range_end'\) .*$/\1/'`
566         AS_VAR_APPEND([at_groups], ["$at_range "])
567         ;;
569     # Directory selection.
570     --directory | -C )
571         at_prev=--directory
572         ;;
573     --directory=* )
574         at_change_dir=:
575         at_dir=$at_optarg
576         ;;
578     # Parallel execution.
579     --jobs | -j )
580         at_jobs=0
581         ;;
582     --jobs=* | -j[[0-9]]* )
583         if test -n "$at_optarg"; then
584           at_jobs=$at_optarg
585         else
586           at_jobs=`expr X$at_option : 'X-j\(.*\)'`
587         fi
588         case $at_jobs in *[[!0-9]]*)
589           at_optname=`echo " $at_option" | sed 's/^ //; s/[[0-9=]].*//'`
590           AS_ERROR([non-numeric argument to $at_optname: $at_jobs]) ;;
591         esac
592         ;;
594     # Keywords.
595     --keywords | -k )
596         at_prev=--keywords
597         ;;
598     --keywords=* )
599         at_groups_selected=$at_help_all
600         at_save_IFS=$IFS
601         IFS=,
602         set X $at_optarg
603         shift
604         IFS=$at_save_IFS
605         for at_keyword
606         do
607           at_invert=
608           case $at_keyword in
609           '!'*)
610             at_invert="-v"
611             at_keyword=`expr "X$at_keyword" : 'X!\(.*\)'`
612             ;;
613           esac
614           # It is on purpose that we match the test group titles too.
615           at_groups_selected=`AS_ECHO(["$at_groups_selected"]) |
616               grep -i $at_invert ["^[1-9][^;]*;.*[; ]$at_keyword[ ;]"]`
617         done
618         # Smash the newlines.
619         at_groups_selected=`AS_ECHO(["$at_groups_selected"]) | sed 's/;.*//' |
620           tr "$as_nl" ' '
621         `
622         AS_VAR_APPEND([at_groups], ["$at_groups_selected "])
623         ;;
624 m4_divert_pop([PARSE_ARGS])dnl
625 dnl Process *=* last to allow for user specified --option=* type arguments.
626 m4_divert_push([PARSE_ARGS_END])dnl
628     *=*)
629         at_envvar=`expr "x$at_option" : 'x\([[^=]]*\)='`
630         # Reject names that are not valid shell variable names.
631         case $at_envvar in
632           '' | [[0-9]]* | *[[!_$as_cr_alnum]]* )
633             AS_ERROR([invalid variable name: `$at_envvar']) ;;
634         esac
635         at_value=`AS_ECHO(["$at_optarg"]) | sed "s/'/'\\\\\\\\''/g"`
636         # Export now, but save eval for later and for debug scripts.
637         export $at_envvar
638         AS_VAR_APPEND([at_debug_args], [" $at_envvar='$at_value'"])
639         ;;
641      *) AS_ECHO(["$as_me: invalid option: $at_option"]) >&2
642         AS_ECHO(["Try \`$[0] --help' for more information."]) >&2
643         exit 1
644         ;;
645   esac
646 done
648 # Verify our last option didn't require an argument
649 AS_IF([test -n "$at_prev"], [AS_ERROR([`$at_prev' requires an argument.])])
651 # Selected test groups.
652 if test -z "$at_groups"; then
653   at_groups=$at_groups_all
654 else
655   # Sort the tests, removing duplicates.
656   at_groups=`AS_ECHO(["$at_groups"]) | tr ' ' "$as_nl" | sort -nu`
658 m4_divert_pop([PARSE_ARGS_END])dnl
659 m4_divert_push([HELP])dnl
661 # Help message.
662 if $at_help_p; then
663   cat <<_ATEOF || at_write_fail=1
664 Usage: $[0] [[OPTION]... [VARIABLE=VALUE]... [TESTS]]
666 Run all the tests, or the selected TESTS, given by numeric ranges, and
667 save a detailed log file.  Upon failure, create debugging scripts.
669 Do not change environment variables directly.  Instead, set them via
670 command line arguments.  Set \`AUTOTEST_PATH' to select the executables
671 to exercise.  Each relative directory is expanded as build and source
672 directories relative to the top level of this distribution.
673 E.g., from within the build directory /tmp/foo-1.0, invoking this:
675   $ $[0] AUTOTEST_PATH=bin
677 is equivalent to the following, assuming the source directory is /src/foo-1.0:
679   PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:\$PATH $[0]
680 _ATEOF
681 m4_divert_pop([HELP])dnl
682 m4_divert_push([HELP_MODES])dnl
683 cat <<_ATEOF || at_write_fail=1
685 Operation modes:
686   -h, --help     print the help message, then exit
687   -V, --version  print version number, then exit
688   -c, --clean    remove all the files this test suite might create and exit
689   -l, --list     describes all the tests, or the selected TESTS
690 _ATEOF
691 m4_divert_pop([HELP_MODES])dnl
692 m4_divert_push([HELP_TUNING])dnl
693 cat <<_ATEOF || at_write_fail=1
695 dnl extra quoting prevents emacs whitespace mode from putting tabs in output
696 Execution tuning:
697   -C, --directory=DIR
698 [                 change to directory DIR before starting]
699   -j, --jobs[[=N]]
700 [                 Allow N jobs at once; infinite jobs with no arg (default 1)]
701   -k, --keywords=KEYWORDS
702 [                 select the tests matching all the comma-separated KEYWORDS]
703 [                 multiple \`-k' accumulate; prefixed \`!' negates a KEYWORD]
704   -e, --errexit  abort as soon as a test fails; implies --debug
705   -v, --verbose  force more detailed output
706 [                 default for debugging scripts]
707   -d, --debug    inhibit clean up and top-level logging
708 [                 default for debugging scripts]
709   -x, --trace    enable tests shell tracing
710 _ATEOF
711 m4_divert_pop([HELP_TUNING])dnl
712 m4_divert_push([HELP_END])dnl
713 cat <<_ATEOF || at_write_fail=1
715 Report bugs to <AT_PACKAGE_BUGREPORT>.dnl
716 m4_ifdef([AT_PACKAGE_NAME],
717 [m4_ifset([AT_PACKAGE_URL], [
718 m4_defn([AT_PACKAGE_NAME]) home page: <AT_PACKAGE_URL>.])dnl
719 m4_if(m4_index(m4_defn([AT_PACKAGE_NAME]), [GNU ]), [0], [
720 General help using GNU software: <http://www.gnu.org/gethelp/>.])])
721 _ATEOF
722   exit $at_write_fail
725 # List of tests.
726 if $at_list_p; then
727   cat <<_ATEOF || at_write_fail=1
728 AT_TESTSUITE_NAME test groups:
730  NUM: FILE-NAME:LINE     TEST-GROUP-NAME
731       KEYWORDS
733 _ATEOF
734   # Passing at_groups is tricky.  We cannot use it to form a literal string
735   # or regexp because of the limitation of AIX awk.  And Solaris' awk
736   # doesn't grok more than 99 fields in a record, so we have to use `split'.
737   # at_groups needs to be space-separated for this script to work.
738   case $at_groups in
739     *"$as_nl"* )
740       at_groups=`AS_ECHO(["$at_groups"]) | tr "$as_nl" ' '` ;;
741   esac
742   AS_ECHO(["$at_groups$as_nl$at_help_all"]) |
743     awk 'BEGIN { FS = ";" }
744          NR == 1 {
745            for (n = split ($ 0, a, " "); n; n--)
746              selected[[a[n]]] = 1
747            next
748          }
749          NF > 0 {
750            if (selected[[$ 1]]) {
751              printf " %3d: %-18s %s\n", $ 1, $ 2, $ 3
752              if ($ 4) {
753                lmax = 79
754                indent = "     "
755                line = indent
756                len = length (line)
757                n = split ($ 4, a, " ")
758                for (i = 1; i <= n; i++) {
759                  l = length (a[[i]]) + 1
760                  if (i > 1 && len + l > lmax) {
761                    print line
762                    line = indent " " a[[i]]
763                    len = length (line)
764                  } else {
765                    line = line " " a[[i]]
766                    len += l
767                  }
768                }
769                if (n)
770                  print line
771              }
772            }
773          }' || at_write_fail=1
774   exit $at_write_fail
776 m4_divert_pop([HELP_END])dnl
777 m4_divert_push([VERSION])dnl
778 if $at_version_p; then
779   AS_ECHO(["$as_me (AT_PACKAGE_STRING)"]) &&
780   cat <<\_ATEOF || at_write_fail=1
781 m4_divert_pop([VERSION])dnl
782 m4_divert_push([VERSION_END])dnl
783 _ATEOF
784   exit $at_write_fail
786 m4_divert_pop([VERSION_END])dnl
787 m4_divert_push([TESTS_BEGIN])dnl
789 # Take any -C into account.
790 if $at_change_dir ; then
791   if test x- = "x$at_dir" ; then
792     at_dir=./-
793   fi
794   test x != "x$at_dir" && cd "$at_dir" \
795     || AS_ERROR([unable to change directory])
796   at_dir=`pwd`
799 # Load the config files for any default variable assignments.
800 for at_file in atconfig atlocal
802   test -r $at_file || continue
803   . ./$at_file || AS_ERROR([invalid content: $at_file])
804 done
806 # Autoconf <=2.59b set at_top_builddir instead of at_top_build_prefix:
807 : ${at_top_build_prefix=$at_top_builddir}
809 # Perform any assignments requested during argument parsing.
810 eval "$at_debug_args"
812 # atconfig delivers names relative to the directory the test suite is
813 # in, but the groups themselves are run in testsuite-dir/group-dir.
814 if test -n "$at_top_srcdir"; then
815   builddir=../..
816   for at_dir_var in srcdir top_srcdir top_build_prefix
817   do
818     AS_VAR_COPY([at_val], [at_$at_dir_var])
819     case $at_val in
820       [[\\/$]]* | ?:[[\\/]]* ) at_prefix= ;;
821       *) at_prefix=../../ ;;
822     esac
823     AS_VAR_SET([$at_dir_var], [$at_prefix$at_val])
824   done
827 m4_text_box([Directory structure.])
829 # This is the set of directories and files used by this script
830 # (non-literals are capitalized):
832 # TESTSUITE         - the testsuite
833 # TESTSUITE.log     - summarizes the complete testsuite run
834 # TESTSUITE.dir/    - created during a run, remains after -d or failed test
835 # + at-groups/      - during a run: status of all groups in run
836 # | + NNN/          - during a run: meta-data about test group NNN
837 # | | + check-line  - location (source file and line) of current AT_CHECK
838 # | | + status      - exit status of current AT_CHECK
839 # | | + stdout      - stdout of current AT_CHECK
840 # | | + stder1      - stderr, including trace
841 # | | + stderr      - stderr, with trace filtered out
842 # | | + test-source - portion of testsuite that defines group
843 # | | + times       - timestamps for computing duration
844 # | | + pass        - created if group passed
845 # | | + xpass       - created if group xpassed
846 # | | + fail        - created if group failed
847 # | | + xfail       - created if group xfailed
848 # | | + skip        - created if group skipped
849 # + at-stop         - during a run: end the run if this file exists
850 # + at-source-lines - during a run: cache of TESTSUITE line numbers for extraction
851 # + 0..NNN/         - created for each group NNN, remains after -d or failed test
852 # | + TESTSUITE.log - summarizes the group results
853 # | + ...           - files created during the group
855 # The directory the whole suite works in.
856 # Should be absolute to let the user `cd' at will.
857 at_suite_dir=$at_dir/$as_me.dir
858 # The file containing the suite.
859 at_suite_log=$at_dir/$as_me.log
860 # The directory containing helper files per test group.
861 at_helper_dir=$at_suite_dir/at-groups
862 # Stop file: if it exists, do not start new jobs.
863 at_stop_file=$at_suite_dir/at-stop
864 # The fifo used for the job dispatcher.
865 at_job_fifo=$at_suite_dir/at-job-fifo
867 if $at_clean; then
868   test -d "$at_suite_dir" &&
869     find "$at_suite_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
870   rm -f -r "$at_suite_dir" "$at_suite_log"
871   exit $?
874 # Don't take risks: use only absolute directories in PATH.
876 # For stand-alone test suites (ie. atconfig was not found),
877 # AUTOTEST_PATH is relative to `.'.
879 # For embedded test suites, AUTOTEST_PATH is relative to the top level
880 # of the package.  Then expand it into build/src parts, since users
881 # may create executables in both places.
882 AUTOTEST_PATH=`AS_ECHO(["$AUTOTEST_PATH"]) | sed "s|:|$PATH_SEPARATOR|g"`
883 at_path=
884 _AS_PATH_WALK([$AUTOTEST_PATH $PATH],
885 [test -n "$at_path" && AS_VAR_APPEND([at_path], [$PATH_SEPARATOR])
886 case $as_dir in
887   [[\\/]]* | ?:[[\\/]]* )
888     AS_VAR_APPEND([at_path], ["$as_dir"])
889     ;;
890   * )
891     if test -z "$at_top_build_prefix"; then
892       # Stand-alone test suite.
893       AS_VAR_APPEND([at_path], ["$as_dir"])
894     else
895       # Embedded test suite.
896       AS_VAR_APPEND([at_path], ["$at_top_build_prefix$as_dir$PATH_SEPARATOR"])
897       AS_VAR_APPEND([at_path], ["$at_top_srcdir/$as_dir"])
898     fi
899     ;;
900 esac])
902 # Now build and simplify PATH.
904 # There might be directories that don't exist, but don't redirect
905 # builtins' (eg., cd) stderr directly: Ultrix's sh hates that.
906 at_new_path=
907 _AS_PATH_WALK([$at_path],
908 [test -d "$as_dir" || continue
909 case $as_dir in
910   [[\\/]]* | ?:[[\\/]]* ) ;;
911   * ) as_dir=`(cd "$as_dir" && pwd) 2>/dev/null` ;;
912 esac
913 case $PATH_SEPARATOR$at_new_path$PATH_SEPARATOR in
914   *$PATH_SEPARATOR$as_dir$PATH_SEPARATOR*) ;;
915   $PATH_SEPARATOR$PATH_SEPARATOR) at_new_path=$as_dir ;;
916   *) AS_VAR_APPEND([at_new_path], ["$PATH_SEPARATOR$as_dir"]) ;;
917 esac])
918 PATH=$at_new_path
919 export PATH
921 # Setting up the FDs.
922 m4_define([AS_MESSAGE_LOG_FD], [5])
923 m4_define([AT_JOB_FIFO_FD], [6])
924 [#] AS_MESSAGE_LOG_FD is the log file.  Not to be overwritten if `-d'.
925 if $at_debug_p; then
926   at_suite_log=/dev/null
927 else
928   : >"$at_suite_log"
930 exec AS_MESSAGE_LOG_FD>>"$at_suite_log"
932 # Banners and logs.
933 AS_BOX(m4_defn([AT_TESTSUITE_NAME])[.])
935   AS_BOX(m4_defn([AT_TESTSUITE_NAME])[.])
936   echo
938   AS_ECHO(["$as_me: command line was:"])
939   AS_ECHO(["  \$ $[0] $at_cli_args"])
940   echo
942   # Try to find a few ChangeLogs in case it might help determining the
943   # exact version.  Use the relative dir: if the top dir is a symlink,
944   # find will not follow it (and options to follow the links are not
945   # portable), which would result in no output here.  Prune directories
946   # matching the package tarname, since they tend to be leftovers from
947   # `make dist' or `make distcheck' and contain redundant or stale logs.
948   if test -n "$at_top_srcdir"; then
949     AS_BOX([ChangeLogs.])
950     echo
951     for at_file in `find "$at_top_srcdir" m4_ifdef([AT_PACKAGE_TARNAME],
952 [-name "AT_PACKAGE_TARNAME-*" -prune -o ])-name ChangeLog -print`
953     do
954       AS_ECHO(["$as_me: $at_file:"])
955       sed 's/^/| /;10q' $at_file
956       echo
957     done
959   fi
961   AS_UNAME
962   echo
964   # Contents of the config files.
965   for at_file in atconfig atlocal
966   do
967     test -r $at_file || continue
968     AS_ECHO(["$as_me: $at_file:"])
969     sed 's/^/| /' $at_file
970     echo
971   done
972 } >&AS_MESSAGE_LOG_FD
974 m4_divert_pop([TESTS_BEGIN])dnl
975 m4_divert_push([PREPARE_TESTS])dnl
977   AS_BOX([Tested programs.])
978   echo
979 } >&AS_MESSAGE_LOG_FD
981 # Report what programs are being tested.
982 for at_program in : $at_tested
984   test "$at_program" = : && continue
985   _AS_PATH_WALK([$PATH], [test -f "$as_dir/$at_program" && break])
986   if test -f "$as_dir/$at_program"; then
987     {
988       AS_ECHO(["$at_srcdir/AT_LINE: $as_dir/$at_program --version"])
989       "$as_dir/$at_program" --version </dev/null
990       echo
991     } >&AS_MESSAGE_LOG_FD 2>&1
992   else
993     AS_ERROR([cannot find $at_program])
994   fi
995 done
998   AS_BOX([Running the tests.])
999 } >&AS_MESSAGE_LOG_FD
1001 at_start_date=`date`
1002 at_start_time=`date +%s 2>/dev/null`
1003 AS_ECHO(["$as_me: starting at: $at_start_date"]) >&AS_MESSAGE_LOG_FD
1004 m4_divert_pop([PREPARE_TESTS])dnl
1005 m4_divert_push([TESTS])dnl
1007 # Create the master directory if it doesn't already exist.
1008 AS_MKDIR_P(["$at_suite_dir"]) ||
1009   AS_ERROR([cannot create `$at_suite_dir'])
1011 # Can we diff with `/dev/null'?  DU 5.0 refuses.
1012 if diff /dev/null /dev/null >/dev/null 2>&1; then
1013   at_devnull=/dev/null
1014 else
1015   at_devnull=$at_suite_dir/devnull
1016   >"$at_devnull"
1019 # Use `diff -u' when possible.
1020 if at_diff=`diff -u "$at_devnull" "$at_devnull" 2>&1` && test -z "$at_diff"
1021 then
1022   at_diff='diff -u'
1023 else
1024   at_diff=diff
1027 # Get the last needed group.
1028 for at_group in : $at_groups; do :; done
1030 # Extract the start and end lines of each test group at the tail
1031 # of this file
1032 awk '
1033 BEGIN { FS="\a" }
1034 /^@%:@AT_START_/ {
1035   start = NR
1037 /^@%:@AT_STOP_/ {
1038   test = substr ($ 0, 10)
1039   print "at_sed" test "=\"1," start "d;" (NR-1) "q\""
1040   if (test == "'"$at_group"'") exit
1041 }' "$at_myself" > "$at_suite_dir/at-source-lines" &&
1042 . "$at_suite_dir/at-source-lines" ||
1043   AS_ERROR([cannot create test line number cache])
1044 rm -f "$at_suite_dir/at-source-lines"
1046 # Set number of jobs for `-j'; avoid more jobs than test groups.
1047 set X $at_groups; shift; at_max_jobs=$[@%:@]
1048 if test $at_max_jobs -eq 0; then
1049   at_jobs=1
1051 if test $at_jobs -ne 1 &&
1052    { test $at_jobs -eq 0 || test $at_jobs -gt $at_max_jobs; }; then
1053   at_jobs=$at_max_jobs
1056 # If parallel mode, don't output banners, don't split summary lines.
1057 if test $at_jobs -ne 1; then
1058   at_print_banners=false
1059   at_quiet=:
1062 # Set up helper dirs.
1063 rm -rf "$at_helper_dir" &&
1064 mkdir "$at_helper_dir" &&
1065 cd "$at_helper_dir" &&
1066 { test -z "$at_groups" || mkdir $at_groups; } ||
1067 AS_ERROR([testsuite directory setup failed])
1069 # Functions for running a test group.  We leave the actual
1070 # test group execution outside of a shell function in order
1071 # to avoid hitting zsh 4.x exit status bugs.
1073 AS_FUNCTION_DESCRIBE([at_fn_group_prepare], [],
1074 [Prepare running a test group.])
1075 at_fn_group_prepare ()
1077   # The directory for additional per-group helper files.
1078   at_job_dir=$at_helper_dir/$at_group
1079   # The file containing the location of the last AT_CHECK.
1080   at_check_line_file=$at_job_dir/check-line
1081   # The file containing the exit status of the last command.
1082   at_status_file=$at_job_dir/status
1083   # The files containing the output of the tested commands.
1084   at_stdout=$at_job_dir/stdout
1085   at_stder1=$at_job_dir/stder1
1086   at_stderr=$at_job_dir/stderr
1087   # The file containing the code for a test group.
1088   at_test_source=$at_job_dir/test-source
1089   # The file containing dates.
1090   at_times_file=$at_job_dir/times
1092   # Be sure to come back to the top test directory.
1093   cd "$at_suite_dir"
1095   # Clearly separate the test groups when verbose.
1096   $at_first || $at_verbose echo
1098   at_group_normalized=$at_group
1099   _AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
1101   # Create a fresh directory for the next test group, and enter.
1102   # If one already exists, the user may have invoked ./run from
1103   # within that directory; we remove the contents, but not the
1104   # directory itself, so that we aren't pulling the rug out from
1105   # under the shell's notion of the current directory.
1106   at_group_dir=$at_suite_dir/$at_group_normalized
1107   at_group_log=$at_group_dir/$as_me.log
1108   _AS_CLEAN_DIR("$at_group_dir") ||
1109     AS_WARN([test directory for $at_group_normalized could not be cleaned.])
1110   # Be tolerant if the above `rm' was not able to remove the directory.
1111   AS_MKDIR_P(["$at_group_dir"])
1113   echo 0 > "$at_status_file"
1115   # In verbose mode, append to the log file *and* show on
1116   # the standard output; in quiet mode only write to the log.
1117   if test -z "$at_verbose"; then
1118     at_tee_pipe='tee -a "$at_group_log"'
1119   else
1120     at_tee_pipe='cat >> "$at_group_log"'
1121   fi
1124 AS_FUNCTION_DESCRIBE([at_fn_group_postprocess], [],
1125 [Perform cleanup after running a test group.])
1126 at_fn_group_postprocess ()
1128   # Be sure to come back to the suite directory, in particular
1129   # since below we might `rm' the group directory we are in currently.
1130   cd "$at_suite_dir"
1132   if test ! -f "$at_check_line_file"; then
1133     sed "s/^ */$as_me: WARNING: /" <<_ATEOF
1134       A failure happened in a test group before any test could be
1135       run. This means that test suite is improperly designed.  Please
1136       report this failure to <AT_PACKAGE_BUGREPORT>.
1137 _ATEOF
1138     AS_ECHO(["$at_setup_line"]) >"$at_check_line_file"
1139     at_status=99
1140   fi
1141   $at_verbose AS_ECHO_N(["$at_group. $at_setup_line: "])
1142   AS_ECHO_N(["$at_group. $at_setup_line: "]) >> "$at_group_log"
1143   case $at_xfail:$at_status in
1144     *:99)
1145         at_msg='FAILED ('`cat "$at_check_line_file"`')'
1146         at_res=fail
1147         at_errexit=$at_errexit_p
1148         ;;
1149     yes:0)
1150         at_msg="UNEXPECTED PASS"
1151         at_res=xpass
1152         at_errexit=$at_errexit_p
1153         ;;
1154     no:0)
1155         at_msg="ok"
1156         at_res=pass
1157         at_errexit=false
1158         ;;
1159     *:77)
1160         at_msg='skipped ('`cat "$at_check_line_file"`')'
1161         at_res=skip
1162         at_errexit=false
1163         ;;
1164     yes:*)
1165         at_msg='expected failure ('`cat "$at_check_line_file"`')'
1166         at_res=xfail
1167         at_errexit=false
1168         ;;
1169     no:*)
1170         at_msg='FAILED ('`cat "$at_check_line_file"`')'
1171         at_res=fail
1172         at_errexit=$at_errexit_p
1173         ;;
1174   esac
1175   echo "$at_res" > "$at_job_dir/$at_res"
1176   # In parallel mode, output the summary line only afterwards.
1177   if test $at_jobs -ne 1 && test -n "$at_verbose"; then
1178     AS_ECHO(["$at_desc_line $at_msg"])
1179   else
1180     # Make sure there is a separator even with long titles.
1181     AS_ECHO([" $at_msg"])
1182   fi
1183   at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg"
1184   case $at_status in
1185     0|77)
1186       # $at_times_file is only available if the group succeeded.
1187       # We're not including the group log, so the success message
1188       # is written in the global log separately.  But we also
1189       # write to the group log in case they're using -d.
1190       if test -f "$at_times_file"; then
1191         at_log_msg="$at_log_msg     ("`sed 1d "$at_times_file"`')'
1192         rm -f "$at_times_file"
1193       fi
1194       AS_ECHO(["$at_log_msg"]) >> "$at_group_log"
1195       AS_ECHO(["$at_log_msg"]) >&AS_MESSAGE_LOG_FD
1197       # Cleanup the group directory, unless the user wants the files.
1198       if $at_debug_p; then
1199         at_fn_create_debugging_script
1200       else
1201         if test -d "$at_group_dir"; then
1202           find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
1203           rm -fr "$at_group_dir"
1204         fi
1205         rm -f "$at_test_source"
1206       fi
1207       ;;
1208     *)
1209       # Upon failure, include the log into the testsuite's global
1210       # log.  The failure message is written in the group log.  It
1211       # is later included in the global log.
1212       AS_ECHO(["$at_log_msg"]) >> "$at_group_log"
1214       # Upon failure, keep the group directory for autopsy, and create
1215       # the debugging script.  With -e, do not start any further tests.
1216       at_fn_create_debugging_script
1217       if $at_errexit; then
1218         echo stop > "$at_stop_file"
1219       fi
1220       ;;
1221   esac
1225 m4_text_box([Driver loop.])
1227 dnl Catching signals correctly:
1229 dnl The first idea was: trap the signal, send it to all spawned jobs,
1230 dnl then reset the handler and reraise the signal for ourselves.
1231 dnl However, before exiting, ksh will then send the signal to all
1232 dnl process group members, potentially killing the outer testsuite
1233 dnl and/or the 'make' process driving us.
1234 dnl So now the strategy is: trap the signal, send it to all spawned jobs,
1235 dnl then exit the script with the right status.
1237 dnl In order to let the jobs know about the signal, we cannot just send it
1238 dnl to the current process group (kill $SIG 0), for the same reason as above.
1239 dnl Also, it does not reliably stop the suite to send the signal to the
1240 dnl spawned processes, because they might not transport it further
1241 dnl (maybe this can be fixed?).
1243 dnl So what we do is enable shell job control if available, which causes the
1244 dnl shell to start each parallel task as its own shell job, thus as a new
1245 dnl process group leader.  We then send the signal to all new process groups.
1247 dnl Do we have job control?
1248 if (set -m && set +m) >/dev/null 2>&1; then
1249   at_job_control_on='set -m' at_job_control_off='set +m' at_job_group=-
1250 else
1251   at_job_control_on=: at_job_control_off=: at_job_group=
1254 for at_signal in 1 2 15; do
1255 dnl This signal handler is not suitable for PIPE: it causes writes.
1256 dnl The code that was interrupted may have the errexit, monitor, or xtrace
1257 dnl flags enabled, so sanitize.
1258   trap 'set +x; set +e
1259         $at_job_control_off
1260         at_signal='"$at_signal"'
1261 dnl Safety belt: even with runaway processes, prevent starting new jobs.
1262         echo stop > "$at_stop_file"
1263 dnl Do not enter this area multiple times, do not kill self prematurely.
1264         trap "" $at_signal
1265 dnl Gather process group IDs of currently running jobs.
1266         at_pgids=
1267         for at_pgid in `jobs -p 2>/dev/null`; do
1268           at_pgids="$at_pgids $at_job_group$at_pgid"
1269         done
1270 dnl Ignore `kill' errors, as some jobs may have finished in the meantime.
1271         test -z "$at_pgids" || kill -$at_signal $at_pgids 2>/dev/null
1272 dnl wait until all jobs have exited.
1273         wait
1274 dnl Status output.  Do this after waiting for the jobs, for ordered output.
1275 dnl Avoid scribbling onto the end of a possibly incomplete line.
1276         if test "$at_jobs" -eq 1 || test -z "$at_verbose"; then
1277           echo >&2
1278         fi
1279         at_signame=`kill -l $at_signal 2>&1 || echo $at_signal`
1280         set x $at_signame
1281         test $# -gt 2 && at_signame=$at_signal
1282         AS_WARN([caught signal $at_signame, bailing out])
1283 dnl Do not reinstall the default handler here and reraise the signal to
1284 dnl let the default handler do its job, see the note about ksh above.
1285 dnl     trap - $at_signal
1286 dnl     kill -$at_signal $$
1287 dnl Instead, exit with appropriate status.
1288         AS_VAR_ARITH([exit_status], [128 + $at_signal])
1289         AS_EXIT([$exit_status])' $at_signal
1290 done
1292 rm -f "$at_stop_file"
1293 at_first=:
1295 if test $at_jobs -ne 1 &&
1296      rm -f "$at_job_fifo" &&
1297      test -n "$at_job_group" &&
1298      ( mkfifo "$at_job_fifo" && trap 'exit 1' PIPE STOP TSTP ) 2>/dev/null
1299 then
1300   # FIFO job dispatcher.
1302 dnl Since we use job control, we need to propagate TSTP.
1303 dnl This handler need not be used for serial execution.
1304 dnl Again, we should stop all processes in the job groups, otherwise
1305 dnl the stopping will not be effective while one test group is running.
1306 dnl Apparently ksh does not honor the TSTP trap.
1307 dnl As a safety measure, not use the same variable names as in the
1308 dnl termination handlers above, one might get called during execution
1309 dnl of the other.
1310   trap 'at_pids=
1311         for at_pid in `jobs -p`; do
1312           at_pids="$at_pids $at_job_group$at_pid"
1313         done
1314 dnl Send it to all spawned jobs, ignoring those finished meanwhile.
1315         if test -n "$at_pids"; then
1316 dnl Unfortunately, ksh93 fork-bombs when we send TSTP, so send STOP
1317 dnl if this might be ksh (STOP prevents possible TSTP handlers inside
1318 dnl AT_CHECKs from running).  Then stop ourselves.
1319           at_sig=TSTP
1320           test "${TMOUT+set}" = set && at_sig=STOP
1321           kill -$at_sig $at_pids 2>/dev/null
1322         fi
1323         kill -STOP $$
1324 dnl We got a CONT, so let's go again.  Passing this to all processes
1325 dnl in the groups is necessary (because we stopped them), but it may
1326 dnl cause changed test semantics; e.g., a sleep will be interrupted.
1327         test -z "$at_pids" || kill -CONT $at_pids 2>/dev/null' TSTP
1329   echo
1330   # Turn jobs into a list of numbers, starting from 1.
1331   at_joblist=`AS_ECHO([" $at_groups_all "]) | \
1332     sed 's/\( '$at_jobs'\) .*/\1/'`
1334   set X $at_joblist
1335   shift
1336   for at_group in $at_groups; do
1337 dnl Enable job control only for spawning the test group:
1338 dnl Let the jobs to run in separate process groups, but
1339 dnl avoid all the status output by the shell.
1340     $at_job_control_on 2>/dev/null
1341     (
1342       # Start one test group.
1343       $at_job_control_off
1344       exec AT_JOB_FIFO_FD>"$at_job_fifo"
1345 dnl When a child receives PIPE, be sure to write back the token,
1346 dnl so the master does not hang waiting for it.
1347 dnl errexit and xtrace should not be set in this shell instance,
1348 dnl except as debug measures.  However, shells such as dash may
1349 dnl optimize away the _AT_CHECK subshell, so normalize here.
1350       trap 'set +x; set +e
1351 dnl Ignore PIPE signals that stem from writing back the token.
1352             trap "" PIPE
1353             echo stop > "$at_stop_file"
1354             echo token >&AT_JOB_FIFO_FD
1355 dnl Do not reraise the default PIPE handler.
1356 dnl It wreaks havoc with ksh, see above.
1357 dnl         trap - 13
1358 dnl         kill -13 $$
1359             AS_EXIT([141])' PIPE
1360       at_fn_group_prepare
1361       if cd "$at_group_dir" &&
1362          at_fn_test $at_group &&
1363          . "$at_test_source" # AT_JOB_FIFO_FD>&-
1364       then :; else
1365         AS_WARN([unable to parse test group: $at_group])
1366         at_failed=:
1367       fi
1368       at_fn_group_postprocess
1369       echo token >&AT_JOB_FIFO_FD
1370     ) &
1371     $at_job_control_off
1372     if $at_first; then
1373       at_first=false
1374       exec AT_JOB_FIFO_FD<"$at_job_fifo"
1375     fi
1376     shift # Consume one token.
1377     if test $[@%:@] -gt 0; then :; else
1378       read at_token <&AT_JOB_FIFO_FD || break
1379       set x $[*]
1380     fi
1381     test -f "$at_stop_file" && break
1382   done
1383   # Read back the remaining ($at_jobs - 1) tokens.
1384   set X $at_joblist
1385   shift
1386   if test $[@%:@] -gt 0; then
1387     shift
1388     for at_job
1389     do
1390       read at_token
1391     done <&AT_JOB_FIFO_FD
1392   fi
1393   exec AT_JOB_FIFO_FD<&-
1394   wait
1395 else
1396   # Run serially, avoid forks and other potential surprises.
1397   for at_group in $at_groups; do
1398     at_fn_group_prepare
1399     if cd "$at_group_dir" &&
1400        at_fn_test $at_group &&
1401        . "$at_test_source"; then :; else
1402       AS_WARN([unable to parse test group: $at_group])
1403       at_failed=:
1404     fi
1405     at_fn_group_postprocess
1406     test -f "$at_stop_file" && break
1407     at_first=false
1408   done
1411 # Wrap up the test suite with summary statistics.
1412 cd "$at_helper_dir"
1414 # Use ?..???? when the list must remain sorted, the faster * otherwise.
1415 at_pass_list=`for f in */pass; do echo $f; done | sed '/\*/d; s,/pass,,'`
1416 at_skip_list=`for f in */skip; do echo $f; done | sed '/\*/d; s,/skip,,'`
1417 at_xfail_list=`for f in */xfail; do echo $f; done | sed '/\*/d; s,/xfail,,'`
1418 at_xpass_list=`for f in ?/xpass ??/xpass ???/xpass ????/xpass; do
1419                  echo $f; done | sed '/?/d; s,/xpass,,'`
1420 at_fail_list=`for f in ?/fail ??/fail ???/fail ????/fail; do
1421                 echo $f; done | sed '/?/d; s,/fail,,'`
1423 set X $at_pass_list $at_xpass_list $at_xfail_list $at_fail_list $at_skip_list
1424 shift; at_group_count=$[@%:@]
1425 set X $at_xpass_list; shift; at_xpass_count=$[@%:@]; at_xpass_list=$[*]
1426 set X $at_xfail_list; shift; at_xfail_count=$[@%:@]
1427 set X $at_fail_list; shift; at_fail_count=$[@%:@]; at_fail_list=$[*]
1428 set X $at_skip_list; shift; at_skip_count=$[@%:@]
1430 AS_VAR_ARITH([at_run_count], [$at_group_count - $at_skip_count])
1431 AS_VAR_ARITH([at_unexpected_count], [$at_xpass_count + $at_fail_count])
1432 AS_VAR_ARITH([at_total_fail_count], [$at_xfail_count + $at_fail_count])
1434 # Back to the top directory.
1435 cd "$at_dir"
1436 rm -rf "$at_helper_dir"
1438 # Compute the duration of the suite.
1439 at_stop_date=`date`
1440 at_stop_time=`date +%s 2>/dev/null`
1441 AS_ECHO(["$as_me: ending at: $at_stop_date"]) >&AS_MESSAGE_LOG_FD
1442 case $at_start_time,$at_stop_time in
1443   [[0-9]*,[0-9]*])
1444     AS_VAR_ARITH([at_duration_s], [$at_stop_time - $at_start_time])
1445     AS_VAR_ARITH([at_duration_m], [$at_duration_s / 60])
1446     AS_VAR_ARITH([at_duration_h], [$at_duration_m / 60])
1447     AS_VAR_ARITH([at_duration_s], [$at_duration_s % 60])
1448     AS_VAR_ARITH([at_duration_m], [$at_duration_m % 60])
1449     at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s"
1450     AS_ECHO(["$as_me: test suite duration: $at_duration"]) >&AS_MESSAGE_LOG_FD
1451     ;;
1452 esac
1454 echo
1455 AS_BOX([Test results.])
1456 echo
1458   echo
1459   AS_BOX([Test results.])
1460   echo
1461 } >&AS_MESSAGE_LOG_FD
1464 dnl FIXME: this code is as far from i18n-cleanness as man
1465 dnl could imagine...
1467 if test $at_run_count = 1; then
1468   at_result="1 test"
1469   at_were=was
1470 else
1471   at_result="$at_run_count tests"
1472   at_were=were
1474 if $at_errexit_p && test $at_unexpected_count != 0; then
1475   if test $at_xpass_count = 1; then
1476     at_result="$at_result $at_were run, one passed"
1477   else
1478     at_result="$at_result $at_were run, one failed"
1479   fi
1480   at_result="$at_result unexpectedly and inhibited subsequent tests."
1481 else
1482   # Don't you just love exponential explosion of the number of cases?
1483   case $at_xpass_count:$at_fail_count:$at_xfail_count in
1484     # So far, so good.
1485     0:0:0) at_result="$at_result $at_were successful." ;;
1486     0:0:*) at_result="$at_result behaved as expected." ;;
1488     # Some unexpected failures
1489     0:*:0) at_result="$at_result $at_were run,
1490 $at_fail_count failed unexpectedly." ;;
1492     # Some failures, both expected and unexpected
1493     0:*:1) at_result="$at_result $at_were run,
1494 $at_total_fail_count failed ($at_xfail_count expected failure)." ;;
1495     0:*:*) at_result="$at_result $at_were run,
1496 $at_total_fail_count failed ($at_xfail_count expected failures)." ;;
1498     # No unexpected failures, but some xpasses
1499     *:0:*) at_result="$at_result $at_were run,
1500 $at_xpass_count passed unexpectedly." ;;
1502     # No expected failures, but failures and xpasses
1503     *:1:0) at_result="$at_result $at_were run,
1504 $at_unexpected_count did not behave as expected dnl
1505 ($at_fail_count unexpected failure)." ;;
1506     *:*:0) at_result="$at_result $at_were run,
1507 $at_unexpected_count did not behave as expected dnl
1508 ($at_fail_count unexpected failures)." ;;
1510     # All of them.
1511     *:*:1) at_result="$at_result $at_were run,
1512 $at_xpass_count passed unexpectedly,
1513 $at_total_fail_count failed ($at_xfail_count expected failure)." ;;
1514     *:*:*) at_result="$at_result $at_were run,
1515 $at_xpass_count passed unexpectedly,
1516 $at_total_fail_count failed ($at_xfail_count expected failures)." ;;
1517   esac
1519   if test $at_skip_count = 0 && test $at_run_count -gt 1; then
1520     at_result="All $at_result"
1521   fi
1524 # Now put skips in the mix.
1525 case $at_skip_count in
1526   0) ;;
1527   1) at_result="$at_result
1528 1 test was skipped." ;;
1529   *) at_result="$at_result
1530 $at_skip_count tests were skipped." ;;
1531 esac
1533 if test $at_unexpected_count = 0; then
1534   echo "$at_result"
1535   echo "$at_result" >&AS_MESSAGE_LOG_FD
1536 else
1537   echo "ERROR: $at_result" >&2
1538   echo "ERROR: $at_result" >&AS_MESSAGE_LOG_FD
1539   {
1540     echo
1541     AS_BOX([Summary of the failures.])
1543     # Summary of failed and skipped tests.
1544     if test $at_fail_count != 0; then
1545       echo "Failed tests:"
1546       $SHELL "$at_myself" $at_fail_list --list
1547       echo
1548     fi
1549     if test $at_skip_count != 0; then
1550       echo "Skipped tests:"
1551       $SHELL "$at_myself" $at_skip_list --list
1552       echo
1553     fi
1554     if test $at_xpass_count != 0; then
1555       echo "Unexpected passes:"
1556       $SHELL "$at_myself" $at_xpass_list --list
1557       echo
1558     fi
1559     if test $at_fail_count != 0; then
1560       AS_BOX([Detailed failed tests.])
1561       echo
1562       for at_group in $at_fail_list
1563       do
1564         at_group_normalized=$at_group
1565         _AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
1566         cat "$at_suite_dir/$at_group_normalized/$as_me.log"
1567         echo
1568       done
1569       echo
1570     fi
1571     if test -n "$at_top_srcdir"; then
1572       AS_BOX([${at_top_build_prefix}config.log])
1573       sed 's/^/| /' ${at_top_build_prefix}config.log
1574       echo
1575     fi
1576   } >&AS_MESSAGE_LOG_FD
1578   AS_BOX([$as_me.log was created.])
1580   echo
1581   AS_ECHO(["Please send \`${at_testdir+${at_testdir}/}$as_me.log' ]dnl
1582 [and all information you think might help:
1584    To: <AT_PACKAGE_BUGREPORT>
1585    Subject: @<:@AT_PACKAGE_STRING@:>@ $as_me: dnl
1586 $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}dnl
1587 $at_xpass_list${at_xpass_list:+ passed unexpectedly}
1589   if test $at_debug_p = false; then
1590     echo
1591     echo 'You may investigate any problem if you feel able to do so, in which'
1592     echo 'case the test suite provides a good starting point.  Its output may'
1593     AS_ECHO(["be found below \`${at_testdir+${at_testdir}/}$as_me.dir'."])
1594     echo
1595   fi
1596     exit 1
1599 exit 0
1601 m4_text_box([Actual tests.])
1602 m4_divert_pop([TESTS])dnl
1603 dnl End of AT_INIT: divert to KILL, only test groups are to be
1604 dnl output, the rest is ignored.  Current diversion is BODY, inherited
1605 dnl from M4sh.
1606 m4_divert([KILL])
1607 ])# AT_INIT
1610 # _AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ARGS],[ACTION-IF-GIVEN],
1611 #                [ACTION-IF-NOT-GIVEN])
1612 # ---------------------------------------------------------------------------
1613 # Internal implementation of AT_ARG_OPTION & AT_ARG_OPTION_ARG
1614 m4_defun([_AT_ARG_OPTION],
1615 [m4_divert_once([HELP_OTHER],
1616 [cat <<_ATEOF || at_write_fail=1
1618 Other options:
1619 _ATEOF
1620 ])dnl m4_divert_once HELP_OTHER
1621 m4_divert_text([HELP_OTHER],
1622 [cat <<_ATEOF || at_write_fail=1
1624 _ATEOF])dnl
1625 dnl Turn our options into our desired strings
1626 m4_ifdef([AT_first_option],[m4_undefine([AT_first_option])])dnl
1627 m4_ifdef([AT_case],[m4_undefine([AT_case])])dnl
1628 m4_ifdef([AT_case_no],[m4_undefine([AT_case_no])])dnl
1629 m4_ifdef([AT_case_arg],[m4_undefine([AT_case_arg])])dnl
1630 m4_foreach([AT_option], m4_split(m4_normalize([$1]),[[ \|]+]),
1631 [m4_define_default([AT_first_option],AT_option)dnl
1632 m4_append([AT_case],m4_if(m4_len(AT_option),1,[],[-])[-]AT_option, [ | ])dnl
1633 m4_append([AT_case_no],[--no]AT_option, [ | ])dnl
1634 m4_append([AT_case_arg],
1635           m4_if(m4_len(AT_option),1,[],[-])[-]AT_option[=*], [ | ])dnl
1636 ])dnl m4_foreach AT_option
1637 dnl keep track so we or the user may process ACTION-IF-NOT-GIVEN
1638 m4_divert_once([PARSE_ARGS_BEGIN],
1641 ## Set up package specific options.
1643 ])dnl
1644 m4_divert_text([PARSE_ARGS_BEGIN],
1645 [dnl Provide a default value for options without arguments.
1646 m4_ifvaln([$3],,[at_arg_[]m4_bpatsubst([AT_first_option], -, _)=false])dnl
1647 at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=false
1648 ])dnl m4_divert_text DEFAULTS
1649 m4_divert_text([PARSE_ARGS],
1650 [dnl Parse the options and args when necessary.
1651 m4_ifvaln([$3],
1652 [    AT_case )
1653         at_prev=--m4_bpatsubst([AT_first_option], -, _)
1654         ;;
1655     AT_case_arg )
1656         at_arg_[]m4_bpatsubst([AT_first_option], -, _)=$at_optarg
1657         at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
1658         $4
1659         ;;],
1660 [    AT_case )
1661         at_optarg=:
1662         at_arg_[]m4_bpatsubst([AT_first_option], -, _)=:
1663         at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
1664         m4_ifval([$4],[$4])dnl
1665         ;;
1666     AT_case_no )
1667         at_optarg=false
1668         at_arg_[]m4_bpatsubst([AT_first_option], -, _)=false
1669         at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
1670         m4_ifval([$4],[$4])dnl
1671         ;;])dnl m4_ifvaln $3
1672 ])dnl m4_divert_text PARSE_ARGS
1673 m4_ifvaln([$5],
1674 [m4_divert_once([PARSE_ARGS_END],
1677 ## Process package specific options when _not_ supplied.
1678 ##])dnl m4_divert_once PARSE_ARGS_END
1679 m4_divert_text([PARSE_ARGS_END],
1681 AS_IF([$at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)],,[$5])dnl
1682 ])dnl m4_divert_text PARSE_ARGS_END
1683 ])dnl m4_ifvaln $5
1684 ])dnl _AT_ARG_OPTION
1687 # AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
1688 # ------------------------------------------------------------------------
1689 # Accept a set of OPTIONS with arguments.  Add HELP-TEXT to the HELP_OTHER
1690 # diversion.
1692 # Preceding dashes should not be passed into OPTIONS.  Users will be required
1693 # to pass `--' before long options and `-' before single character options.
1695 # $at_arg_OPTION will be set to `:' if this option is received, `false' if
1696 # if --noOPTION is received, and `false' by default.
1698 # Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered with
1699 # $at_optarg set to `:' or `false' as appropriate.  $at_optarg is actually
1700 # just a copy of $at_arg_OPTION.
1702 # ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
1703 # if no option from OPTIONS was found.
1704 m4_defun([AT_ARG_OPTION],[_AT_ARG_OPTION([$1],[$2],,[$3],[$4])])
1707 # AT_ARG_OPTION_ARG(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
1708 # ---------------------------------------------------------------------------
1709 # Accept a set of OPTIONS with arguments, seperated by commas.  Add HELP-TEXT
1710 # to the HELP_OTHER diversion.
1712 # Preceding dashes should not be passed into OPTIONS.  Users will be required
1713 # to pass `--' before long options and `-' before single character options.
1715 # By default, any argument to these options will be assigned to the shell
1716 # variable $at_arg_OPTION, where OPTION is the first option in OPTIONS with
1717 # any `-' characters replaced with `_'.
1719 # Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered with
1720 # $at_optarg set.  $at_optarg is actually just a copy of $at_arg_OPTION.
1722 # ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
1723 # if no option from OPTIONS was found.
1724 m4_defun([AT_ARG_OPTION_ARG],[_AT_ARG_OPTION([$1],[$2],1,[$3],[$4])])
1727 # AT_TESTED(PROGRAMS)
1728 # -------------------
1729 # Specify the list of programs exercised by the test suite.  Their
1730 # versions are logged, and in the case of embedded test suite, they
1731 # must correspond to the version of the package.  PATH should be
1732 # already preset so the proper executable will be selected.
1733 m4_define([AT_TESTED],
1734 [m4_append_uniq_w([AT_tested], [$1])])
1737 # AT_COPYRIGHT(TEXT, [FILTER = m4_newline])
1738 # -----------------------------------------
1739 # Emit TEXT, a copyright notice, in the top of the test suite and in
1740 # --version output.  Macros in TEXT are evaluated once.  Process
1741 # the --version output through FILTER (m4_newline, m4_do, and
1742 # m4_copyright_condense are common filters).
1743 m4_define([AT_COPYRIGHT],
1744 [AS_COPYRIGHT([$1])[]]dnl
1745 [m4_divert_text([VERSION_NOTICES],
1746 [m4_default([$2], [m4_newline])([$1])])])# AT_COPYRIGHT
1749 # AT_SETUP(DESCRIPTION)
1750 # ---------------------
1751 # Start a group of related tests, all to be executed in the same subshell.
1752 # The group is testing what DESCRIPTION says.
1753 _AT_DEFINE_INIT([AT_SETUP],
1754 [m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])],
1755   [m4_define([AT_ingroup], [AS_ECHO(["$at_setup_line"]) >"$at_check_line_file"
1756 ])])
1757 m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])])
1758 m4_define([AT_capture_files], [])
1759 m4_define([AT_line], AT_LINE)
1760 m4_define([AT_xfail], [at_xfail=no])
1761 m4_define([AT_description], m4_expand([$1]))
1762 m4_define([AT_ordinal], m4_incr(AT_ordinal))
1763 m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal]))
1764 m4_divert_push([TEST_GROUPS])dnl
1765 [#AT_START_]AT_ordinal
1766 @%:@ AT_ordinal. m4_defn([AT_line]): m4_defn([AT_description])
1767 at_setup_line='m4_defn([AT_line])'
1768 m4_if(AT_banner_ordinal, [0], [], [at_fn_banner AT_banner_ordinal
1769 ])dnl
1770 at_desc="AS_ESCAPE(m4_dquote(m4_defn([AT_description])))"
1771 at_desc_line=m4_format(["%3d: $at_desc%*s"], AT_ordinal,
1772   m4_max(0, m4_eval(47 - m4_qlen(m4_defn([AT_description])))), [])
1773 $at_quiet AS_ECHO_N(["$at_desc_line"])
1774 m4_divert_push([TEST_SCRIPT])dnl
1778 # AT_XFAIL_IF(SHELL-EXPRESSION)
1779 # -----------------------------
1780 # Set up the test to be expected to fail if SHELL-EXPRESSION evaluates to
1781 # true (exitcode = 0).
1782 _AT_DEFINE_SETUP([AT_XFAIL_IF],
1783 [dnl
1784 dnl Try to limit the amount of conditionals that we emit.
1785 m4_case([$1],
1786       [], [],
1787       [false], [],
1788       [:], [m4_define([AT_xfail], [at_xfail=yes])],
1789       [true], [m4_define([AT_xfail], [at_xfail=yes])],
1790       [m4_append([AT_xfail], [
1791       $1 && at_xfail=yes])])])
1794 # AT_KEYWORDS(KEYWORDS)
1795 # ---------------------
1796 # Declare a list of keywords associated to the current test group.
1797 # Since the -k option is case-insensitive, the list is stored in lower case
1798 # to avoid duplicates that differ only by case.
1799 _AT_DEFINE_SETUP([AT_KEYWORDS],
1800 [m4_append_uniq_w([AT_keywords], m4_tolower(m4_dquote(_m4_expand([$1
1801 ]))))])
1804 # AT_CAPTURE_FILE(FILE)
1805 # ---------------------
1806 # If the current test group does not behave as expected, save the contents of
1807 # FILE in the test suite log.
1808 _AT_DEFINE_SETUP([AT_CAPTURE_FILE],
1809 [m4_append_uniq([AT_capture_files], ["$1"], [ \
1810 ])])
1813 # AT_CLEANUP
1814 # ----------
1815 # Complete a group of related tests.
1816 _AT_DEFINE_INIT([AT_CLEANUP],
1817 [m4_ifdef([AT_ingroup], [AT_ingroup[]_m4_undefine([AT_ingroup])],
1818   [m4_fatal([$0: missing AT_SETUP detected])])dnl
1819 m4_append([AT_help_all],
1820 m4_defn([AT_ordinal]);m4_defn([AT_line]);m4_defn([AT_description]);dnl
1821 m4_ifdef([AT_keywords], [m4_defn([AT_keywords])]);
1822 )dnl
1823 m4_divert_pop([TEST_SCRIPT])dnl Back to TEST_GROUPS
1824 AT_xfail
1825 echo "#                             -*- compilation -*-" >> "$at_group_log"
1827   AS_ECHO(["AT_ordinal. m4_defn([AT_line]): testing $1..."])
1828   $at_traceon
1829 m4_undivert([TEST_SCRIPT])dnl Insert the code here
1830   set +x
1831   $at_times_p && times >"$at_times_file"
1832 ) AS_MESSAGE_LOG_FD>&1 2>&1 | eval $at_tee_pipe
1833 read at_status <"$at_status_file"
1834 [#AT_STOP_]AT_ordinal
1835 m4_divert_pop([TEST_GROUPS])dnl Back to KILL.
1836 ])# AT_CLEANUP
1839 # AT_BANNER([TEXT])
1840 # -----------------
1841 # Start a category of related test groups.  If multiple groups are executed,
1842 # output TEXT as a banner without any shell expansion, prior to any test
1843 # from the category.  If TEXT is empty, no banner is printed.
1844 _AT_DEFINE_INIT([AT_BANNER],
1845 [m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])])dnl
1846 m4_define([AT_banner_ordinal], m4_incr(AT_banner_ordinal))
1847 m4_divert_text([BANNERS],
1848 [@%:@ Banner AT_banner_ordinal. AT_LINE
1849 @%:@ Category starts at test group m4_incr(AT_ordinal).
1850 at_banner_text_[]AT_banner_ordinal="AS_ESCAPE([$1])"])dnl
1851 ])# AT_BANNER
1854 # AT_DATA(FILE, CONTENTS)
1855 # -----------------------
1856 # Initialize an input data FILE with given CONTENTS, which should end with
1857 # an end of line.
1858 # This macro is not robust to active symbols in CONTENTS *on purpose*.
1859 # If you don't want CONTENTS to be evaluated, quote it twice.
1860 _AT_DEFINE_SETUP([AT_DATA],
1861 [cat >$1 <<'_ATEOF'
1862 $2[]_ATEOF
1866 # AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,
1867 #          [RUN-IF-FAIL], [RUN-IF-PASS])
1868 # ------------------------------------------------
1869 # Execute a test by performing given shell COMMANDS.  These commands
1870 # should normally exit with STATUS, while producing expected STDOUT and
1871 # STDERR contents.  Shell metacharacters in STDOUT and STDERR are
1872 # _not_ processed by the shell, but are treated as string literals.
1874 # STATUS, STDOUT, and STDERR are not checked if equal to `ignore'.
1876 # If STDOUT is `expout', then stdout is compared to the content of the file
1877 # `expout'.  Likewise for STDERR and `experr'.
1879 # If STDOUT is `stdout', then the stdout is left in the file `stdout',
1880 # likewise for STDERR and `stderr'.  Don't do this:
1882 #    AT_CHECK([command >out])
1883 #    # Some checks on `out'
1885 # do this instead:
1887 #    AT_CHECK([command], [], [stdout])
1888 #    # Some checks on `stdout'
1890 # You might wonder why you can't just use `ignore', then directly use stdout
1891 # and stderr left by the test suite:
1893 #    AT_CHECK([command], [], [ignore])
1894 #    AT_CHECK([check stdout])
1896 # If the test suite always captured data in the file `stdout', then the
1897 # second command would be trying to read and write from the same file, with
1898 # undefined behavior.  Therefore, the test suite actually captures data in
1899 # an internal file of a different name, and only creates `stdout' when
1900 # explicitly requested.
1902 # Any line of stderr starting with leading blanks and a `+' are filtered
1903 # out, since most shells when tracing include subshell traces in stderr.
1904 # This may cause spurious failures when the test suite is run with `-x'.
1906 _AT_DEFINE_SETUP([AT_CHECK],
1907 [_AT_CHECK(m4_expand([$1]), [$2], AS_ESCAPE(m4_dquote(m4_expand([$3]))),
1908   AS_ESCAPE(m4_dquote(m4_expand([$4]))), [$5], [$6])])
1910 # AT_CHECK_UNQUOTED(COMMANDS, [STATUS = 0], STDOUT, STDERR,
1911 #                   [RUN-IF-FAIL], [RUN-IF-PASS])
1912 # ---------------------------------------------------------
1913 # Like AT_CHECK, but do not AS_ESCAPE shell metacharacters in the STDOUT
1914 # and STDERR arguments before running the comparison.
1915 _AT_DEFINE_SETUP([AT_CHECK_UNQUOTED],
1916 [_AT_CHECK(m4_expand([$1]), [$2], AS_ESCAPE(m4_dquote(m4_expand([$3])), [""]),
1917   AS_ESCAPE(m4_dquote(m4_expand([$4])), [""]), [$5], [$6])])
1919 # AT_CHECK_NOESCAPE(COMMANDS, [STATUS = 0], STDOUT, STDERR,
1920 #                   [RUN-IF-FAIL], [RUN-IF-PASS])
1921 # ---------------------------------------------------------
1922 # Obsolete spelling of AT_CHECK_UNQUOTED.
1923 m4_define([AT_CHECK_NOESCAPE],
1924 [m4_warn([obsolete], [consider using AT_CHECK_UNQUOTED instead of $0])]dnl
1925 [_AT_CHECK(m4_expand([$1]), [$2], m4_expand([$3]),
1926   m4_expand([$4]), [$5], [$6])])
1929 # _AT_DECIDE_TRACEABLE(COMMANDS)
1930 # ------------------------------
1931 # Worker for _AT_CHECK that expands to shell code.  If COMMANDS are safe to
1932 # trace with `set -x', the shell code will evaluate to true.  Otherwise,
1933 # the shell code will print a message stating an aspect of COMMANDS that makes
1934 # tracing them unsafe, and evaluate to false.
1936 # Tracing COMMANDS is not safe if they contain a command that spans multiple
1937 # lines.  When the test suite user passes `-x' or `--trace', the test suite
1938 # precedes every command with a `set -x'.  Since most tests expect a specific
1939 # stderr, if only to confirm that it is empty, the test suite filters ^+ from
1940 # the captured stderr before comparing with the expected stderr.  If a command
1941 # spans multiple lines, so will its trace, but a `+' only prefixes the first
1942 # line of that trace:
1944 # $ echo 'foo
1945 # bar'
1946 # => stdout
1947 # foo
1948 # bar
1949 # => stderr
1950 # + foo
1951 # bar
1953 # In a subset of cases, one could filter such extended shell traces from
1954 # stderr.  Since test commands spanning several lines are rare, I chose
1955 # instead to simply not trace COMMANDS that could yield multiple trace lines.
1956 # Distinguishing such COMMANDS became the task at hand.
1958 # These features may cause a shell command to span multiple lines:
1960 # (a) A quoted literal newline.
1961 # Example:
1962 #   echo foo'
1963 #   'bar
1964 # M4 is a hostile language for the job of parsing COMMANDS to determine whether
1965 # each literal newline is quoted, so we simply disable tracing for all COMMANDS
1966 # that bear literal newlines.
1968 # (b) A command substitution not subject to word splitting.
1969 # Example:
1970 #   var=$(printf 'foo\nbar')
1971 # Example:
1972 #   echo "`printf 'foo\\nbar`"
1973 # One cannot know in general the number of lines a command substitution will
1974 # yield without executing the substituted command.  As such, we disable tracing
1975 # for all COMMANDS containing these constructs.
1977 # (c) A parameter expansion not subject to word splitting.
1978 # Example:
1979 #   var=foo'
1980 #   'bar
1981 #   echo "$var"
1982 # Parameter expansions appear in COMMANDS with much greater frequency than do
1983 # newlines and command substitutions, so disabling tracing for all such
1984 # COMMANDS would much more substantially devalue `testsuite -x'.  To determine
1985 # which parameter expansions yield multiple lines, we escape all ``', `"',
1986 # and `\' in a copy of COMMANDS and expand that string within double quotes
1987 # at runtime.  If the result of that expansion contains multiple lines, the
1988 # test suite disables tracing for the command in question.
1990 # This method leads the test suite to expand some parameters that the shell
1991 # itself will never expand due to single-quotes or backslash escapes.  This is
1992 # not a problem for `$foo' expansions, which will simply yield the empty string
1993 # or some unrelated value.  A `${...}' expansion could actually form invalid
1994 # shell code, however; consider `${=foo}'.  Therefore, we disable tracing for
1995 # all COMMANDS containing `${...}'.  This affects few COMMANDS.
1997 # This macro falls in a very hot path; the Autoconf test suite expands it 1640
1998 # times as of this writing.  To give a sense of the impact of the heuristics I
1999 # just described, the test suite preemptively disables tracing for 31 of those,
2000 # and 268 contain parameter expansions that require runtime evaluation.  The
2001 # balance are always safe to trace.
2002 m4_define([_AT_DECIDE_TRACEABLE],
2003 dnl Utility macro.
2005 dnl Examine COMMANDS for a reason to never trace COMMANDS.
2006 [m4_pushdef([at_reason],
2007 m4_cond([m4_eval(m4_index([$1], [`]) >= 0)], [1],
2008                 [[a `...` command substitution]],
2009         [m4_eval(m4_index([$1], [$(]) >= 0)], [1],
2010                 [[a $(...) command substitution]],
2011         [m4_eval(m4_index([$1], [${]) >= 0)], [1],
2012                 [[a ${...} parameter expansion]],
2013         [m4_eval(m4_index([$1], m4_newline) >= 0)], [1],
2014                 [[an embedded newline]],
2015         []))]dnl No reason.
2016 [m4_if(m4_index(_m4_defn([at_reason]), [a]), [0],]dnl
2017 dnl We know at build time that tracing COMMANDS is never safe.
2018 [[at_fn_check_prepare_notrace 'm4_defn([at_reason])'],dnl
2019        m4_index([$1], [$]), [-1],]dnl
2020 dnl We know at build time that tracing COMMANDS is always safe.
2021 [[at_fn_check_prepare_trace],]dnl
2022 dnl COMMANDS may contain parameter expansions; expand them at runtime.
2023 [[at_fn_check_prepare_dynamic "AS_ESCAPE([[$1]], [`\"])"])[]]dnl
2024 [_m4_popdef([at_reason])])
2027 # AT_DIFF_STDERR/AT_DIFF_STDOUT
2028 # -----------------------------
2029 # These are subroutines of AT_CHECK.  Using indirect dispatch is a tad
2030 # faster than using m4_case, and these are called very frequently.
2031 m4_define([AT_DIFF_STDERR(stderr)],
2032           [echo stderr:; tee stderr <"$at_stderr"])
2033 m4_define([AT_DIFF_STDERR(stderr-nolog)],
2034           [echo stderr captured; cp "$at_stderr" stderr])
2035 m4_define([AT_DIFF_STDERR(ignore)],
2036           [echo stderr:; cat "$at_stderr"])
2037 m4_define([AT_DIFF_STDERR(ignore-nolog)])
2038 m4_define([AT_DIFF_STDERR(experr)],
2039           [$at_diff experr "$at_stderr" || at_failed=:])
2040 m4_define([AT_DIFF_STDERR()],
2041           [at_fn_diff_devnull "$at_stderr" || at_failed=:])
2043 m4_define([AT_DIFF_STDOUT(stdout)],
2044           [echo stdout:; tee stdout <"$at_stdout"])
2045 m4_define([AT_DIFF_STDOUT(stdout-nolog)],
2046           [echo stdout captured; cp "$at_stdout" stdout])
2047 m4_define([AT_DIFF_STDOUT(ignore)],
2048           [echo stdout:; cat "$at_stdout"])
2049 m4_define([AT_DIFF_STDOUT(ignore-nolog)])
2050 m4_define([AT_DIFF_STDOUT(expout)],
2051           [$at_diff expout "$at_stdout" || at_failed=:])
2052 m4_define([AT_DIFF_STDOUT()],
2053           [at_fn_diff_devnull "$at_stdout" || at_failed=:])
2055 # _AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,
2056 #           [RUN-IF-FAIL], [RUN-IF-PASS])
2057 # -------------------------------------------------
2058 # Worker for AT_CHECK and AT_CHECK_UNQUOTED, with COMMANDS, STDOUT, and
2059 # STDERR pre-expanded.
2061 # Implementation Details
2062 # ----------------------
2063 # Ideally, we would like to run
2065 #    ( $at_traceon; COMMANDS >at-stdout 2> at-stderr )
2067 # but we must group COMMANDS as it is not limited to a single command, and
2068 # then the shells will save the traces in at-stderr. So we have to filter
2069 # them out when checking stderr, and we must send them into the test suite's
2070 # stderr to honor -x properly. Since only the first line of the trace of a
2071 # multiline command starts with a `+', and I know of no straightforward way to
2072 # filter out the unadorned trace lines, we disable shell tracing entirely for
2073 # commands that could span multiple lines.
2075 # Limiting COMMANDS to a single command is not good either, since then
2076 # the user herself would use {} or (), and then we face the same problem.
2078 # But then, there is no point in running
2080 #   ( $at_traceon { $1 ; } >at-stdout 2>at-stder1 )
2082 # instead of the simpler
2084 #  ( $at_traceon; $1 ) >at-stdout 2>at-stder1
2086 # Note that we truncate and append to the output files, to avoid losing
2087 # output from multiple concurrent processes, e.g., an inner testsuite
2088 # with parallel jobs.
2089 m4_define([_AT_CHECK],
2090 [m4_define([AT_ingroup])]dnl
2091 [{ set +x
2092 AS_ECHO(["$at_srcdir/AT_LINE: AS_ESCAPE([[$1]])"])
2093 _AT_DECIDE_TRACEABLE([$1]) "AS_ESCAPE(m4_dquote(AT_LINE))"
2094 ( $at_check_trace; [$1]
2095 ) >>"$at_stdout" 2>>"$at_stderr"
2096 at_status=$? at_failed=false
2097 $at_check_filter
2098 m4_ifdef([AT_DIFF_STDERR($4)], [m4_indir([AT_DIFF_STDERR($4)])],
2099   [echo >>"$at_stderr"; AS_ECHO([["$4"]]) | \
2100   $at_diff - "$at_stderr" || at_failed=:])
2101 m4_ifdef([AT_DIFF_STDOUT($3)], [m4_indir([AT_DIFF_STDOUT($3)])],
2102   [echo >>"$at_stdout"; AS_ECHO([["$3"]]) | \
2103   $at_diff - "$at_stdout" || at_failed=:])
2104 m4_if([$2], [ignore], [at_fn_check_skip],
2105   [at_fn_check_status m4_default([$2], [0])]) $at_status "$at_srcdir/AT_LINE"
2106 m4_ifvaln([$5$6], [AS_IF($at_failed, [$5], [$6])])]dnl
2107 [$at_failed && at_fn_log_failure AT_capture_files
2108 $at_traceon; }
2109 ])# _AT_CHECK