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