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