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