1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215 |
- # This file is part of Autoconf. -*- Autoconf -*-
- # M4 macros used in building test suites.
- m4_define([_AT_COPYRIGHT_YEARS], [
- Copyright (C) 2000-2012 Free Software Foundation, Inc.
- ])
- # This file is part of Autoconf. This program is free
- # software; you can redistribute it and/or modify it under the
- # terms of the GNU General Public License as published by the
- # Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # Under Section 7 of GPL version 3, you are granted additional
- # permissions described in the Autoconf Configure Script Exception,
- # version 3.0, as published by the Free Software Foundation.
- #
- # You should have received a copy of the GNU General Public License
- # and a copy of the Autoconf Configure Script Exception along with
- # this program; see the files COPYINGv3 and COPYING.EXCEPTION
- # respectively. If not, see <http://www.gnu.org/licenses/>.
- # _m4_divert(DIVERSION-NAME)
- # --------------------------
- # Convert a diversion name into its number. Otherwise, return
- # DIVERSION-NAME which is supposed to be an actual diversion number.
- # Of course it would be nicer to use m4_case here, instead of zillions
- # of little macros, but it then takes twice longer to run `autoconf'!
- #
- # From M4sugar:
- # -1. KILL
- # 10000. GROW
- #
- # From M4sh:
- # 0. BINSH
- # 1. HEADER-REVISION
- # 2. HEADER-COMMENT
- # 3. HEADER-COPYRIGHT
- # 4. M4SH-SANITIZE
- # 5. M4SH-INIT
- # 1000. BODY
- #
- # Defined below:
- # - DEFAULTS
- # Overall initialization, value of $at_groups_all.
- # - PARSE_ARGS_BEGIN
- # Setup defaults required for option processing.
- # - PARSE_ARGS
- # Option processing. After AT_INIT, user options can be entered here as
- # cases of a case statement.
- # - PARSE_ARGS_END
- # Finish up the option processing.
- #
- # - HELP
- # Start printing the help message.
- # - HELP_MODES
- # Modes help text. Additional modes can be appended as self-contained
- # cat'd here-docs as generated by AS_HELP_STRING.
- # - HELP_TUNING_BEGIN
- # Tuning help text. This is for Autotest-provided text.
- # - HELP_TUNING
- # Additional tuning options' help text can be appended here as
- # self-contained cat'd here-docs as generated by AS_HELP_STRING.
- # - HELP_OTHER
- # User help can be appended to this as self-contained cat'd here-docs.
- # - HELP_END
- # Finish up the help texts.
- #
- # - VERSION
- # Head of the handling of --version.
- # - VERSION_NOTICES
- # Copyright notices for --version.
- # - VERSION_END
- # Tail of the handling of --version.
- #
- # - BANNERS
- # Output shell initialization for the associative array of banner text.
- # - TESTS_BEGIN
- # Like DEFAULTS but run after argument processing for purposes of
- # optimization. Do anything else that needs to be done to prepare for
- # tests. Sets up verbose and log file descriptors. Sets and logs PATH.
- # - PREPARE_TESTS
- # Declares functions shared among the tests. Perform any user
- # initialization to be shared among all tests.
- # - TESTS
- # The core of the test suite.
- #
- # - TEST_SCRIPT
- # The collector for code for each test, the ``normal'' diversion, but
- # undiverted into other locations before final output.
- #
- # - TEST_GROUPS
- # Contents of each test group. The tests deliberately occur after the
- # end of the shell script, so that the shell need not spend time parsing
- # commands it will not execute.
- m4_define([_m4_divert(DEFAULTS)], 100)
- m4_define([_m4_divert(PARSE_ARGS_BEGIN)], 200)
- m4_define([_m4_divert(PARSE_ARGS)], 201)
- m4_define([_m4_divert(PARSE_ARGS_END)], 202)
- m4_define([_m4_divert(HELP)], 300)
- m4_define([_m4_divert(HELP_MODES)], 301)
- m4_define([_m4_divert(HELP_TUNING_BEGIN)], 302)
- m4_define([_m4_divert(HELP_TUNING)], 303)
- m4_define([_m4_divert(HELP_OTHER)], 304)
- m4_define([_m4_divert(HELP_END)], 305)
- m4_define([_m4_divert(VERSION)], 350)
- m4_define([_m4_divert(VERSION_NOTICES)], 351)
- m4_define([_m4_divert(VERSION_END)], 352)
- m4_define([_m4_divert(BANNERS)], 400)
- m4_define([_m4_divert(TESTS_BEGIN)], 401)
- m4_define([_m4_divert(PREPARE_TESTS)], 402)
- m4_define([_m4_divert(TESTS)], 403)
- m4_define([_m4_divert(TEST_SCRIPT)], 450)
- m4_define([_m4_divert(TEST_GROUPS)], 500)
- # AT_LINE
- # -------
- # Return the current file sans directory, a colon, and the current
- # line. Be sure to return a _quoted_ file name, so if, for instance,
- # the user is lunatic enough to have a file named `dnl' (and I, for
- # one, love to be brainless and stubborn sometimes), then we return a
- # quoted name.
- #
- # Gee, we can't use simply
- #
- # m4_bpatsubst(__file__, [^.*/\(.*\)], [[\1]])
- #
- # since then, since `dnl' doesn't match the pattern, it is returned
- # with once quotation level less, so you lose! And since GNU M4
- # is one of the biggest junk in the whole universe wrt regexp, don't
- # even think about using `?' or `\?'. Bah, `*' will do.
- # Pleeeeeeeease, Gary, provide us with dirname and ERE!
- #
- # M4 recompiles the regular expression for every m4_bpatsubst, but __file__
- # rarely changes. Be fast - only compute the dirname when necessary; for
- # autoconf alone, this shaves off several seconds in building testsuite.
- m4_define([_AT_LINE_file])
- m4_define([_AT_LINE_base])
- m4_define([AT_LINE],
- [m4_if(m4_defn([_AT_LINE_file]), __file__, [],
- [m4_do([m4_define([_AT_LINE_file], __file__)],
- [m4_define([_AT_LINE_base],
- m4_bregexp(/__file__, [/\([^/]*\)$], [[\1]]))])])dnl
- m4_defn([_AT_LINE_base]):__line__])
- # _AT_LINE_ESCAPED
- # ----------------
- # Same as AT_LINE, but already escaped for the shell.
- m4_define([_AT_LINE_ESCAPED], ["AS_ESCAPE(m4_dquote(AT_LINE))"])
- # _AT_NORMALIZE_TEST_GROUP_NUMBER(SHELL-VAR)
- # ------------------------------------------
- # Normalize SHELL-VAR so that its value has the same number of digits as
- # all the other test group numbers.
- m4_define([_AT_NORMALIZE_TEST_GROUP_NUMBER],
- [
- eval 'while :; do
- case $$1 in #(
- '"$at_format"'*) break;;
- esac
- $1=0$$1
- done'
- ])
- # _AT_DEFINE_INIT(NAME, [DEFINITION])
- # -----------------------------------
- # Define macro NAME to die if invoked prior to AT_INIT, and to DEFINITION
- # after AT_INIT.
- m4_define([_AT_DEFINE_INIT],
- [m4_define($@)m4_pushdef([$1], [m4_fatal([$1: missing AT_INIT detected])])dnl
- m4_append([_AT_DEFINE_INIT_LIST], [[$1]], [,])])
- # _AT_DEFINE_SETUP(NAME, [DEFINITION])
- # ------------------------------------
- # Define macro NAME to die if invoked outside AT_SETUP/AT_CLEANUP, and
- # to DEFINITION otherwise.
- m4_define([_AT_DEFINE_SETUP],
- [m4_define([$1], [m4_ifndef([AT_ingroup],
- [m4_fatal([$1: missing AT_SETUP detected])])$2])])
- # AT_INIT([TESTSUITE-NAME])
- # -------------------------
- # Begin test suite.
- m4_define([AT_INIT],
- [m4_pushdef([AT_INIT], [m4_fatal([$0: invoked multiple times])])]
- [m4_pattern_forbid([^_?AT_])]
- [m4_pattern_allow([^_ATEOF$])]
- [m4_ifndef([AT_PACKAGE_BUGREPORT], [m4_fatal(
- [$1: AT_PACKAGE_BUGREPORT is missing, consider writing package.m4])])]
- [m4_define([AT_TESTSUITE_NAME],
- m4_defn([AT_PACKAGE_STRING])[ test suite]m4_ifval([$1],
- [m4_expand([: $1])]))]
- [m4_define([AT_ordinal], 0)]
- [m4_define([AT_banner_ordinal], 0)]
- [m4_define([AT_help_all], [])]
- [m4_map_args([_m4_popdef], _AT_DEFINE_INIT_LIST)]
- [m4_wrap([_AT_FINISH])]
- [AS_INIT[]]dnl
- dnl We don't use m4sh's BODY diversion, but AS_INIT sticks a banner there.
- dnl This trick removes that banner, since it adds nothing to autotest.
- [m4_cleardivert([BODY])]dnl
- [AS_ME_PREPARE[]]dnl
- [m4_divert_push([DEFAULTS])]dnl
- [AT_COPYRIGHT(m4_defn([_AT_COPYRIGHT_YEARS]), [
- m4_copyright_condense])]
- [AT_COPYRIGHT(
- [This test suite is free software; the Free Software Foundation gives
- unlimited permission to copy, distribute and modify it.], [m4_echo])]
- [AS_PREPARE
- SHELL=${CONFIG_SHELL-/bin/sh}
- # How were we run?
- at_cli_args="$[@]"
- m4_divert_push([BANNERS])dnl
- # Should we print banners? Yes if more than one test is run.
- case $at_groups in #(
- *$as_nl* )
- at_print_banners=: ;; #(
- * ) at_print_banners=false ;;
- esac
- # Text for banner N, set to a single space once printed.
- m4_divert_pop([BANNERS])dnl back to DEFAULTS
- m4_divert_push([PREPARE_TESTS])dnl
- m4_text_box([Autotest shell functions.])
- AS_FUNCTION_DESCRIBE([at_fn_banner], [NUMBER],
- [Output banner NUMBER, provided the testsuite is running multiple groups
- and this particular banner has not yet been printed.])
- at_fn_banner ()
- {
- $at_print_banners || return 0
- eval at_banner_text=\$at_banner_text_$[1]
- test "x$at_banner_text" = "x " && return 0
- eval "at_banner_text_$[1]=\" \""
- if test -z "$at_banner_text"; then
- $at_first || echo
- else
- AS_ECHO(["$as_nl$at_banner_text$as_nl"])
- fi
- } # at_fn_banner
- AS_FUNCTION_DESCRIBE([at_fn_check_prepare_notrace], [REASON LINE],
- [Perform AT_CHECK preparations for the command at LINE for an
- untraceable command; REASON is the reason for disabling tracing.])
- at_fn_check_prepare_notrace ()
- {
- $at_trace_echo "Not enabling shell tracing (command contains $[1])"
- AS_ECHO(["$[2]"]) >"$at_check_line_file"
- at_check_trace=: at_check_filter=:
- : >"$at_stdout"; : >"$at_stderr"
- }
- AS_FUNCTION_DESCRIBE([at_fn_check_prepare_trace], [LINE],
- [Perform AT_CHECK preparations for the command at LINE for a traceable
- command.])
- at_fn_check_prepare_trace ()
- {
- AS_ECHO(["$[1]"]) >"$at_check_line_file"
- at_check_trace=$at_traceon at_check_filter=$at_check_filter_trace
- : >"$at_stdout"; : >"$at_stderr"
- }
- AS_FUNCTION_DESCRIBE([at_fn_check_prepare_dynamic], [COMMAND LINE],
- [Decide if COMMAND at LINE is traceable at runtime, and call the
- appropriate preparation function.])
- at_fn_check_prepare_dynamic ()
- {
- case $[1] in
- *$as_nl*)
- at_fn_check_prepare_notrace 'an embedded newline' "$[2]" ;;
- *)
- at_fn_check_prepare_trace "$[2]" ;;
- esac
- }
- AS_FUNCTION_DESCRIBE([at_fn_filter_trace], [],
- [Remove the lines in the file "$at_stderr" generated by "set -x" and print
- them to stderr.])
- at_fn_filter_trace ()
- {
- mv "$at_stderr" "$at_stder1"
- grep '^ *+' "$at_stder1" >&2
- grep -v '^ *+' "$at_stder1" >"$at_stderr"
- }
- AS_FUNCTION_DESCRIBE([at_fn_log_failure], [FILE-LIST],
- [Copy the files in the list on stdout with a "> " prefix, and exit the shell
- with a failure exit code.])
- at_fn_log_failure ()
- {
- for file
- do AS_ECHO(["$file:"]); sed 's/^/> /' "$file"; done
- echo 1 > "$at_status_file"
- exit 1
- }
- AS_FUNCTION_DESCRIBE([at_fn_check_skip], [EXIT-CODE LINE],
- [Check whether EXIT-CODE is a special exit code (77 or 99), and if so exit
- the test group subshell with that same exit code. Use LINE in any report
- about test failure.])
- at_fn_check_skip ()
- {
- case $[1] in
- 99) echo 99 > "$at_status_file"; at_failed=:
- AS_ECHO(["$[2]: hard failure"]); exit 99;;
- 77) echo 77 > "$at_status_file"; exit 77;;
- esac
- }
- AS_FUNCTION_DESCRIBE([at_fn_check_status], [EXPECTED EXIT-CODE LINE],
- [Check whether EXIT-CODE is the EXPECTED exit code, and if so do nothing.
- Otherwise, if it is 77 or 99, exit the test group subshell with that same
- exit code; if it is anything else print an error message referring to LINE,
- and fail the test.])
- at_fn_check_status ()
- {
- dnl This order ensures that we don't `skip' if we are precisely checking
- dnl $? = 77 or $? = 99.
- case $[2] in
- $[1] ) ;;
- 77) echo 77 > "$at_status_file"; exit 77;;
- 99) echo 99 > "$at_status_file"; at_failed=:
- AS_ECHO(["$[3]: hard failure"]); exit 99;;
- *) AS_ECHO(["$[3]: exit code was $[2], expected $[1]"])
- at_failed=:;;
- esac
- }
- AS_FUNCTION_DESCRIBE([at_fn_diff_devnull], [FILE],
- [Emit a diff between /dev/null and FILE. Uses "test -s" to avoid useless
- diff invocations.])
- at_fn_diff_devnull ()
- {
- test -s "$[1]" || return 0
- $at_diff "$at_devnull" "$[1]"
- }
- AS_FUNCTION_DESCRIBE([at_fn_test], [NUMBER],
- [Parse out test NUMBER from the tail of this file.])
- at_fn_test ()
- {
- eval at_sed=\$at_sed$[1]
- sed "$at_sed" "$at_myself" > "$at_test_source"
- }
- AS_FUNCTION_DESCRIBE([at_fn_create_debugging_script], [],
- [Create the debugging script $at_group_dir/run which will reproduce the
- current test group.])
- at_fn_create_debugging_script ()
- {
- {
- echo "#! /bin/sh" &&
- echo 'test "${ZSH_VERSION+set}" = set dnl
- && alias -g '\''${1+"$[@]"}'\''='\''"$[@]"'\''' &&
- AS_ECHO(["cd '$at_dir'"]) &&
- AS_ECHO(["exec \${CONFIG_SHELL-$SHELL} \"$at_myself\" -v -d ]dnl
- [$at_debug_args $at_group \${1+\"\$[@]\"}"]) &&
- echo 'exit 1'
- } >"$at_group_dir/run" &&
- chmod +x "$at_group_dir/run"
- }
- m4_text_box([End of autotest shell functions.])
- m4_divert_pop([PREPARE_TESTS])dnl back to DEFAULTS
- # Not all shells have the 'times' builtin; the subshell is needed to make
- # sure we discard the 'times: not found' message from the shell.
- at_times_p=false
- (times) >/dev/null 2>&1 && at_times_p=:
- # CLI Arguments to pass to the debugging scripts.
- at_debug_args=
- # -e sets to true
- at_errexit_p=false
- # Shall we be verbose? ':' means no, empty means yes.
- at_verbose=:
- at_quiet=
- # Running several jobs in parallel, 0 means as many as test groups.
- at_jobs=1
- at_traceon=:
- at_trace_echo=:
- at_check_filter_trace=:
- # Shall we keep the debug scripts? Must be `:' when the suite is
- # run by a debug script, so that the script doesn't remove itself.
- at_debug_p=false
- # Display help message?
- at_help_p=false
- # Display the version message?
- at_version_p=false
- # List test groups?
- at_list_p=false
- # --clean
- at_clean=false
- # Test groups to run
- at_groups=
- # Whether to rerun failed tests.
- at_recheck=
- # Whether a write failure occurred
- at_write_fail=0
- # The directory we run the suite in. Default to . if no -C option.
- at_dir=`pwd`
- # An absolute reference to this testsuite script.
- dnl m4-double quote, to preserve []
- [case $as_myself in
- [\\/]* | ?:[\\/]* ) at_myself=$as_myself ;;
- * ) at_myself=$at_dir/$as_myself ;;
- esac]
- # Whether -C is in effect.
- at_change_dir=false
- m4_divert_pop([DEFAULTS])dnl
- m4_define([_AT_FINISH],
- [m4_ifdef([AT_ingroup], [m4_fatal([missing AT_CLEANUP detected])])dnl
- m4_divert_text([DEFAULTS],
- [
- # Whether to enable colored test results.
- at_color=m4_ifdef([AT_color], [AT_color], [no])
- # List of the tested programs.
- at_tested='m4_ifdef([AT_tested],
- [m4_translit(m4_dquote(m4_defn([AT_tested])), [ ], m4_newline)])'
- # As many question marks as there are digits in the last test group number.
- # Used to normalize the test group numbers so that `ls' lists them in
- # numerical order.
- at_format='m4_bpatsubst(m4_defn([AT_ordinal]), [.], [?])'
- # Description of all the test groups.
- at_help_all="AS_ESCAPE(m4_dquote(m4_defn([AT_help_all])))"
- # List of the all the test groups.
- at_groups_all=`AS_ECHO(["$at_help_all"]) | sed 's/;.*//'`
- AS_FUNCTION_DESCRIBE([at_fn_validate_ranges], [NAME...],
- [Validate and normalize the test group number contained in each
- variable NAME. Leading zeroes are treated as decimal.])
- at_fn_validate_ranges ()
- {
- for at_grp
- do
- eval at_value=\$$at_grp
- if test $at_value -lt 1 || test $at_value -gt AT_ordinal; then
- AS_ECHO(["invalid test group: $at_value"]) >&2
- exit 1
- fi
- case $at_value in
- 0*) # We want to treat leading 0 as decimal, like expr and test, but
- # AS_VAR_ARITH treats it as octal if it uses $(( )).
- # With XSI shells, ${at_value#${at_value%%[1-9]*}} avoids the
- # expr fork, but it is not worth the effort to determine if the
- # shell supports XSI when the user can just avoid leading 0.
- eval $at_grp='`expr $at_value + 0`' ;;
- esac
- done
- }])])dnl
- m4_divert_push([PARSE_ARGS])dnl
- at_prev=
- for at_option
- do
- # If the previous option needs an argument, assign it.
- if test -n "$at_prev"; then
- at_option=$at_prev=$at_option
- at_prev=
- fi
- case $at_option in
- *=?*) at_optarg=`expr "X$at_option" : '[[^=]]*=\(.*\)'` ;;
- *) at_optarg= ;;
- esac
- # Accept the important Cygnus configure options, so we can diagnose typos.
- case $at_option in
- --help | -h )
- at_help_p=:
- ;;
- --list | -l )
- at_list_p=:
- ;;
- --version | -V )
- at_version_p=:
- ;;
- --clean | -c )
- at_clean=:
- ;;
- --color )
- at_color=always
- ;;
- --color=* )
- case $at_optarg in
- no | never | none) at_color=never ;;
- auto | tty | if-tty) at_color=auto ;;
- always | yes | force) at_color=always ;;
- *) at_optname=`echo " $at_option" | sed 's/^ //; s/=.*//'`
- AS_ERROR([unrecognized argument to $at_optname: $at_optarg]) ;;
- esac
- ;;
- --debug | -d )
- at_debug_p=:
- ;;
- --errexit | -e )
- at_debug_p=:
- at_errexit_p=:
- ;;
- --verbose | -v )
- at_verbose=; at_quiet=:
- ;;
- --trace | -x )
- at_traceon='set -x'
- at_trace_echo=echo
- at_check_filter_trace=at_fn_filter_trace
- ;;
- [[0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]])
- at_fn_validate_ranges at_option
- AS_VAR_APPEND([at_groups], ["$at_option$as_nl"])
- ;;
- # Ranges
- [[0-9]- | [0-9][0-9]- | [0-9][0-9][0-9]- | [0-9][0-9][0-9][0-9]-])
- at_range_start=`echo $at_option |tr -d X-`
- at_fn_validate_ranges at_range_start
- at_range=`AS_ECHO(["$at_groups_all"]) | \
- sed -ne '/^'$at_range_start'$/,$p'`
- AS_VAR_APPEND([at_groups], ["$at_range$as_nl"])
- ;;
- [-[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | -[0-9][0-9][0-9][0-9]])
- at_range_end=`echo $at_option |tr -d X-`
- at_fn_validate_ranges at_range_end
- at_range=`AS_ECHO(["$at_groups_all"]) | \
- sed -ne '1,/^'$at_range_end'$/p'`
- AS_VAR_APPEND([at_groups], ["$at_range$as_nl"])
- ;;
- [[0-9]-[0-9] | [0-9]-[0-9][0-9] | [0-9]-[0-9][0-9][0-9]] | \
- [[0-9]-[0-9][0-9][0-9][0-9] | [0-9][0-9]-[0-9][0-9]] | \
- [[0-9][0-9]-[0-9][0-9][0-9] | [0-9][0-9]-[0-9][0-9][0-9][0-9]] | \
- [[0-9][0-9][0-9]-[0-9][0-9][0-9]] | \
- [[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]] | \
- [[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]] )
- at_range_start=`expr $at_option : '\(.*\)-'`
- at_range_end=`expr $at_option : '.*-\(.*\)'`
- if test $at_range_start -gt $at_range_end; then
- at_tmp=$at_range_end
- at_range_end=$at_range_start
- at_range_start=$at_tmp
- fi
- at_fn_validate_ranges at_range_start at_range_end
- at_range=`AS_ECHO(["$at_groups_all"]) | \
- sed -ne '/^'$at_range_start'$/,/^'$at_range_end'$/p'`
- AS_VAR_APPEND([at_groups], ["$at_range$as_nl"])
- ;;
- # Directory selection.
- --directory | -C )
- at_prev=--directory
- ;;
- --directory=* )
- at_change_dir=:
- at_dir=$at_optarg
- if test x- = "x$at_dir" ; then
- at_dir=./-
- fi
- ;;
- # Parallel execution.
- --jobs | -j )
- at_jobs=0
- ;;
- --jobs=* | -j[[0-9]]* )
- if test -n "$at_optarg"; then
- at_jobs=$at_optarg
- else
- at_jobs=`expr X$at_option : 'X-j\(.*\)'`
- fi
- case $at_jobs in *[[!0-9]]*)
- at_optname=`echo " $at_option" | sed 's/^ //; s/[[0-9=]].*//'`
- AS_ERROR([non-numeric argument to $at_optname: $at_jobs]) ;;
- esac
- ;;
- # Keywords.
- --keywords | -k )
- at_prev=--keywords
- ;;
- --keywords=* )
- at_groups_selected=$at_help_all
- at_save_IFS=$IFS
- IFS=,
- set X $at_optarg
- shift
- IFS=$at_save_IFS
- for at_keyword
- do
- at_invert=
- case $at_keyword in
- '!'*)
- at_invert="-v"
- at_keyword=`expr "X$at_keyword" : 'X!\(.*\)'`
- ;;
- esac
- # It is on purpose that we match the test group titles too.
- at_groups_selected=`AS_ECHO(["$at_groups_selected"]) |
- grep -i $at_invert ["^[1-9][^;]*;.*[; ]$at_keyword[ ;]"]`
- done
- # Smash the keywords.
- at_groups_selected=`AS_ECHO(["$at_groups_selected"]) | sed 's/;.*//'`
- AS_VAR_APPEND([at_groups], ["$at_groups_selected$as_nl"])
- ;;
- --recheck)
- at_recheck=:
- ;;
- m4_divert_pop([PARSE_ARGS])dnl
- dnl Process *=* last to allow for user specified --option=* type arguments.
- m4_divert_push([PARSE_ARGS_END])dnl
- *=*)
- at_envvar=`expr "x$at_option" : 'x\([[^=]]*\)='`
- # Reject names that are not valid shell variable names.
- case $at_envvar in
- '' | [[0-9]]* | *[[!_$as_cr_alnum]]* )
- AS_ERROR([invalid variable name: `$at_envvar']) ;;
- esac
- at_value=`AS_ECHO(["$at_optarg"]) | sed "s/'/'\\\\\\\\''/g"`
- # Export now, but save eval for later and for debug scripts.
- export $at_envvar
- AS_VAR_APPEND([at_debug_args], [" $at_envvar='$at_value'"])
- ;;
- *) AS_ECHO(["$as_me: invalid option: $at_option"]) >&2
- AS_ECHO(["Try \`$[0] --help' for more information."]) >&2
- exit 1
- ;;
- esac
- done
- # Verify our last option didn't require an argument
- AS_IF([test -n "$at_prev"], [AS_ERROR([`$at_prev' requires an argument])])
- # The file containing the suite.
- at_suite_log=$at_dir/$as_me.log
- # Selected test groups.
- if test -z "$at_groups$at_recheck"; then
- at_groups=$at_groups_all
- else
- if test -n "$at_recheck" && test -r "$at_suite_log"; then
- at_oldfails=`sed -n ['
- /^Failed tests:$/,/^Skipped tests:$/{
- s/^[ ]*\([1-9][0-9]*\):.*/\1/p
- }
- /^Unexpected passes:$/,/^## Detailed failed tests/{
- s/^[ ]*\([1-9][0-9]*\):.*/\1/p
- }
- /^## Detailed failed tests/q
- '] "$at_suite_log"`
- AS_VAR_APPEND([at_groups], ["$at_oldfails$as_nl"])
- fi
- # Sort the tests, removing duplicates.
- at_groups=`AS_ECHO(["$at_groups"]) | sort -nu | sed '/^$/d'`
- fi
- if test x"$at_color" = xalways \
- || { test x"$at_color" = xauto && test -t 1; }; then
- at_red=`printf '\033@<:@0;31m'`
- at_grn=`printf '\033@<:@0;32m'`
- at_lgn=`printf '\033@<:@1;32m'`
- at_blu=`printf '\033@<:@1;34m'`
- at_std=`printf '\033@<:@m'`
- else
- at_red= at_grn= at_lgn= at_blu= at_std=
- fi
- m4_divert_pop([PARSE_ARGS_END])dnl
- m4_divert_push([HELP])dnl
- # Help message.
- if $at_help_p; then
- cat <<_ATEOF || at_write_fail=1
- Usage: $[0] [[OPTION]... [VARIABLE=VALUE]... [TESTS]]
- Run all the tests, or the selected TESTS, given by numeric ranges, and
- save a detailed log file. Upon failure, create debugging scripts.
- Do not change environment variables directly. Instead, set them via
- command line arguments. Set \`AUTOTEST_PATH' to select the executables
- to exercise. Each relative directory is expanded as build and source
- directories relative to the top level of this distribution.
- E.g., from within the build directory /tmp/foo-1.0, invoking this:
- $ $[0] AUTOTEST_PATH=bin
- is equivalent to the following, assuming the source directory is /src/foo-1.0:
- PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:\$PATH $[0]
- _ATEOF
- m4_divert_pop([HELP])dnl
- m4_divert_push([HELP_MODES])dnl
- cat <<_ATEOF || at_write_fail=1
- Operation modes:
- -h, --help print the help message, then exit
- -V, --version print version number, then exit
- -c, --clean remove all the files this test suite might create and exit
- -l, --list describes all the tests, or the selected TESTS
- _ATEOF
- m4_divert_pop([HELP_MODES])dnl
- m4_wrap([m4_divert_push([HELP_TUNING_BEGIN])dnl
- cat <<_ATEOF || at_write_fail=1
- dnl extra quoting prevents emacs whitespace mode from putting tabs in output
- Execution tuning:
- -C, --directory=DIR
- [ change to directory DIR before starting]
- --color[[=never|auto|always]]
- [ ]m4_ifdef([AT_color],
- [disable colored test results, or enable even without terminal],
- [enable colored test results on terminal, or always])
- -j, --jobs[[=N]]
- [ Allow N jobs at once; infinite jobs with no arg (default 1)]
- -k, --keywords=KEYWORDS
- [ select the tests matching all the comma-separated KEYWORDS]
- [ multiple \`-k' accumulate; prefixed \`!' negates a KEYWORD]
- --recheck select all tests that failed or passed unexpectedly last time
- -e, --errexit abort as soon as a test fails; implies --debug
- -v, --verbose force more detailed output
- [ default for debugging scripts]
- -d, --debug inhibit clean up and top-level logging
- [ default for debugging scripts]
- -x, --trace enable tests shell tracing
- _ATEOF
- m4_divert_pop([HELP_TUNING_BEGIN])])dnl
- m4_divert_push([HELP_END])dnl
- cat <<_ATEOF || at_write_fail=1
- Report bugs to <AT_PACKAGE_BUGREPORT>.dnl
- m4_ifdef([AT_PACKAGE_NAME],
- [m4_ifset([AT_PACKAGE_URL], [
- m4_defn([AT_PACKAGE_NAME]) home page: <AT_PACKAGE_URL>.])dnl
- m4_if(m4_index(m4_defn([AT_PACKAGE_NAME]), [GNU ]), [0], [
- General help using GNU software: <http://www.gnu.org/gethelp/>.])])
- _ATEOF
- exit $at_write_fail
- fi
- # List of tests.
- if $at_list_p; then
- cat <<_ATEOF || at_write_fail=1
- AT_TESTSUITE_NAME test groups:
- NUM: FILE-NAME:LINE TEST-GROUP-NAME
- KEYWORDS
- _ATEOF
- # Pass an empty line as separator between selected groups and help.
- AS_ECHO(["$at_groups$as_nl$as_nl$at_help_all"]) |
- awk 'NF == 1 && FS != ";" {
- selected[[$ 1]] = 1
- next
- }
- /^$/ { FS = ";" }
- NF > 0 {
- if (selected[[$ 1]]) {
- printf " %3d: %-18s %s\n", $ 1, $ 2, $ 3
- if ($ 4) {
- lmax = 79
- indent = " "
- line = indent
- len = length (line)
- n = split ($ 4, a, " ")
- for (i = 1; i <= n; i++) {
- l = length (a[[i]]) + 1
- if (i > 1 && len + l > lmax) {
- print line
- line = indent " " a[[i]]
- len = length (line)
- } else {
- line = line " " a[[i]]
- len += l
- }
- }
- if (n)
- print line
- }
- }
- }' || at_write_fail=1
- exit $at_write_fail
- fi
- m4_divert_pop([HELP_END])dnl
- m4_divert_push([VERSION])dnl
- if $at_version_p; then
- AS_ECHO(["$as_me (AT_PACKAGE_STRING)"]) &&
- cat <<\_ATEOF || at_write_fail=1
- m4_divert_pop([VERSION])dnl
- m4_divert_push([VERSION_END])dnl
- _ATEOF
- exit $at_write_fail
- fi
- m4_divert_pop([VERSION_END])dnl
- m4_divert_push([TESTS_BEGIN])dnl
- # Take any -C into account.
- if $at_change_dir ; then
- test x != "x$at_dir" && cd "$at_dir" \
- || AS_ERROR([unable to change directory])
- at_dir=`pwd`
- fi
- # Load the config files for any default variable assignments.
- for at_file in atconfig atlocal
- do
- test -r $at_file || continue
- . ./$at_file || AS_ERROR([invalid content: $at_file])
- done
- # Autoconf <=2.59b set at_top_builddir instead of at_top_build_prefix:
- : "${at_top_build_prefix=$at_top_builddir}"
- # Perform any assignments requested during argument parsing.
- eval "$at_debug_args"
- # atconfig delivers names relative to the directory the test suite is
- # in, but the groups themselves are run in testsuite-dir/group-dir.
- if test -n "$at_top_srcdir"; then
- builddir=../..
- for at_dir_var in srcdir top_srcdir top_build_prefix
- do
- AS_VAR_COPY([at_val], [at_$at_dir_var])
- case $at_val in
- [[\\/$]]* | ?:[[\\/]]* ) at_prefix= ;;
- *) at_prefix=../../ ;;
- esac
- AS_VAR_SET([$at_dir_var], [$at_prefix$at_val])
- done
- fi
- m4_text_box([Directory structure.])
- # This is the set of directories and files used by this script
- # (non-literals are capitalized):
- #
- # TESTSUITE - the testsuite
- # TESTSUITE.log - summarizes the complete testsuite run
- # TESTSUITE.dir/ - created during a run, remains after -d or failed test
- # + at-groups/ - during a run: status of all groups in run
- # | + NNN/ - during a run: meta-data about test group NNN
- # | | + check-line - location (source file and line) of current AT_CHECK
- # | | + status - exit status of current AT_CHECK
- # | | + stdout - stdout of current AT_CHECK
- # | | + stder1 - stderr, including trace
- # | | + stderr - stderr, with trace filtered out
- # | | + test-source - portion of testsuite that defines group
- # | | + times - timestamps for computing duration
- # | | + pass - created if group passed
- # | | + xpass - created if group xpassed
- # | | + fail - created if group failed
- # | | + xfail - created if group xfailed
- # | | + skip - created if group skipped
- # + at-stop - during a run: end the run if this file exists
- # + at-source-lines - during a run: cache of TESTSUITE line numbers for extraction
- # + 0..NNN/ - created for each group NNN, remains after -d or failed test
- # | + TESTSUITE.log - summarizes the group results
- # | + ... - files created during the group
- # The directory the whole suite works in.
- # Should be absolute to let the user `cd' at will.
- at_suite_dir=$at_dir/$as_me.dir
- # The file containing the suite ($at_dir might have changed since earlier).
- at_suite_log=$at_dir/$as_me.log
- # The directory containing helper files per test group.
- at_helper_dir=$at_suite_dir/at-groups
- # Stop file: if it exists, do not start new jobs.
- at_stop_file=$at_suite_dir/at-stop
- # The fifo used for the job dispatcher.
- at_job_fifo=$at_suite_dir/at-job-fifo
- if $at_clean; then
- test -d "$at_suite_dir" &&
- find "$at_suite_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
- rm -f -r "$at_suite_dir" "$at_suite_log"
- exit $?
- fi
- # Don't take risks: use only absolute directories in PATH.
- #
- # For stand-alone test suites (ie. atconfig was not found),
- # AUTOTEST_PATH is relative to `.'.
- #
- # For embedded test suites, AUTOTEST_PATH is relative to the top level
- # of the package. Then expand it into build/src parts, since users
- # may create executables in both places.
- AUTOTEST_PATH=`AS_ECHO(["$AUTOTEST_PATH"]) | sed "s|:|$PATH_SEPARATOR|g"`
- at_path=
- _AS_PATH_WALK([$AUTOTEST_PATH $PATH],
- [test -n "$at_path" && AS_VAR_APPEND([at_path], [$PATH_SEPARATOR])
- case $as_dir in
- [[\\/]]* | ?:[[\\/]]* )
- AS_VAR_APPEND([at_path], ["$as_dir"])
- ;;
- * )
- if test -z "$at_top_build_prefix"; then
- # Stand-alone test suite.
- AS_VAR_APPEND([at_path], ["$as_dir"])
- else
- # Embedded test suite.
- AS_VAR_APPEND([at_path], ["$at_top_build_prefix$as_dir$PATH_SEPARATOR"])
- AS_VAR_APPEND([at_path], ["$at_top_srcdir/$as_dir"])
- fi
- ;;
- esac])
- # Now build and simplify PATH.
- #
- # There might be directories that don't exist, but don't redirect
- # builtins' (eg., cd) stderr directly: Ultrix's sh hates that.
- at_new_path=
- _AS_PATH_WALK([$at_path],
- [test -d "$as_dir" || continue
- case $as_dir in
- [[\\/]]* | ?:[[\\/]]* ) ;;
- * ) as_dir=`(cd "$as_dir" && pwd) 2>/dev/null` ;;
- esac
- case $PATH_SEPARATOR$at_new_path$PATH_SEPARATOR in
- *$PATH_SEPARATOR$as_dir$PATH_SEPARATOR*) ;;
- $PATH_SEPARATOR$PATH_SEPARATOR) at_new_path=$as_dir ;;
- *) AS_VAR_APPEND([at_new_path], ["$PATH_SEPARATOR$as_dir"]) ;;
- esac])
- PATH=$at_new_path
- export PATH
- # Setting up the FDs.
- m4_define([AS_MESSAGE_LOG_FD], [5])
- dnl The parent needs two fds to the same fifo, otherwise, there is a race
- dnl where the parent can read the fifo before a child opens it for writing
- m4_define([AT_JOB_FIFO_IN_FD], [6])
- m4_define([AT_JOB_FIFO_OUT_FD], [7])
- [#] AS_MESSAGE_LOG_FD is the log file. Not to be overwritten if `-d'.
- if $at_debug_p; then
- at_suite_log=/dev/null
- else
- : >"$at_suite_log"
- fi
- exec AS_MESSAGE_LOG_FD>>"$at_suite_log"
- # Banners and logs.
- AS_BOX(m4_defn([AT_TESTSUITE_NAME])[.])
- {
- AS_BOX(m4_defn([AT_TESTSUITE_NAME])[.])
- echo
- AS_ECHO(["$as_me: command line was:"])
- AS_ECHO([" \$ $[0] $at_cli_args"])
- echo
- # If ChangeLog exists, list a few lines in case it might help determining
- # the exact version.
- if test -n "$at_top_srcdir" && test -f "$at_top_srcdir/ChangeLog"; then
- AS_BOX([ChangeLog.])
- echo
- sed 's/^/| /;10q' "$at_top_srcdir/ChangeLog"
- echo
- fi
- AS_UNAME
- echo
- # Contents of the config files.
- for at_file in atconfig atlocal
- do
- test -r $at_file || continue
- AS_ECHO(["$as_me: $at_file:"])
- sed 's/^/| /' $at_file
- echo
- done
- } >&AS_MESSAGE_LOG_FD
- m4_divert_pop([TESTS_BEGIN])dnl
- m4_divert_push([PREPARE_TESTS])dnl
- {
- AS_BOX([Tested programs.])
- echo
- } >&AS_MESSAGE_LOG_FD
- # Report what programs are being tested.
- for at_program in : $at_tested
- do
- test "$at_program" = : && continue
- case $at_program in
- [[\\/]* | ?:[\\/]* ) $at_program_=$at_program ;;]
- * )
- _AS_PATH_WALK([$PATH], [test -f "$as_dir/$at_program" && break])
- at_program_=$as_dir/$at_program ;;
- esac
- if test -f "$at_program_"; then
- {
- AS_ECHO(["$at_srcdir/AT_LINE: $at_program_ --version"])
- "$at_program_" --version </dev/null
- echo
- } >&AS_MESSAGE_LOG_FD 2>&1
- else
- AS_ERROR([cannot find $at_program])
- fi
- done
- {
- AS_BOX([Running the tests.])
- } >&AS_MESSAGE_LOG_FD
- at_start_date=`date`
- at_start_time=`date +%s 2>/dev/null`
- AS_ECHO(["$as_me: starting at: $at_start_date"]) >&AS_MESSAGE_LOG_FD
- m4_divert_pop([PREPARE_TESTS])dnl
- m4_divert_push([TESTS])dnl
- # Create the master directory if it doesn't already exist.
- AS_MKDIR_P(["$at_suite_dir"]) ||
- AS_ERROR([cannot create `$at_suite_dir'])
- # Can we diff with `/dev/null'? DU 5.0 refuses.
- if diff /dev/null /dev/null >/dev/null 2>&1; then
- at_devnull=/dev/null
- else
- at_devnull=$at_suite_dir/devnull
- >"$at_devnull"
- fi
- # Use `diff -u' when possible.
- if at_diff=`diff -u "$at_devnull" "$at_devnull" 2>&1` && test -z "$at_diff"
- then
- at_diff='diff -u'
- else
- at_diff=diff
- fi
- # Get the last needed group.
- for at_group in : $at_groups; do :; done
- # Extract the start and end lines of each test group at the tail
- # of this file
- awk '
- BEGIN { FS="" }
- /^@%:@AT_START_/ {
- start = NR
- }
- /^@%:@AT_STOP_/ {
- test = substr ($ 0, 10)
- print "at_sed" test "=\"1," start "d;" (NR-1) "q\""
- if (test == "'"$at_group"'") exit
- }' "$at_myself" > "$at_suite_dir/at-source-lines" &&
- . "$at_suite_dir/at-source-lines" ||
- AS_ERROR([cannot create test line number cache])
- rm -f "$at_suite_dir/at-source-lines"
- # Set number of jobs for `-j'; avoid more jobs than test groups.
- set X $at_groups; shift; at_max_jobs=$[@%:@]
- if test $at_max_jobs -eq 0; then
- at_jobs=1
- fi
- if test $at_jobs -ne 1 &&
- { test $at_jobs -eq 0 || test $at_jobs -gt $at_max_jobs; }; then
- at_jobs=$at_max_jobs
- fi
- # If parallel mode, don't output banners, don't split summary lines.
- if test $at_jobs -ne 1; then
- at_print_banners=false
- at_quiet=:
- fi
- # Set up helper dirs.
- rm -rf "$at_helper_dir" &&
- mkdir "$at_helper_dir" &&
- cd "$at_helper_dir" &&
- { test -z "$at_groups" || mkdir $at_groups; } ||
- AS_ERROR([testsuite directory setup failed])
- # Functions for running a test group. We leave the actual
- # test group execution outside of a shell function in order
- # to avoid hitting zsh 4.x exit status bugs.
- AS_FUNCTION_DESCRIBE([at_fn_group_prepare], [],
- [Prepare for running a test group.])
- at_fn_group_prepare ()
- {
- # The directory for additional per-group helper files.
- at_job_dir=$at_helper_dir/$at_group
- # The file containing the location of the last AT_CHECK.
- at_check_line_file=$at_job_dir/check-line
- # The file containing the exit status of the last command.
- at_status_file=$at_job_dir/status
- # The files containing the output of the tested commands.
- at_stdout=$at_job_dir/stdout
- at_stder1=$at_job_dir/stder1
- at_stderr=$at_job_dir/stderr
- # The file containing the code for a test group.
- at_test_source=$at_job_dir/test-source
- # The file containing dates.
- at_times_file=$at_job_dir/times
- # Be sure to come back to the top test directory.
- cd "$at_suite_dir"
- # Clearly separate the test groups when verbose.
- $at_first || $at_verbose echo
- at_group_normalized=$at_group
- _AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
- # Create a fresh directory for the next test group, and enter.
- # If one already exists, the user may have invoked ./run from
- # within that directory; we remove the contents, but not the
- # directory itself, so that we aren't pulling the rug out from
- # under the shell's notion of the current directory.
- at_group_dir=$at_suite_dir/$at_group_normalized
- at_group_log=$at_group_dir/$as_me.log
- _AS_CLEAN_DIR("$at_group_dir") ||
- AS_WARN([test directory for $at_group_normalized could not be cleaned])
- # Be tolerant if the above `rm' was not able to remove the directory.
- AS_MKDIR_P(["$at_group_dir"])
- echo 0 > "$at_status_file"
- # In verbose mode, append to the log file *and* show on
- # the standard output; in quiet mode only write to the log.
- if test -z "$at_verbose"; then
- at_tee_pipe='tee -a "$at_group_log"'
- else
- at_tee_pipe='cat >> "$at_group_log"'
- fi
- }
- AS_FUNCTION_DESCRIBE([at_fn_group_banner], [[ORDINAL LINE DESC PAD [BANNER]]],
- [Declare the test group ORDINAL, located at LINE with group description
- DESC, and residing under BANNER. Use PAD to align the status column.])
- at_fn_group_banner ()
- {
- at_setup_line="$[2]"
- test -n "$[5]" && at_fn_banner $[5]
- at_desc="$[3]"
- case $[1] in
- [[0-9]]) at_desc_line=" $[1]: ";;
- [[0-9][0-9]]) at_desc_line=" $[1]: " ;;
- [*]) at_desc_line="$[1]: " ;;
- esac
- AS_VAR_APPEND([at_desc_line], ["$[3]$[4]"])
- $at_quiet AS_ECHO_N(["$at_desc_line"])
- echo "# -*- compilation -*-" >> "$at_group_log"
- }
- AS_FUNCTION_DESCRIBE([at_fn_group_postprocess], [],
- [Perform cleanup after running a test group.])
- at_fn_group_postprocess ()
- {
- # Be sure to come back to the suite directory, in particular
- # since below we might `rm' the group directory we are in currently.
- cd "$at_suite_dir"
- if test ! -f "$at_check_line_file"; then
- sed "s/^ */$as_me: WARNING: /" <<_ATEOF
- A failure happened in a test group before any test could be
- run. This means that test suite is improperly designed. Please
- report this failure to <AT_PACKAGE_BUGREPORT>.
- _ATEOF
- AS_ECHO(["$at_setup_line"]) >"$at_check_line_file"
- at_status=99
- fi
- $at_verbose AS_ECHO_N(["$at_group. $at_setup_line: "])
- AS_ECHO_N(["$at_group. $at_setup_line: "]) >> "$at_group_log"
- case $at_xfail:$at_status in
- yes:0)
- at_msg="UNEXPECTED PASS"
- at_res=xpass
- at_errexit=$at_errexit_p
- at_color=$at_red
- ;;
- no:0)
- at_msg="ok"
- at_res=pass
- at_errexit=false
- at_color=$at_grn
- ;;
- *:77)
- at_msg='skipped ('`cat "$at_check_line_file"`')'
- at_res=skip
- at_errexit=false
- at_color=$at_blu
- ;;
- no:* | *:99)
- at_msg='FAILED ('`cat "$at_check_line_file"`')'
- at_res=fail
- at_errexit=$at_errexit_p
- at_color=$at_red
- ;;
- yes:*)
- at_msg='expected failure ('`cat "$at_check_line_file"`')'
- at_res=xfail
- at_errexit=false
- at_color=$at_lgn
- ;;
- esac
- echo "$at_res" > "$at_job_dir/$at_res"
- # In parallel mode, output the summary line only afterwards.
- if test $at_jobs -ne 1 && test -n "$at_verbose"; then
- AS_ECHO(["$at_desc_line $at_color$at_msg$at_std"])
- else
- # Make sure there is a separator even with long titles.
- AS_ECHO([" $at_color$at_msg$at_std"])
- fi
- at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg"
- case $at_status in
- 0|77)
- # $at_times_file is only available if the group succeeded.
- # We're not including the group log, so the success message
- # is written in the global log separately. But we also
- # write to the group log in case they're using -d.
- if test -f "$at_times_file"; then
- at_log_msg="$at_log_msg ("`sed 1d "$at_times_file"`')'
- rm -f "$at_times_file"
- fi
- AS_ECHO(["$at_log_msg"]) >> "$at_group_log"
- AS_ECHO(["$at_log_msg"]) >&AS_MESSAGE_LOG_FD
- # Cleanup the group directory, unless the user wants the files
- # or the success was unexpected.
- if $at_debug_p || test $at_res = xpass; then
- at_fn_create_debugging_script
- if test $at_res = xpass && $at_errexit; then
- echo stop > "$at_stop_file"
- fi
- else
- if test -d "$at_group_dir"; then
- find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
- rm -fr "$at_group_dir"
- fi
- rm -f "$at_test_source"
- fi
- ;;
- *)
- # Upon failure, include the log into the testsuite's global
- # log. The failure message is written in the group log. It
- # is later included in the global log.
- AS_ECHO(["$at_log_msg"]) >> "$at_group_log"
- # Upon failure, keep the group directory for autopsy, and create
- # the debugging script. With -e, do not start any further tests.
- at_fn_create_debugging_script
- if $at_errexit; then
- echo stop > "$at_stop_file"
- fi
- ;;
- esac
- }
- m4_text_box([Driver loop.])
- dnl Catching signals correctly:
- dnl
- dnl The first idea was: trap the signal, send it to all spawned jobs,
- dnl then reset the handler and reraise the signal for ourselves.
- dnl However, before exiting, ksh will then send the signal to all
- dnl process group members, potentially killing the outer testsuite
- dnl and/or the 'make' process driving us.
- dnl So now the strategy is: trap the signal, send it to all spawned jobs,
- dnl then exit the script with the right status.
- dnl
- dnl In order to let the jobs know about the signal, we cannot just send it
- dnl to the current process group (kill $SIG 0), for the same reason as above.
- dnl Also, it does not reliably stop the suite to send the signal to the
- dnl spawned processes, because they might not transport it further
- dnl (maybe this can be fixed?).
- dnl
- dnl So what we do is enable shell job control if available, which causes the
- dnl shell to start each parallel task as its own shell job, thus as a new
- dnl process group leader. We then send the signal to all new process groups.
- dnl Do we have job control?
- if (set -m && set +m && set +b) >/dev/null 2>&1; then
- set +b
- at_job_control_on='set -m' at_job_control_off='set +m' at_job_group=-
- else
- at_job_control_on=: at_job_control_off=: at_job_group=
- fi
- for at_signal in 1 2 15; do
- dnl This signal handler is not suitable for PIPE: it causes writes.
- dnl The code that was interrupted may have the errexit, monitor, or xtrace
- dnl flags enabled, so sanitize.
- trap 'set +x; set +e
- $at_job_control_off
- at_signal='"$at_signal"'
- dnl Safety belt: even with runaway processes, prevent starting new jobs.
- echo stop > "$at_stop_file"
- dnl Do not enter this area multiple times, do not kill self prematurely.
- trap "" $at_signal
- dnl Gather process group IDs of currently running jobs.
- at_pgids=
- for at_pgid in `jobs -p 2>/dev/null`; do
- at_pgids="$at_pgids $at_job_group$at_pgid"
- done
- dnl Ignore `kill' errors, as some jobs may have finished in the meantime.
- test -z "$at_pgids" || kill -$at_signal $at_pgids 2>/dev/null
- dnl wait until all jobs have exited.
- wait
- dnl Status output. Do this after waiting for the jobs, for ordered output.
- dnl Avoid scribbling onto the end of a possibly incomplete line.
- if test "$at_jobs" -eq 1 || test -z "$at_verbose"; then
- echo >&2
- fi
- at_signame=`kill -l $at_signal 2>&1 || echo $at_signal`
- set x $at_signame
- test $# -gt 2 && at_signame=$at_signal
- AS_WARN([caught signal $at_signame, bailing out])
- dnl Do not reinstall the default handler here and reraise the signal to
- dnl let the default handler do its job, see the note about ksh above.
- dnl trap - $at_signal
- dnl kill -$at_signal $$
- dnl Instead, exit with appropriate status.
- AS_VAR_ARITH([exit_status], [128 + $at_signal])
- AS_EXIT([$exit_status])' $at_signal
- done
- rm -f "$at_stop_file"
- at_first=:
- if test $at_jobs -ne 1 &&
- rm -f "$at_job_fifo" &&
- test -n "$at_job_group" &&
- ( mkfifo "$at_job_fifo" && trap 'exit 1' PIPE STOP TSTP ) 2>/dev/null
- then
- # FIFO job dispatcher.
- dnl Since we use job control, we need to propagate TSTP.
- dnl This handler need not be used for serial execution.
- dnl Again, we should stop all processes in the job groups, otherwise
- dnl the stopping will not be effective while one test group is running.
- dnl Apparently ksh does not honor the TSTP trap.
- dnl As a safety measure, not use the same variable names as in the
- dnl termination handlers above, one might get called during execution
- dnl of the other.
- trap 'at_pids=
- for at_pid in `jobs -p`; do
- at_pids="$at_pids $at_job_group$at_pid"
- done
- dnl Send it to all spawned jobs, ignoring those finished meanwhile.
- if test -n "$at_pids"; then
- dnl Unfortunately, ksh93 fork-bombs when we send TSTP, so send STOP
- dnl if this might be ksh (STOP prevents possible TSTP handlers inside
- dnl AT_CHECKs from running). Then stop ourselves.
- at_sig=TSTP
- test "${TMOUT+set}" = set && at_sig=STOP
- kill -$at_sig $at_pids 2>/dev/null
- fi
- kill -STOP $$
- dnl We got a CONT, so let's go again. Passing this to all processes
- dnl in the groups is necessary (because we stopped them), but it may
- dnl cause changed test semantics; e.g., a sleep will be interrupted.
- test -z "$at_pids" || kill -CONT $at_pids 2>/dev/null' TSTP
- echo
- # Turn jobs into a list of numbers, starting from 1.
- at_joblist=`AS_ECHO(["$at_groups"]) | sed -n 1,${at_jobs}p`
- set X $at_joblist
- shift
- for at_group in $at_groups; do
- dnl Enable job control only for spawning the test group:
- dnl Let the jobs to run in separate process groups, but
- dnl avoid all the status output by the shell.
- $at_job_control_on 2>/dev/null
- (
- # Start one test group.
- $at_job_control_off
- dnl First child must open the fifo to avoid blocking parent; all other
- dnl children inherit it already opened from the parent.
- if $at_first; then
- exec AT_JOB_FIFO_OUT_FD>"$at_job_fifo"
- else
- dnl Children do not need parent's copy of fifo.
- exec AT_JOB_FIFO_IN_FD<&-
- fi
- dnl When a child receives PIPE, be sure to write back the token,
- dnl so the master does not hang waiting for it.
- dnl errexit and xtrace should not be set in this shell instance,
- dnl except as debug measures. However, shells such as dash may
- dnl optimize away the _AT_CHECK subshell, so normalize here.
- trap 'set +x; set +e
- dnl Ignore PIPE signals that stem from writing back the token.
- trap "" PIPE
- echo stop > "$at_stop_file"
- echo >&AT_JOB_FIFO_OUT_FD
- dnl Do not reraise the default PIPE handler.
- dnl It wreaks havoc with ksh, see above.
- dnl trap - 13
- dnl kill -13 $$
- AS_EXIT([141])' PIPE
- at_fn_group_prepare
- if cd "$at_group_dir" &&
- at_fn_test $at_group &&
- . "$at_test_source"
- then :; else
- AS_WARN([unable to parse test group: $at_group])
- at_failed=:
- fi
- at_fn_group_postprocess
- echo >&AT_JOB_FIFO_OUT_FD
- ) &
- $at_job_control_off
- if $at_first; then
- at_first=false
- exec AT_JOB_FIFO_IN_FD<"$at_job_fifo" AT_JOB_FIFO_OUT_FD>"$at_job_fifo"
- fi
- shift # Consume one token.
- if test $[@%:@] -gt 0; then :; else
- read at_token <&AT_JOB_FIFO_IN_FD || break
- set x $[*]
- fi
- test -f "$at_stop_file" && break
- done
- exec AT_JOB_FIFO_OUT_FD>&-
- # Read back the remaining ($at_jobs - 1) tokens.
- set X $at_joblist
- shift
- if test $[@%:@] -gt 0; then
- shift
- for at_job
- do
- read at_token
- done <&AT_JOB_FIFO_IN_FD
- fi
- exec AT_JOB_FIFO_IN_FD<&-
- wait
- else
- # Run serially, avoid forks and other potential surprises.
- for at_group in $at_groups; do
- at_fn_group_prepare
- if cd "$at_group_dir" &&
- at_fn_test $at_group &&
- . "$at_test_source"; then :; else
- AS_WARN([unable to parse test group: $at_group])
- at_failed=:
- fi
- at_fn_group_postprocess
- test -f "$at_stop_file" && break
- at_first=false
- done
- fi
- # Wrap up the test suite with summary statistics.
- cd "$at_helper_dir"
- # Use ?..???? when the list must remain sorted, the faster * otherwise.
- at_pass_list=`for f in */pass; do echo $f; done | sed '/\*/d; s,/pass,,'`
- at_skip_list=`for f in */skip; do echo $f; done | sed '/\*/d; s,/skip,,'`
- at_xfail_list=`for f in */xfail; do echo $f; done | sed '/\*/d; s,/xfail,,'`
- at_xpass_list=`for f in ?/xpass ??/xpass ???/xpass ????/xpass; do
- echo $f; done | sed '/?/d; s,/xpass,,'`
- at_fail_list=`for f in ?/fail ??/fail ???/fail ????/fail; do
- echo $f; done | sed '/?/d; s,/fail,,'`
- set X $at_pass_list $at_xpass_list $at_xfail_list $at_fail_list $at_skip_list
- shift; at_group_count=$[@%:@]
- set X $at_xpass_list; shift; at_xpass_count=$[@%:@]; at_xpass_list=$[*]
- set X $at_xfail_list; shift; at_xfail_count=$[@%:@]
- set X $at_fail_list; shift; at_fail_count=$[@%:@]; at_fail_list=$[*]
- set X $at_skip_list; shift; at_skip_count=$[@%:@]
- AS_VAR_ARITH([at_run_count], [$at_group_count - $at_skip_count])
- AS_VAR_ARITH([at_unexpected_count], [$at_xpass_count + $at_fail_count])
- AS_VAR_ARITH([at_total_fail_count], [$at_xfail_count + $at_fail_count])
- # Back to the top directory.
- cd "$at_dir"
- rm -rf "$at_helper_dir"
- # Compute the duration of the suite.
- at_stop_date=`date`
- at_stop_time=`date +%s 2>/dev/null`
- AS_ECHO(["$as_me: ending at: $at_stop_date"]) >&AS_MESSAGE_LOG_FD
- case $at_start_time,$at_stop_time in
- [[0-9]*,[0-9]*])
- AS_VAR_ARITH([at_duration_s], [$at_stop_time - $at_start_time])
- AS_VAR_ARITH([at_duration_m], [$at_duration_s / 60])
- AS_VAR_ARITH([at_duration_h], [$at_duration_m / 60])
- AS_VAR_ARITH([at_duration_s], [$at_duration_s % 60])
- AS_VAR_ARITH([at_duration_m], [$at_duration_m % 60])
- at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s"
- AS_ECHO(["$as_me: test suite duration: $at_duration"]) >&AS_MESSAGE_LOG_FD
- ;;
- esac
- echo
- AS_BOX([Test results.])
- echo
- {
- echo
- AS_BOX([Test results.])
- echo
- } >&AS_MESSAGE_LOG_FD
- dnl
- dnl FIXME: this code is as far from i18n-cleanness as man
- dnl could imagine...
- dnl
- if test $at_run_count = 1; then
- at_result="1 test"
- at_were=was
- else
- at_result="$at_run_count tests"
- at_were=were
- fi
- if $at_errexit_p && test $at_unexpected_count != 0; then
- if test $at_xpass_count = 1; then
- at_result="$at_result $at_were run, one passed"
- else
- at_result="$at_result $at_were run, one failed"
- fi
- at_result="$at_result unexpectedly and inhibited subsequent tests."
- at_color=$at_red
- else
- # Don't you just love exponential explosion of the number of cases?
- at_color=$at_red
- case $at_xpass_count:$at_fail_count:$at_xfail_count in
- # So far, so good.
- 0:0:0) at_result="$at_result $at_were successful." at_color=$at_grn ;;
- 0:0:*) at_result="$at_result behaved as expected." at_color=$at_lgn ;;
- # Some unexpected failures
- 0:*:0) at_result="$at_result $at_were run,
- $at_fail_count failed unexpectedly." ;;
- # Some failures, both expected and unexpected
- 0:*:1) at_result="$at_result $at_were run,
- $at_total_fail_count failed ($at_xfail_count expected failure)." ;;
- 0:*:*) at_result="$at_result $at_were run,
- $at_total_fail_count failed ($at_xfail_count expected failures)." ;;
- # No unexpected failures, but some xpasses
- *:0:*) at_result="$at_result $at_were run,
- $at_xpass_count passed unexpectedly." ;;
- # No expected failures, but failures and xpasses
- *:1:0) at_result="$at_result $at_were run,
- $at_unexpected_count did not behave as expected dnl
- ($at_fail_count unexpected failure)." ;;
- *:*:0) at_result="$at_result $at_were run,
- $at_unexpected_count did not behave as expected dnl
- ($at_fail_count unexpected failures)." ;;
- # All of them.
- *:*:1) at_result="$at_result $at_were run,
- $at_xpass_count passed unexpectedly,
- $at_total_fail_count failed ($at_xfail_count expected failure)." ;;
- *:*:*) at_result="$at_result $at_were run,
- $at_xpass_count passed unexpectedly,
- $at_total_fail_count failed ($at_xfail_count expected failures)." ;;
- esac
- if test $at_skip_count = 0 && test $at_run_count -gt 1; then
- at_result="All $at_result"
- fi
- fi
- # Now put skips in the mix.
- case $at_skip_count in
- 0) ;;
- 1) at_result="$at_result
- 1 test was skipped." ;;
- *) at_result="$at_result
- $at_skip_count tests were skipped." ;;
- esac
- if test $at_unexpected_count = 0; then
- echo "$at_color$at_result$at_std"
- echo "$at_result" >&AS_MESSAGE_LOG_FD
- else
- echo "${at_color}ERROR: $at_result$at_std" >&2
- echo "ERROR: $at_result" >&AS_MESSAGE_LOG_FD
- {
- echo
- AS_BOX([Summary of the failures.])
- # Summary of failed and skipped tests.
- if test $at_fail_count != 0; then
- echo "Failed tests:"
- $SHELL "$at_myself" $at_fail_list --list
- echo
- fi
- if test $at_skip_count != 0; then
- echo "Skipped tests:"
- $SHELL "$at_myself" $at_skip_list --list
- echo
- fi
- if test $at_xpass_count != 0; then
- echo "Unexpected passes:"
- $SHELL "$at_myself" $at_xpass_list --list
- echo
- fi
- if test $at_fail_count != 0; then
- AS_BOX([Detailed failed tests.])
- echo
- for at_group in $at_fail_list
- do
- at_group_normalized=$at_group
- _AT_NORMALIZE_TEST_GROUP_NUMBER(at_group_normalized)
- cat "$at_suite_dir/$at_group_normalized/$as_me.log"
- echo
- done
- echo
- fi
- if test -n "$at_top_srcdir"; then
- AS_BOX([${at_top_build_prefix}config.log])
- sed 's/^/| /' ${at_top_build_prefix}config.log
- echo
- fi
- } >&AS_MESSAGE_LOG_FD
- AS_BOX([$as_me.log was created.])
- echo
- if $at_debug_p; then
- at_msg='per-test log files'
- else
- at_msg="\`${at_testdir+${at_testdir}/}$as_me.log'"
- fi
- AS_ECHO(["Please send $at_msg and all information you think might help:
- To: <AT_PACKAGE_BUGREPORT>
- Subject: @<:@AT_PACKAGE_STRING@:>@ $as_me: dnl
- $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}dnl
- $at_xpass_list${at_xpass_list:+ passed unexpectedly}
- You may investigate any problem if you feel able to do so, in which
- case the test suite provides a good starting point. Its output may
- be found below \`${at_testdir+${at_testdir}/}$as_me.dir'.
- "])
- exit 1
- fi
- exit 0
- m4_text_box([Actual tests.])
- m4_divert_pop([TESTS])dnl
- dnl End of AT_INIT: divert to KILL, only test groups are to be
- dnl output, the rest is ignored. Current diversion is BODY, inherited
- dnl from M4sh.
- m4_divert([KILL])
- ])# AT_INIT
- # _AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ARGS],[ACTION-IF-GIVEN],
- # [ACTION-IF-NOT-GIVEN])
- # ----------------------------------------------------------
- # Internal implementation of AT_ARG_OPTION & AT_ARG_OPTION_ARG
- m4_defun([_AT_ARG_OPTION],
- [m4_divert_once([HELP_OTHER],
- [cat <<_ATEOF || at_write_fail=1
- Other options:
- _ATEOF
- ])dnl m4_divert_once HELP_OTHER
- m4_divert_text([HELP_OTHER],
- [cat <<_ATEOF || at_write_fail=1
- $2
- _ATEOF])dnl
- dnl Turn our options into our desired strings
- m4_ifdef([AT_first_option],[m4_undefine([AT_first_option])])dnl
- m4_ifdef([AT_case],[m4_undefine([AT_case])])dnl
- m4_ifdef([AT_case_no],[m4_undefine([AT_case_no])])dnl
- m4_ifdef([AT_case_arg],[m4_undefine([AT_case_arg])])dnl
- m4_foreach([AT_option], m4_split(m4_normalize([$1]),[[ \|]+]),
- [m4_define_default([AT_first_option],AT_option)dnl
- m4_define_default([AT_first_option_tr],
- [m4_bpatsubst(m4_defn([AT_first_option]), -, [_])])dnl
- m4_append([AT_case],m4_if(m4_len(AT_option),1,[],[-])[-]AT_option, [ | ])dnl
- m4_append([AT_case_no],[--no-]AT_option, [ | ])dnl
- m4_append([AT_case_arg],
- m4_if(m4_len(AT_option),1,[],[-])[-]AT_option[=*], [ | ])dnl
- ])dnl m4_foreach AT_option
- dnl keep track so we or the user may process ACTION-IF-NOT-GIVEN
- m4_divert_once([PARSE_ARGS_BEGIN],
- [
- ##
- ## Set up package specific options.
- ##
- ])dnl
- m4_divert_text([PARSE_ARGS_BEGIN],
- [dnl Provide a default value for options without arguments.
- m4_ifvaln([$3],,[at_arg_[]AT_first_option_tr=false])dnl
- at_arg_given_[]AT_first_option_tr=false
- ])dnl m4_divert_text DEFAULTS
- m4_divert_text([PARSE_ARGS],
- [dnl Parse the options and args when necessary.
- m4_ifvaln([$3],
- [ AT_case )
- at_prev=--AT_first_option_tr
- ;;
- AT_case_arg )
- at_arg_[]AT_first_option_tr=$at_optarg
- at_arg_given_[]AT_first_option_tr=:
- $4
- ;;],
- [ AT_case )
- at_optarg=:
- at_arg_[]AT_first_option_tr=:
- at_arg_given_[]AT_first_option_tr=:
- m4_ifval([$4],[$4])[]dnl
- ;;
- AT_case_no )
- at_optarg=false
- at_arg_[]AT_first_option_tr=false
- at_arg_given_[]AT_first_option_tr=:
- m4_ifval([$4],[$4])[]dnl
- ;;])dnl m4_ifvaln $3
- ])dnl m4_divert_text PARSE_ARGS
- m4_ifvaln([$5],
- [m4_divert_once([PARSE_ARGS_END],
- [
- ##
- ## Process package specific options when _not_ supplied.
- ##])dnl m4_divert_once PARSE_ARGS_END
- m4_divert_text([PARSE_ARGS_END],
- [
- AS_IF([$at_arg_given_[]AT_first_option_tr],,[$5])dnl
- ])dnl m4_divert_text PARSE_ARGS_END
- ])dnl m4_ifvaln $5
- ])dnl _AT_ARG_OPTION
- # AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
- # ------------------------------------------------------------------------
- # Accept a list of space-separated OPTIONS, all aliases of the first one.
- # Add HELP-TEXT to the HELP_OTHER diversion.
- #
- # Leading dashes should not be passed in OPTIONS. Users will be required
- # to pass `--' before long options and `-' before single character options.
- #
- # $at_arg_OPTION will be set to `:' if this option is received, `false' if
- # if --no-OPTION is received, and `false' by default.
- #
- # Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered; here,
- # $at_optarg will be set to `:' or `false' as appropriate. $at_optarg is
- # actually just a copy of $at_arg_OPTION.
- #
- # ACTION-IF-NOT-GIVEN will be run once after option parsing is complete and
- # if no option from OPTIONS was used.
- m4_defun([AT_ARG_OPTION],[_AT_ARG_OPTION([$1],[$2],,[$3],[$4])])
- # AT_ARG_OPTION_ARG(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
- # ----------------------------------------------------------------------------
- # Accept a set of space-separated OPTIONS with arguments, all aliases of the
- # first one. Add HELP-TEXT to the HELP_OTHER diversion.
- #
- # Leading dashes should not be passed in OPTIONS. Users will be required
- # to pass `--' before long options and `-' before single character options.
- #
- # By default, any argument to these options will be assigned to the shell
- # variable $at_arg_OPTION, where OPTION is the first option in OPTIONS with
- # any `-' characters replaced with `_'.
- #
- # Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered; here,
- # $at_optarg will be set to the option argument. $at_optarg is actually just
- # a copy of $at_arg_OPTION.
- #
- # ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
- # and if no option from OPTIONS was used.
- m4_defun([AT_ARG_OPTION_ARG],[_AT_ARG_OPTION([$1],[$2],1,[$3],[$4])])
- # AT_TESTED(PROGRAMS)
- # -------------------
- # Specify the list of programs exercised by the test suite. Their
- # versions are logged, and in the case of embedded test suite, they
- # must correspond to the version of the package. PATH should be
- # already preset so the proper executable will be selected.
- m4_define([AT_TESTED],
- [m4_append_uniq_w([AT_tested], [$1])])
- # AT_COPYRIGHT(TEXT, [FILTER = m4_newline])
- # -----------------------------------------
- # Emit TEXT, a copyright notice, in the top of the test suite and in
- # --version output. Macros in TEXT are evaluated once. Process
- # the --version output through FILTER (m4_newline, m4_do, and
- # m4_copyright_condense are common filters).
- m4_define([AT_COPYRIGHT],
- [AS_COPYRIGHT([$1])[]]dnl
- [m4_divert_text([VERSION_NOTICES],
- [m4_default([$2], [m4_newline])([$1])])])# AT_COPYRIGHT
- # AT_COLOR_TESTS
- # --------------
- # Enable colored test results if standard error is connected to a terminal.
- m4_define([AT_COLOR_TESTS],
- [m4_define([AT_color], [auto])])
- # AT_SETUP(DESCRIPTION)
- # ---------------------
- # Start a group of related tests, all to be executed in the same subshell.
- # The group is testing what DESCRIPTION says.
- _AT_DEFINE_INIT([AT_SETUP],
- [m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])],
- [m4_define([AT_ingroup], [AS_ECHO(["$at_setup_line"]) >"$at_check_line_file"
- ])])
- m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])])
- m4_define([AT_capture_files], [])
- m4_define([AT_line], AT_LINE)
- m4_define([AT_xfail], [at_xfail=no])
- m4_define([AT_description], m4_expand([$1]))
- m4_define([AT_ordinal], m4_incr(AT_ordinal))
- m4_divert_push([TEST_GROUPS])dnl
- [#AT_START_]AT_ordinal
- at_fn_group_banner AT_ordinal 'm4_defn([AT_line])' \
- "AS_ESCAPE(m4_dquote(m4_defn([AT_description])))" m4_format(["%*s"],
- m4_max(0, m4_eval(47 - m4_qlen(m4_defn([AT_description])))), [])m4_if(
- AT_banner_ordinal, [0], [], [ AT_banner_ordinal])
- m4_divert_push([TEST_SCRIPT])dnl
- ])
- # AT_FAIL_IF(SHELL-EXPRESSION)
- # ----------------------------
- # Make the test die with hard failure if SHELL-EXPRESSION evaluates to
- # true (exitcode = 0).
- _AT_DEFINE_SETUP([AT_FAIL_IF],
- [dnl
- dnl Try to limit the amount of conditionals that we emit.
- m4_case([$1],
- [], [],
- [false], [],
- [:], [_AT_CHECK_EXIT([], [99])],
- [true], [_AT_CHECK_EXIT([], [99])],
- [_AT_CHECK_EXIT([$1], [99])])])
- # AT_SKIP_IF(SHELL-EXPRESSION)
- # ----------------------------
- # Skip the rest of the group if SHELL-EXPRESSION evaluates to true
- # (exitcode = 0).
- _AT_DEFINE_SETUP([AT_SKIP_IF],
- [dnl
- dnl Try to limit the amount of conditionals that we emit.
- m4_case([$1],
- [], [],
- [false], [],
- [:], [_AT_CHECK_EXIT([], [77])],
- [true], [_AT_CHECK_EXIT([], [77])],
- [_AT_CHECK_EXIT([$1], [77])])])
- # AT_XFAIL_IF(SHELL-EXPRESSION)
- # -----------------------------
- # Set up the test to be expected to fail if SHELL-EXPRESSION evaluates to
- # true (exitcode = 0).
- _AT_DEFINE_SETUP([AT_XFAIL_IF],
- [dnl
- dnl Try to limit the amount of conditionals that we emit.
- m4_case([$1],
- [], [],
- [false], [],
- [:], [m4_define([AT_xfail], [at_xfail=yes])],
- [true], [m4_define([AT_xfail], [at_xfail=yes])],
- [m4_append([AT_xfail], [
- $1 && at_xfail=yes])])])
- # AT_KEYWORDS(KEYWORDS)
- # ---------------------
- # Declare a list of keywords associated to the current test group.
- # Since the -k option is case-insensitive, the list is stored in lower case
- # to avoid duplicates that differ only by case.
- _AT_DEFINE_SETUP([AT_KEYWORDS],
- [m4_append_uniq_w([AT_keywords], m4_tolower(_m4_expand([$1
- ])))])
- # AT_CAPTURE_FILE(FILE)
- # ---------------------
- # If the current test group does not behave as expected, save the contents of
- # FILE in the test suite log.
- _AT_DEFINE_SETUP([AT_CAPTURE_FILE],
- [m4_append_uniq([AT_capture_files], ["$1"], [ \
- ])])
- # AT_CLEANUP
- # ----------
- # Complete a group of related tests.
- _AT_DEFINE_INIT([AT_CLEANUP],
- [m4_ifdef([AT_ingroup], [AT_ingroup[]_m4_undefine([AT_ingroup])],
- [m4_fatal([$0: missing AT_SETUP detected])])dnl
- m4_append([AT_help_all],
- m4_defn([AT_ordinal]);m4_defn([AT_line]);m4_defn([AT_description]);dnl
- m4_ifdef([AT_keywords], [m4_defn([AT_keywords])]);
- )dnl
- m4_divert_pop([TEST_SCRIPT])dnl Back to TEST_GROUPS
- AT_xfail
- (
- AS_ECHO(["AT_ordinal. $at_setup_line: testing $at_desc ..."])
- $at_traceon
- m4_undivert([TEST_SCRIPT])dnl Insert the code here
- set +x
- $at_times_p && times >"$at_times_file"
- ) AS_MESSAGE_LOG_FD>&1 2>&1 AT_JOB_FIFO_OUT_FD>&- | eval $at_tee_pipe
- read at_status <"$at_status_file"
- [#AT_STOP_]AT_ordinal
- m4_divert_pop([TEST_GROUPS])dnl Back to KILL.
- ])# AT_CLEANUP
- # AT_BANNER([TEXT])
- # -----------------
- # Start a category of related test groups. If multiple groups are executed,
- # output TEXT as a banner without any shell expansion, prior to any test
- # from the category. If TEXT is empty, no banner is printed.
- _AT_DEFINE_INIT([AT_BANNER],
- [m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])])dnl
- m4_define([AT_banner_ordinal], m4_incr(AT_banner_ordinal))
- m4_divert_text([BANNERS],
- [@%:@ Banner AT_banner_ordinal. AT_LINE
- @%:@ Category starts at test group m4_incr(AT_ordinal).
- at_banner_text_[]AT_banner_ordinal="AS_ESCAPE([$1])"])dnl
- ])# AT_BANNER
- # AT_DATA(FILE, CONTENTS)
- # -----------------------
- # Initialize an input data FILE with given CONTENTS, which should be
- # empty or end with a newline.
- # This macro is not robust to active symbols in CONTENTS *on purpose*.
- # If you don't want CONTENTS to be evaluated, quote it twice.
- _AT_DEFINE_SETUP([AT_DATA],
- [m4_if([$2], [], [: >$1],
- [$2], [[]], [: >$1],
- [cat >$1 <<'_ATEOF'
- $2[]_ATEOF
- ])])
- # AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,
- # [RUN-IF-FAIL], [RUN-IF-PASS])
- # ------------------------------------------------
- # Execute a test by performing given shell COMMANDS. These commands
- # should normally exit with STATUS, while producing expected STDOUT and
- # STDERR contents. Shell metacharacters in STDOUT and STDERR are
- # _not_ processed by the shell, but are treated as string literals.
- #
- # STATUS, STDOUT, and STDERR are not checked if equal to `ignore'.
- #
- # If STDOUT is `expout', then stdout is compared to the content of the file
- # `expout'. Likewise for STDERR and `experr'.
- #
- # If STDOUT is `stdout', then the stdout is left in the file `stdout',
- # likewise for STDERR and `stderr'. Don't do this:
- #
- # AT_CHECK([command >out])
- # # Some checks on `out'
- #
- # do this instead:
- #
- # AT_CHECK([command], [], [stdout])
- # # Some checks on `stdout'
- #
- # You might wonder why you can't just use `ignore', then directly use stdout
- # and stderr left by the test suite:
- #
- # AT_CHECK([command], [], [ignore])
- # AT_CHECK([check stdout])
- #
- # If the test suite always captured data in the file `stdout', then the
- # second command would be trying to read and write from the same file, with
- # undefined behavior. Therefore, the test suite actually captures data in
- # an internal file of a different name, and only creates `stdout' when
- # explicitly requested.
- #
- # Any line of stderr starting with leading blanks and a `+' are filtered
- # out, since most shells when tracing include subshell traces in stderr.
- # This may cause spurious failures when the test suite is run with `-x'.
- #
- _AT_DEFINE_SETUP([AT_CHECK],
- [_AT_CHECK(m4_expand([$1]), [$2], AS_ESCAPE(m4_dquote(m4_expand([$3]))),
- AS_ESCAPE(m4_dquote(m4_expand([$4]))), [$5], [$6])])
- # AT_CHECK_UNQUOTED(COMMANDS, [STATUS = 0], STDOUT, STDERR,
- # [RUN-IF-FAIL], [RUN-IF-PASS])
- # ---------------------------------------------------------
- # Like AT_CHECK, but do not AS_ESCAPE shell metacharacters in the STDOUT
- # and STDERR arguments before running the comparison.
- _AT_DEFINE_SETUP([AT_CHECK_UNQUOTED],
- [_AT_CHECK(m4_expand([$1]), [$2], AS_ESCAPE(m4_dquote(m4_expand([$3])), [""]),
- AS_ESCAPE(m4_dquote(m4_expand([$4])), [""]), [$5], [$6])])
- # AT_CHECK_NOESCAPE(COMMANDS, [STATUS = 0], STDOUT, STDERR,
- # [RUN-IF-FAIL], [RUN-IF-PASS])
- # ---------------------------------------------------------
- # Obsolete spelling of AT_CHECK_UNQUOTED.
- m4_define([AT_CHECK_NOESCAPE],
- [m4_warn([obsolete], [consider using AT_CHECK_UNQUOTED instead of $0])]dnl
- [_AT_CHECK(m4_expand([$1]), [$2], m4_expand([$3]),
- m4_expand([$4]), [$5], [$6])])
- # _AT_DECIDE_TRACEABLE(COMMANDS)
- # ------------------------------
- # Worker for _AT_CHECK that expands to shell code. If COMMANDS are safe to
- # trace with `set -x', the shell code will evaluate to true. Otherwise,
- # the shell code will print a message stating an aspect of COMMANDS that makes
- # tracing them unsafe, and evaluate to false.
- #
- # Tracing COMMANDS is not safe if they contain a command that spans multiple
- # lines. When the test suite user passes `-x' or `--trace', the test suite
- # precedes every command with a `set -x'. Since most tests expect a specific
- # stderr, if only to confirm that it is empty, the test suite filters ^+ from
- # the captured stderr before comparing with the expected stderr. If a command
- # spans multiple lines, so will its trace, but a `+' only prefixes the first
- # line of that trace:
- #
- # $ echo 'foo
- # bar'
- # => stdout
- # foo
- # bar
- # => stderr
- # + foo
- # bar
- #
- # In a subset of cases, one could filter such extended shell traces from
- # stderr. Since test commands spanning several lines are rare, I chose
- # instead to simply not trace COMMANDS that could yield multiple trace lines.
- # Distinguishing such COMMANDS became the task at hand.
- #
- # These features may cause a shell command to span multiple lines:
- #
- # (a) A quoted literal newline.
- # Example:
- # echo foo'
- # 'bar
- # M4 is a hostile language for the job of parsing COMMANDS to determine whether
- # each literal newline is quoted, so we simply disable tracing for all COMMANDS
- # that bear literal newlines.
- #
- # (b) A command substitution not subject to word splitting.
- # Example:
- # var=$(printf 'foo\nbar')
- # Example:
- # echo "`printf 'foo\\nbar`"
- # One cannot know in general the number of lines a command substitution will
- # yield without executing the substituted command. As such, we disable tracing
- # for all COMMANDS containing these constructs.
- #
- # (c) A parameter expansion not subject to word splitting.
- # Example:
- # var=foo'
- # 'bar
- # echo "$var"
- # Parameter expansions appear in COMMANDS with much greater frequency than do
- # newlines and command substitutions, so disabling tracing for all such
- # COMMANDS would much more substantially devalue `testsuite -x'. To determine
- # which parameter expansions yield multiple lines, we escape all ``', `"',
- # and `\' in a copy of COMMANDS and expand that string within double quotes
- # at runtime. If the result of that expansion contains multiple lines, the
- # test suite disables tracing for the command in question.
- #
- # This method leads the test suite to expand some parameters that the shell
- # itself will never expand due to single-quotes or backslash escapes. This is
- # not a problem for `$foo' expansions, which will simply yield the empty string
- # or some unrelated value. A `${...}' expansion could actually form invalid
- # shell code, however; consider `${=foo}'. Therefore, we disable tracing for
- # all COMMANDS containing `${...}'. This affects few COMMANDS.
- #
- # This macro falls in a very hot path; the Autoconf test suite expands it 1640
- # times as of this writing. To give a sense of the impact of the heuristics I
- # just described, the test suite preemptively disables tracing for 31 of those,
- # and 268 contain parameter expansions that require runtime evaluation. The
- # balance are always safe to trace.
- m4_define([_AT_DECIDE_TRACEABLE],
- dnl Utility macro.
- dnl
- dnl Examine COMMANDS for a reason to never trace COMMANDS.
- [m4_pushdef([at_reason],
- m4_cond([m4_eval(m4_index([$1], [`]) >= 0)], [1],
- [[a `...` command substitution]],
- [m4_eval(m4_index([$1], [$(]) >= 0)], [1],
- [[a $(...) command substitution]],
- [m4_eval(m4_index([$1], [${]) >= 0)], [1],
- [[a ${...} parameter expansion]],
- [m4_eval(m4_index([$1], m4_newline) >= 0)], [1],
- [[an embedded newline]],
- [m4_eval(m4_bregexp([$1], [[^|]|[^|]]) >= 0)], [1],
- [[a shell pipeline]],
- []))]dnl No reason.
- [m4_if(m4_index(_m4_defn([at_reason]), [a]), [0],]dnl
- dnl We know at build time that tracing COMMANDS is never safe.
- [[at_fn_check_prepare_notrace '_m4_defn([at_reason])'],
- m4_index([$1], [$]), [-1],]dnl
- dnl We know at build time that tracing COMMANDS is always safe.
- [[at_fn_check_prepare_trace],]dnl
- dnl COMMANDS may contain parameter expansions; expand them at runtime.
- [[at_fn_check_prepare_dynamic "AS_ESCAPE([[$1]], [`\"])"])[]]dnl
- [_m4_popdef([at_reason])])
- # AT_DIFF_STDERR/AT_DIFF_STDOUT
- # -----------------------------
- # These are subroutines of AT_CHECK. Using indirect dispatch is a tad
- # faster than using m4_case, and these are called very frequently.
- m4_define([AT_DIFF_STDERR(stderr)],
- [echo stderr:; tee stderr <"$at_stderr"])
- m4_define([AT_DIFF_STDERR(stderr-nolog)],
- [echo stderr captured; cp "$at_stderr" stderr])
- m4_define([AT_DIFF_STDERR(ignore)],
- [echo stderr:; cat "$at_stderr"])
- m4_define([AT_DIFF_STDERR(ignore-nolog)])
- m4_define([AT_DIFF_STDERR(experr)],
- [$at_diff experr "$at_stderr" || at_failed=:])
- m4_define([AT_DIFF_STDERR()],
- [at_fn_diff_devnull "$at_stderr" || at_failed=:])
- m4_define([AT_DIFF_STDOUT(stdout)],
- [echo stdout:; tee stdout <"$at_stdout"])
- m4_define([AT_DIFF_STDOUT(stdout-nolog)],
- [echo stdout captured; cp "$at_stdout" stdout])
- m4_define([AT_DIFF_STDOUT(ignore)],
- [echo stdout:; cat "$at_stdout"])
- m4_define([AT_DIFF_STDOUT(ignore-nolog)])
- m4_define([AT_DIFF_STDOUT(expout)],
- [$at_diff expout "$at_stdout" || at_failed=:])
- m4_define([AT_DIFF_STDOUT()],
- [at_fn_diff_devnull "$at_stdout" || at_failed=:])
- # _AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,
- # [RUN-IF-FAIL], [RUN-IF-PASS])
- # -------------------------------------------------
- # Worker for AT_CHECK and AT_CHECK_UNQUOTED, with COMMANDS, STDOUT, and
- # STDERR pre-expanded.
- #
- # Implementation Details
- # ----------------------
- # Ideally, we would like to run
- #
- # ( $at_traceon; COMMANDS >at-stdout 2> at-stderr )
- #
- # but we must group COMMANDS as it is not limited to a single command, and
- # then the shells will save the traces in at-stderr. So we have to filter
- # them out when checking stderr, and we must send them into the test suite's
- # stderr to honor -x properly. Since only the first line of the trace of a
- # multiline command starts with a `+', and I know of no straightforward way to
- # filter out the unadorned trace lines, we disable shell tracing entirely for
- # commands that could span multiple lines.
- #
- # Limiting COMMANDS to a single command is not good either, since then
- # the user herself would use {} or (), and then we face the same problem.
- #
- # But then, there is no point in running
- #
- # ( $at_traceon { $1 ; } >at-stdout 2>at-stder1 )
- #
- # instead of the simpler
- #
- # ( $at_traceon; $1 ) >at-stdout 2>at-stder1
- #
- # Note that we truncate and append to the output files, to avoid losing
- # output from multiple concurrent processes, e.g., an inner testsuite
- # with parallel jobs.
- m4_define([_AT_CHECK],
- [m4_define([AT_ingroup])]dnl
- [{ set +x
- AS_ECHO(["$at_srcdir/AT_LINE: AS_ESCAPE([[$1]])"])
- _AT_DECIDE_TRACEABLE([$1]) _AT_LINE_ESCAPED
- ( $at_check_trace; [$1]
- ) >>"$at_stdout" 2>>"$at_stderr" AS_MESSAGE_LOG_FD>&-
- at_status=$? at_failed=false
- $at_check_filter
- m4_ifdef([AT_DIFF_STDERR($4)], [m4_indir([AT_DIFF_STDERR($4)])],
- [echo >>"$at_stderr"; AS_ECHO([["$4"]]) | \
- $at_diff - "$at_stderr" || at_failed=:])
- m4_ifdef([AT_DIFF_STDOUT($3)], [m4_indir([AT_DIFF_STDOUT($3)])],
- [echo >>"$at_stdout"; AS_ECHO([["$3"]]) | \
- $at_diff - "$at_stdout" || at_failed=:])
- m4_if([$2], [ignore], [at_fn_check_skip],
- [at_fn_check_status m4_default([$2], [0])]) $at_status "$at_srcdir/AT_LINE"
- m4_ifvaln([$5$6], [AS_IF($at_failed, [$5], [$6])])]dnl
- [$at_failed && at_fn_log_failure AT_capture_files
- $at_traceon; }
- ])# _AT_CHECK
- # _AT_CHECK_EXIT(COMMANDS, [EXIT-STATUS-IF-PASS])
- # -----------------------------------------------
- # Minimal version of _AT_CHECK for AT_SKIP_IF and AT_FAIL_IF.
- m4_define([_AT_CHECK_EXIT],
- [m4_define([AT_ingroup])]dnl
- [AS_ECHO(_AT_LINE_ESCAPED) >"$at_check_line_file"
- m4_ifval([$1], [($1) \
- && ])at_fn_check_skip $2 "$at_srcdir/AT_LINE"])# _AT_CHECK_EXIT
|