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