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