📄 general.m4
字号:
# 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([AT_tested], [$1], [])])# AT_COPYRIGHT(TEXT)# ------------------# Emit TEXT, a copyright notice, in the top of the test suite and in# --version output. Macros in TEXT are evaluated once.m4_define([AT_COPYRIGHT],[AS_COPYRIGHT([$1])[]dnlm4_divert_text([VERSION_NOTICES],[$1])])# AT_COPYRIGHT# AT_SETUP(DESCRIPTION)# ---------------------# Start a group of related tests, all to be executed in the same subshell.# The group is testing what DESCRIPTION says.m4_define([AT_SETUP],[m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])])m4_ifdef([AT_capture_files], [m4_undefine([AT_capture_files])])m4_define([AT_line], AT_LINE)m4_define([AT_xfail], [at_xfail=no])m4_define([AT_description], [$1])m4_define([AT_ordinal], m4_incr(AT_ordinal))m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal]))m4_divert_push([TESTS])dnl AT_ordinal ) @%:@ AT_ordinal. m4_defn([AT_line]): $1 at_setup_line='m4_defn([AT_line])' at_desc='$1' $at_quiet $ECHO_N "m4_format([%3d: %-]m4_eval(47 - m4_qdelta([$1]))[s], AT_ordinal, [[$1]])[]$ECHO_C"m4_divert_push([TEST_SCRIPT])dnl])# AT_XFAIL_IF(SHELL-EXPRESSION)# -----------------------------# Set up the test to be expected to fail if SHELL-EXPRESSION evaluates to# true (exitcode = 0).m4_define([AT_XFAIL_IF],[dnldnl 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.m4_define([AT_KEYWORDS],[m4_append_uniq([AT_keywords], [$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.m4_define([AT_CAPTURE_FILE],[m4_append_uniq([AT_capture_files], ["$1"], [ \])])# AT_CLEANUP# ----------# Complete a group of related tests.m4_define([AT_CLEANUP],[m4_append([AT_help_all],m4_defn([AT_ordinal]);m4_defn([AT_line]);m4_defn([AT_description]);m4_ifdef([AT_keywords], [m4_defn([AT_keywords])]);)dnlm4_divert_pop([TEST_SCRIPT])dnl Back to TESTS AT_xfail echo "# -*- compilation -*-" >> "$at_group_log" ( echo "AT_ordinal. m4_defn([AT_line]): testing $1..." $at_traceonm4_undivert([TEST_SCRIPT])dnl Insert the code here $at_traceoff $at_times_p && times >"$at_times_file" ) AS_MESSAGE_LOG_FD>&1 2>&1 | eval $at_tee_pipe at_status=`cat "$at_status_file"` ;;m4_divert_pop([TESTS])dnl Back to KILL.])# AT_CLEANUP# AT_BANNER(TEXT)# ---------------# Output TEXT without any shell expansion.m4_define([AT_BANNER],[m4_define([AT_banner_ordinal], m4_incr(AT_banner_ordinal))m4_append([AT_groups_all], [ banner-]m4_defn([AT_banner_ordinal]))m4_divert_text([TESTS],[ banner-AT_banner_ordinal ) @%:@ Banner AT_banner_ordinal. AT_LINE cat <<\_ATEOF$1_ATEOF ;;])dnl])# AT_BANNER# AT_DATA(FILE, CONTENTS)# -----------------------# Initialize an input data FILE with given CONTENTS, which should end with# an end of line.# This macro is not robust to active symbols in CONTENTS *on purpose*.# If you don't want CONTENTS to be evaluated, quote it twice.m4_define([AT_DATA],[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'## This is an unfortunate limitation inherited from Ultrix which will not# let you redirect several times the same FD (see the Autoconf documentation).# If you use the `AT_CHECK([command >out])' be sure to get a test suite# that will show spurious failures.## You might wonder why not just use `ignore' and directly use stdout and# stderr left by the test suite. Firstly because the names of these files# is an internal detail, and secondly, because## AT_CHECK([command], [], [ignore])# AT_CHECK([check stdout])## will use `stdout' both in input and output: undefined behavior would# certainly result. That's why the test suite will save them in `at-stdout'# and `at-stderr', and will provide you with `stdout' and `stderr'.## 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'.#m4_define([AT_CHECK],[_AT_CHECK([$1],[$2],[$3],[$4],[$5],[$6],1)])# AT_CHECK_NOESCAPE(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.m4_define([AT_CHECK_NOESCAPE],[_AT_CHECK([$1],[$2],[$3],[$4],[$5],[$6])])# _AT_DECIDE_TRACEABLE(COMMANDS)# ------------------------------# Worker for for _AT_CHECK that expands to shell code. If COMMANDS are safe to# trace with `set -x', the shell code will set `at_trace_this=yes'. Otherwise,# the shell code will print a message stating an aspect of COMMANDS that makes# tracing them unsafe.## 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.## _AT_CHECK expands COMMANDS, but the Autoconf language does not provide a way# to safely expand arbitrary COMMANDS in an argument list, so the below tests# examine COMMANDS unexpanded.m4_define([_AT_DECIDE_TRACEABLE],[dnl Utility macros.m4_pushdef([at_lf], [])[]dnldnldnl Examine COMMANDS for a reason to never trace COMMANDS.m4_pushdef([at_reason], m4_bmatch([$1], [`.*`], [[a `...` command substitution]], [\$(], [[a $(...) command substitution]], [\${], [[a ${...} parameter expansion]], at_lf, [[an embedded newline]], [[]]dnl No reason.))dnldnlm4_ifval(m4_defn([at_reason]),[echo 'Not enabling shell tracing (command contains ]m4_defn([at_reason])[)'],[m4_bmatch([$1], [\$],dnl COMMANDS may contain parameter expansions; expand them at runtime.[case "AS_ESCAPE([$1], [`"\])" in *''*) echo 'Not enabling shell tracing (command contains an embedded newline)' ;; *) at_trace_this=yes ;; esac],dnl We know at build time that tracing COMMANDS is always safe.[at_trace_this=yes])])[]dnlm4_popdef([at_lf])[]dnlm4_popdef([at_reason])])# _AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR,# [RUN-IF-FAIL], [RUN-IF-PASS], SHELL_ESCAPE_IO)# ---------------------------------------------------------# Worker for AT_CHECK & AT_CHECK_NOESCAPE. The final SHELL-ESCAPE-IO# argument determines whether the STDOUT & STDERR arguments will be escaped or# not.### 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 them# 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#m4_define([_AT_CHECK],[$at_traceoffecho "$at_srcdir/AT_LINE: AS_ESCAPE([$1])"echo AT_LINE >"$at_check_line_file"at_trace_this=if test -n "$at_traceon"; then _AT_DECIDE_TRACEABLE([$1])fiif test -n "$at_trace_this"; then ( $at_traceon; $1 ) >"$at_stdout" 2>"$at_stder1" at_status=$? grep '^ *+' "$at_stder1" >&2 grep -v '^ *+' "$at_stder1" >"$at_stderr"else ( :; $1 ) >"$at_stdout" 2>"$at_stderr" at_status=$?fiat_failed=falsednl Check stderr.m4_case([$4], stderr, [echo stderr:; tee stderr <"$at_stderr"], ignore, [echo stderr:; cat "$at_stderr"], experr, [$at_diff experr "$at_stderr" || at_failed=:], [], [$at_diff "$at_devnull" "$at_stderr" || at_failed=:], [echo >>"$at_stderr"; echo "m4_ifval([$7],[AS_ESCAPE([$4])],[$4])" | $at_diff - "$at_stderr" || at_failed=:])dnl Check stdout.m4_case([$3], stdout, [echo stdout:; tee stdout <"$at_stdout"], ignore, [echo stdout:; cat "$at_stdout"], expout, [$at_diff expout "$at_stdout" || at_failed=:], [], [$at_diff "$at_devnull" "$at_stdout" || at_failed=:], [echo >>"$at_stdout"; echo "m4_ifval([$7],[AS_ESCAPE([$3])],[$3])" | $at_diff - "$at_stdout" || at_failed=:])dnl Check exit val. Don't `skip' if we are precisely checking $? = 77.case $at_status inm4_if([$2], [77], [], [ 77) echo 77 > "$at_status_file"; exit 77;;])dnlm4_if([$2], [ignore], [ *);;], [ m4_default([$2], [0])) ;; *) echo "$at_srcdir/AT_LINE: exit code was $at_status, expected m4_default([$2], [0])" at_failed=:;;])esacAS_IF($at_failed, [$5 m4_ifdef([AT_capture_files], [for file in AT_capture_files do echo "$file:"; sed 's/^/> /' "$file"; done]) echo 1 > "$at_status_file" exit 1], [$6])$at_traceon])# _AT_CHECK
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -