diff options
Diffstat (limited to '')
-rw-r--r-- | tests/Makefile.in | 257 | ||||
-rw-r--r-- | tests/README | 57 | ||||
-rw-r--r-- | tests/aclocal.m4 | 61 | ||||
-rw-r--r-- | tests/atconfig.in | 67 | ||||
-rw-r--r-- | tests/atgeneral.m4 | 567 | ||||
-rw-r--r-- | tests/atspecific.m4 | 185 | ||||
-rw-r--r-- | tests/base.at | 255 | ||||
-rw-r--r-- | tests/compile.at | 277 | ||||
-rw-r--r-- | tests/m4sh.at | 118 | ||||
-rw-r--r-- | tests/m4sugar.at | 139 | ||||
-rwxr-xr-x | tests/mktests.in | 230 | ||||
-rw-r--r-- | tests/semantics.at | 378 | ||||
-rw-r--r-- | tests/suite.at | 53 | ||||
-rw-r--r-- | tests/tools.at | 490 | ||||
-rw-r--r-- | tests/torture.at | 478 |
15 files changed, 3612 insertions, 0 deletions
diff --git a/tests/Makefile.in b/tests/Makefile.in new file mode 100644 index 0000000..c417f20 --- /dev/null +++ b/tests/Makefile.in @@ -0,0 +1,257 @@ +# Copyright 2010-2021,2023 Thomas E. Dickey +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +datarootdir = @datarootdir@ +datadir = @datadir@ + +DESTDIR = + +top_builddir = .. + +transform = @program_transform_name@ + +EXPR = @EXPR@ +M4 = @M4@ +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SUITE = suite.at \ + m4sugar.at \ + m4sh.at \ + base.at \ + tools.at \ + torture.at \ + compile.at \ + semantics.at \ + acgeneral.at \ + acspecific.at \ + acfunctions.at \ + aclang.at \ + acheaders.at \ + actypes.at + +EGREP = @EGREP@ +FGREP = @FGREP@ + +# We don't actually distribute the testsuite, since one only +# needs m4 to build it, m4 being required anyway to install Autoconf. +EXTRA_DIST = README atgeneral.m4 atspecific.m4 aclocal.m4 $(SUITE) mktests.sh + +# The files which contains macro we check for syntax. Don't use $(top_srcdir) +# here since below we explicitly `cd' to $srcdir. As for the dependencies, +# thanks God for VPATH. Hm... +MACRO_FILES = \ + ../acgeneral.m4 \ + ../acspecific.m4 \ + ../acfunctions.m4 \ + ../aclang.m4 \ + ../acheaders.m4 \ + ../actypes.m4 + +CLEANFILES = \ + debug-*.sh \ + macro \ + configure \ + configure.in \ + configure.ac \ + config.status \ + config.cache \ + config.log \ + config.h.in \ + config.h \ + config.hin \ + state-* \ + at-* \ + stderr \ + stdout \ + empty \ + config.guess \ + config.sub \ + expr \ + libtool \ + ltconfig \ + ltmain.sh \ + install-sh + +DISTCLEANFILES = atconfig testsuite +CONFIG_CLEAN_FILES = \ + atconfig \ + mktests.sh \ + acgeneral.at \ + acspecific.at \ + acfunctions.at \ + aclang.at \ + acheaders.at \ + actypes.at + +DIST_COMMON = README Makefile.am Makefile.in atconfig.in + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +atconfig: $(top_builddir)/config.status atconfig.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = tests + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check-local check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +check-local: atconfig testsuite + @echo "making $@" + @FGREP="$(FGREP)" EGREP="$(EGREP)" $(SHELL) testsuite + +testsuite: $(top_srcdir)/m4sugar.m4 $(top_srcdir)/m4sh.m4 \ + atgeneral.m4 atspecific.m4 \ + $(SUITE) + $(M4) -I $(srcdir) -I $(top_srcdir) atspecific.m4 suite.at | \ + sed -e 's/[ ]*$$//' | \ + sed -e '/^$$/N;/\n$$/D' >$@.tmp + chmod +x $@.tmp + mv $@.tmp $@ + +acgeneral.at: mktests.sh $(MACRO_FILES) + cd $(srcdir) && $(SHELL) ./mktests.sh $(MACRO_FILES) + +acspecific.at: mktests.sh $(MACRO_FILES) + cd $(srcdir) && $(SHELL) ./mktests.sh $(MACRO_FILES) + +acfunctions.at: mktests.sh $(MACRO_FILES) + cd $(srcdir) && $(SHELL) ./mktests.sh $(MACRO_FILES) + +aclang.at: mktests.sh $(MACRO_FILES) + cd $(srcdir) && $(SHELL) ./mktests.sh $(MACRO_FILES) + +acheaders.at: mktests.sh $(MACRO_FILES) + cd $(srcdir) && $(SHELL) ./mktests.sh $(MACRO_FILES) + +actypes.at: mktests.sh $(MACRO_FILES) + cd $(srcdir) && $(SHELL) ./mktests.sh $(MACRO_FILES) + +maintainer-check: maintainer-check-posix maintainer-check-c++ + +# The hairy heredoc is more robust than using echo. +expr: + echo '#! $(SHELL)' >expr + echo 'result=`@EXPR@ "$$@"`' >>expr + echo 'estatus=$$?' >>expr + echo 'cat <<EOF' >>expr + echo '$${result:-0}' >>expr + echo 'EOF' >>expr + echo 'exit $$estatus' >>expr + chmod +x expr + +# Try the test suite with more severe environments. +maintainer-check-posix: expr + POSIXLY_CORRECTLY=yes make check + rm expr + +# Try using G++ as a C compiler. +maintainer-check-c++: + CC=g++ make check + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..f0661c2 --- /dev/null +++ b/tests/README @@ -0,0 +1,57 @@ + -*- outline -*- + +This directory holds the M4sugar, M4sh and Autoconf test suites. + + +Here are a few rules on how to write tests. + +* Order of the tests + +It is extremely important to pay attention to the order of the tests. +There are basically two philosophies: (i) test earlier the most +critical features (hence hurried users will at least check those), or +(ii) test earlier the primitives. + +For having tried both, I definitely recommend (ii). In practice users +will run the whole test suite even if it's long. And if they don't, +there will be enough other users who will do the job. + +But also in practice some problems in the core of project can be +responsible for an incredible number of failures. Then the problems +at the origin will be hidden by the consequences. If dependencies are +properly ordered in the test suite (test features which depend upon +other features *after* having checked the latter), basically you'll +just have to pay attention to the first failures. BTW, it also makes +`./testsuite -e' much more useful. + + +* Write tests! + +Don't let you be bitten three times by the same dog! When you spent a +significant amount of time tracking the failure of feature in some +more primitive problem, immediately write a test for the latter. + +If you track down several bugs down to the same origin, write a test +especially for it. + +Of course in both cases, more primitive tests will be run beforehand. +Write your test and have it failed before your fixing, and succeeding +after. This usually means having at hand two copies of the source +tree, one running the test suite to have it fail, and the other to +have the same testsuite succeed. + + +* Autoconf + +** Use of `exit' +Don't directly `exit 1' or `exit 77', rather use `AC_MSG_ERROR'. +First of all because when we have to read the test suite logs we are +happy to know why `configure' exited thanks to the error +message. Secondly, because `configure' traps the `exit' and pretty +many shells fail to set $? to 77 when trapping `exit 77'. This +results in the test suite not being able to check the exit status. + +** AC_MSG_ERROR +Of course, since macro names are forbidden in `configure', if you +really want to mention the macro name, you'll have to do without +including `A?_' in the output. diff --git a/tests/aclocal.m4 b/tests/aclocal.m4 new file mode 100644 index 0000000..db41e8f --- /dev/null +++ b/tests/aclocal.m4 @@ -0,0 +1,61 @@ +# actest.m4 -*- autoconf -*- +# Additional Autoconf macros to ease testing. + +# AC_STATE_SAVE(FILE) +# ------------------ +# Save the environment, except for those variables we are allowed to touch. +# This is to check no test touches the user name space. +# FIXME: There are surely better ways. Explore for instance if +# we can ask help from AC_SUBST. We have the right to touch what +# is AC_SUBST'ed. +# - ^ac_ +# Autoconf's shell name space. +# - prefix and exec_prefix +# are kept undefined (NONE) until AC_OUTPUT which then sets them to +# `/usr/local' and `${prefix}' for make. +# - CONFIG_STATUS and DEFS +# Set by AC_OUTPUT. +# - F77_DUMMY_MAIN +# Set by AC_F77_DUMMY_MAIN. +# - ALLOCA|NEED_SETGID|KMEM_GROUP +# AC_FUNCs from acspecific. +# - AWK|LEX|LEXLIB|LEX_OUTPUT_ROOT|LN_S|M4|RANLIB|SET_MAKE|YACC +# AC_PROGs from acspecific +# - _|@|.[*#?].|LINENO|OLDPWD|PIPESTATUS|RANDOM|SECONDS +# Some variables some shells use and change. +# `.[*#?].' catches `$#' etc. which are displayed like this: +# | '!'=18186 +# | '#'=0 +# | '$'=6908 +# - POW_LIB +# From acfunctions.m4. +# +# Some `egrep' choke on such a big regex (e.g., SunOS 4.1.3). In this +# case just don't pay attention to the env. It would be great +# to keep the error message but we can't: that would break AT_CHECK. +m4_defun([AC_STATE_SAVE], +[(set) 2>&1 | + $EGREP -v -e 'm4_join([|], + [^a[cs]_], + [^((exec_)?prefix|DEFS|CONFIG_STATUS)=], + [^(CC|CFLAGS|CPP|GCC|CXX|CXXFLAGS|CXXCPP|GXX|F77|FFLAGS|FLIBS|G77)=], + [^(LIBS|LIBOBJS|LDFLAGS)=], + [^INSTALL(_(DATA|PROGRAM|SCRIPT))?=], + [^(CYGWIN|ISC|MINGW32|MINIX|EMXOS2|XENIX|EXEEXT|OBJEXT)=], + [^(X_(CFLAGS|(EXTRA_|PRE_)?LIBS)|x_(includes|libraries)|(have|no)_x)=], + [^(host|build|target)(_(alias|cpu|vendor|os))?=], + [^(cross_compiling)=], + [^(interpval|PATH_SEPARATOR)=], + [^(F77_DUMMY_MAIN|f77_(case|underscore))=], + [^(COLLECT_(GCC|GCC_OPTIONS|LTO_WRAPPER)|(COMPILER|LIBRARY)_PATH)=], + [^(ALLOCA|GETLOADAVG_LIBS|KMEM_GROUP|NEED_SETGID|POW_LIB)=], + [^(AWK|LEX|LEXLIB|LEX_OUTPUT_ROOT|LN_S|M4|RANLIB|SET_MAKE|YACC)=], + [^(GREP|EGREP|FGREP|ToD)=], + [^(_|@|.[*#?].|LINENO|OLDPWD|PIPESTATUS|RANDOM|SECONDS)=])' 2>/dev/null | + # There may be variables spread on several lines, eg IFS, remove the dead + # lines. + grep '^m4_defn([m4_re_word])=' >state-env.$1 +test $? = 0 || rm -f state-env.$1 + +ls -1 | $EGREP -v '^(at-|state-|config\.|conftest\.dSYM)' | sort >state-ls.$1 +])# AC_STATE_SAVE diff --git a/tests/atconfig.in b/tests/atconfig.in new file mode 100644 index 0000000..9c5b7c8 --- /dev/null +++ b/tests/atconfig.in @@ -0,0 +1,67 @@ +# -*- shell-script -*- +# @configure_input@ +# Configurable variable values for building test suites. +# Copyright 2000 Free Software Foundation, Inc. + +# 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 2, 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# This script is part of Autotest. Unlimited permission to copy, +# distribute and modify the testing scripts that are the output of +# that Autotest script is given. You need not follow the terms of the +# GNU General Public License when using or distributing such scripts, +# even though portions of the text of Autotest appear in them. The +# GNU General Public License (GPL) does govern all other use of the +# material that constitutes the Autotest. +# +# Certain portions of the Autotest source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# Autotest. We call these the "data" portions. The rest of the +# Autotest source text consists of comments plus executable code that +# decides which of the data portions to output in any given case. We +# call these comments and executable code the "non-data" portions. +# Autotest never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of Autotest +# released by the Free Software Foundation. When you make and +# distribute a modified version of Autotest, you may extend this +# special exception to the GPL to apply to your modified version as +# well, *unless* your modified version has the potential to copy into +# its output some of the text that was the non-data portion of the +# version that you started with. (In other words, unless your change +# moves or copies text from the non-data portions to the data +# portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified +# version. + +# This debugging script has been automatically generated from `make check'. +# Call it with `--help' to get a quick usage summary. + +at_package='@PACKAGE_NAME@' +at_version='@PACKAGE_VERSION@' +at_bugreport='@PACKAGE_BUGREPORT@' + +at_n='@ECHO_N@' +at_c='@ECHO_C@' + +srcdir='@srcdir@' +top_srcdir='@top_srcdir@' +AUTOTEST_PATH='@AUTOTEST_PATH@' + +SHELL=${CONFIG_SHELL-'@SHELL@'} +PATH_SEPARATOR='@PATH_SEPARATOR@' + +# We need GNU m4. +M4='@M4@' diff --git a/tests/atgeneral.m4 b/tests/atgeneral.m4 new file mode 100644 index 0000000..2097005 --- /dev/null +++ b/tests/atgeneral.m4 @@ -0,0 +1,567 @@ +include(m4sh.m4) -*- Autoconf -*- +# M4 macros used in building test suites. +# Copyright 2022,2023 Thomas E. Dickey +# Copyright 2000, 2001 Free Software Foundation, Inc. + +# 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 2, 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# This script is part of Autotest. Unlimited permission to copy, +# distribute and modify the testing scripts that are the output of +# that Autotest script is given. You need not follow the terms of the +# GNU General Public License when using or distributing such scripts, +# even though portions of the text of Autotest appear in them. The +# GNU General Public License (GPL) does govern all other use of the +# material that constitutes the Autotest. +# +# Certain portions of the Autotest source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# Autotest. We call these the "data" portions. The rest of the +# Autotest source text consists of comments plus executable code that +# decides which of the data portions to output in any given case. We +# call these comments and executable code the "non-data" portions. +# Autotest never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of Autotest +# released by the Free Software Foundation. When you make and +# distribute a modified version of Autotest, you may extend this +# special exception to the GPL to apply to your modified version as +# well, *unless* your modified version has the potential to copy into +# its output some of the text that was the non-data portion of the +# version that you started with. (In other words, unless your change +# moves or copies text from the non-data portions to the data +# portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified +# version. + + +# Use of diversions: +# +# - DEFAULT +# Overall initialization, value of $at_tests_all. +# - OPTIONS +# Option processing +# - HELP +# Help message. Of course it is useless, you could just push into +# OPTIONS, but that's much clearer this way. +# - SETUP +# Be ready to run the tests. +# - TESTS +# The core of the test suite, the ``normal'' diversion. +# - TAIL +# tail of the core for;case, overall wrap up, generation of debugging +# scripts and statistics. + +m4_define([_m4_divert(DEFAULT)], 0) +m4_define([_m4_divert(OPTIONS)], 10) +m4_define([_m4_divert(HELP)], 20) +m4_define([_m4_divert(SETUP)], 30) +m4_define([_m4_divert(TESTS)], 50) +m4_define([_m4_divert(TAIL)], 60) + +m4_divert_push([TESTS]) +m4_divert_push([KILL]) + + +# AT_LINE +# ------- +# Return the current file sans directory, a colon, and the current line. +m4_define([AT_LINE], +[m4_patsubst(__file__, ^.*/\(.*\), \1):__line__]) + + +# AT_INIT(PROGRAM) +# ---------------- +# Begin test suite, using PROGRAM to check version. The search path +# should be already preset so the proper executable will be selected. +m4_define([AT_INIT], +[m4_define([AT_ordinal], 0) +m4_define([AT_banner_ordinal], 0) +m4_define([AT_data_files], + [stdout expout at-setup-line at-check-line at-stdout stderr experr + at-stder1 at-stderr ]) +m4_divert_push([DEFAULT])dnl +#! /bin/sh + +AS_SHELL_SANITIZE +SHELL=${CONFIG_SHELL-/bin/sh} + +. ./atconfig +# Use absolute file notations, as the test might change directories. +at_srcdir=`cd "$srcdir" && pwd` +at_top_srcdir=`cd "$top_srcdir" && pwd` + +# Don't take risks: use absolute path names. +at_path=`pwd` +at_IFS_save=$IFS +IFS=$PATH_SEPARATOR +for at_dir in $AUTOTEST_PATH $PATH; do + # There might be directories that don't exist, but don't redirect + # builtins' (eg., cd) stderr directly: Ultrix's sh hates that. + at_dir=`(cd "$at_dir" && pwd) 2>/dev/null` + test -n "$at_dir" && at_path="$at_path$PATH_SEPARATOR$at_dir" +done +IFS=$at_IFS_save +PATH=$at_path +export PATH + +test -f atlocal && . ./atlocal + +# -e sets to true +at_stop_on_error=false +# Shall we be verbose? +at_verbose=: +at_quiet=echo +# Shall we keep the debug scripts? Must be `:' when testsuite is +# run by a debug script, so that the script doesn't remove itself. +at_debug=false +# Display help message? +at_help=false +# Tests to run +at_tests= +dnl Other vars inserted here (DEFAULT). +m4_divert([OPTIONS]) + +while test $[#] -gt 0; do + case $[1] in + --help | -h) at_help=: ;; + --version) echo "$[0] ($at_package) $at_version"; exit 0 ;; + + -d) at_debug=:;; + -e) at_stop_on_error=:;; + -v) at_verbose=echo; at_quiet=:;; + -x) at_traceon='set -vx'; at_traceoff='set +vx';; + + [[0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]]) + at_tests="$at_tests$[1] ";; + + *) echo "$as_me: invalid option: $[1]" >&2 + echo "Try \`$[0] --help' for more information." >&2 + exit 1 ;; + esac + shift +done + +# Help message. +if $at_help; then + # If tests were specified, display only their title. + if test -z "$at_tests"; then + cat <<EOF +Usage: $[0] [[OPTION]]... [[TESTS]] + +Run all the tests, or the selected TESTS. + +Options: + -h Display this help message and the description of TESTS + -e Abort the full suite and inhibit normal clean up if a test fails + -v Force more detailed output, default for debugging scripts + -d Inhibit clean up and debug script creation, default for debugging scripts + -x Have the shell to trace command execution + +Tests: +EOF + else + # " 1 42 45 " => " (1|42|45): " + at_tests_pattern=`echo "$at_tests" | sed 's/^ *//;s/ *$//;s/ */|/g'` + at_tests_pattern=" (${at_tests_pattern}): " + fi + $EGREP -e "$at_tests_pattern" <<EOF +m4_divert([HELP])dnl Help message inserted here. +m4_divert([SETUP])dnl +EOF + exit 0 +fi + +# Tests to run. +test -z "$at_tests" && at_tests=$at_tests_all + +# 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-devnull + cp /dev/null $at_devnull +fi + +# Use `diff -u' when possible. +if diff -u $at_devnull $at_devnull >/dev/null 2>&1; then + at_diff='diff -u' +else + at_diff=diff +fi + +# Tester and tested. +if $1 --version | grep "$at_package.*$at_version" >/dev/null; then + AS_BOX([Test suite for $at_package $at_version]) +else + AS_BOX([ERROR: Not using the proper version, no tests performed]) + exit 1 +fi + +# Setting up the FDs. +# 5 is stdout conditioned by verbosity. +if test $at_verbose = echo; then + exec 5>&1 +else + exec 5>/dev/null +fi + +at_fail_list= +at_skip_list= +at_test_count=0 +m4_divert([TESTS])dnl + +for at_test in $at_tests +do + at_status=0 + rm -rf $at_data_files + # Clearly separate the tests when verbose. + test $at_test_count != 0 && $at_verbose + case $at_test in +dnl Tests inserted here (TESTS). +m4_divert([TAIL])[]dnl + + * ) + echo $as_me: no such test: $at_test + continue + ;; + esac + case $at_test in + banner-*) ;; + *) + if test ! -f at-check-line; then + echo "$as_me: warning: no at-check-line which means a failure happened" + echo "$as_me: warning: in a [AT_SETUP/AT_CLEANUP] pair before any" + echo "$as_me: warning: [AT_CHECK] could be run. This test suite is" + echo "$as_me: warning: improperly designed, please report to" + echo "$as_me: warning: <$at_bugreport>." + cp at-setup-line at-check-line + fi + at_test_count=`expr 1 + $at_test_count` + $at_verbose $at_n "$at_test. $srcdir/`cat at-setup-line`: $at_c" + case $at_status in + 0) echo ok + ;; + 77) echo "ok (skipped near \``cat at-check-line`')" + at_skip_list="$at_skip_list $at_test" + ;; + *) echo "FAILED near \``cat at-check-line`'" + at_fail_list="$at_fail_list $at_test" + $at_stop_on_error && break + ;; + esac + $at_debug || rm -rf $at_data_files + ;; + esac +done + +# Wrap up the test suite with summary statistics. + +rm -f at-check-line at-setup-line +at_skip_count=`set dummy $at_skip_list; shift; echo $[#]` +at_fail_count=`set dummy $at_fail_list; shift; echo $[#]` +if test $at_fail_count = 0; then + if test $at_skip_count = 0; then + AS_BOX([All $at_test_count tests were successful]) + else + AS_BOX([All $at_test_count tests were successful ($at_skip_count skipped)]) + fi +elif test $at_debug = false; then + if $at_stop_on_error; then + AS_BOX([ERROR: One of the tests failed, inhibiting subsequent tests]) + else + AS_BOX([ERROR: Suite unsuccessful, $at_fail_count of $at_test_count tests failed]) + fi + + # Remove any debugging script resulting from a previous run. + rm -f debug-*.sh $[0].log + echo + echo $at_n "Writing \`debug-NN.sh' scripts, NN =$at_c" + for at_group in $at_fail_list; do + echo $at_n " $at_group$at_c" + ( echo "#! /bin/sh" + echo 'exec ${CONFIG_SHELL-'"$SHELL"'} '"$[0]"' -v -d '"$at_group"' ${1+"$[@]"}' + echo 'exit 1' + ) >debug-$at_group.sh + chmod +x debug-$at_group.sh + done + echo ', done' + echo + echo 'You may investigate any problem if you feel able to do so, in which' + echo 'case the testsuite provide a good starting point.' + echo + echo 'Now, failed tests will be executed again, verbosely, and logged' + echo 'in the file '$[0]'.log.' + + { + AS_BOX([Test suite log for $at_package $at_version]) + echo + + # Try to find a few ChangeLogs in case it might help determining the + # exact version. + find "$at_top_srcdir" -name ChangeLog \ + -exec echo {} : ';' \ + -exec sed 's/^/| /;10q' {} ';' \ + -exec echo ';' + + # Summary of failed and skipped tests. + if test $at_fail_count != 0; then + echo "Failed tests:" + $SHELL $[0] $at_fail_list --help + echo + fi + if test $at_skip_count != 0; then + echo "Skipped tests:" + $SHELL $[0] $at_skip_list --help + echo + fi + + AS_UNAME + } >>$[0].log + + $SHELL $[0] -v -d $at_fail_list 2>&1 | tee -a $[0].log + AS_BOX([$[0].log is created]) + + echo + echo "Please send \`$[0].log' to <$at_bugreport> together with all" + echo "the information you think might help." + exit 1 +fi + +exit 0 +m4_divert_pop()dnl +m4_wrap([m4_divert_text([DEFAULT], + [# List of the tests. +at_tests_all="AT_TESTS_ALL "])])dnl +m4_wrap([m4_divert_text([SETUP], + [# List of the output files. +at_data_files="AT_data_files "])])dnl +])# AT_INIT + + + +# 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_define([AT_ordinal], m4_incr(AT_ordinal)) +m4_append([AT_TESTS_ALL], [ ]m4_defn([AT_ordinal])) +m4_divert_text([HELP], + [m4_format([ %3d: %-15s %s], AT_ordinal, AT_LINE, [$1])]) +m4_divert_push([TESTS])dnl + AT_ordinal ) [#] AT_ordinal. AT_LINE: $1 + echo AT_LINE >at-setup-line + $at_verbose "AT_ordinal. $srcdir/AT_LINE: testing $1..." + $at_quiet $at_n "m4_format([%3d: %-18s], AT_ordinal, AT_LINE)[]$at_c" + ( + $at_traceon +]) + + +# AT_CLEANUP_FILE_IFELSE(FILE, IF-REGISTERED, IF-NOT-REGISTERED) +# -------------------------------------------------------------- +# We try to build a regular expression matching `[', `]', `*', and +# `.', i.e., the regexp active characters. +# +# Novices would write, `[[]*.]', which sure fails since the character +# class ends with the first closing braquet. +# M4 gurus will sure write `[\[\]*.]', but it will fail too because +# regexp does not support this and understands `\' per se. +# Regexp gurus will write `[][*.]' which is indeed what Regexp expects, +# but it will fail for M4 reasons: it's the same as `[*.]'. +# +# So the question is: +# +# Can you write a regexp that matches those four characters, +# and respects the M4 quotation constraints? +# +# The answer is: (rot13) tvira va gur ertrkc orybj, lbh vqvbg! +m4_define([AT_CLEANUP_FILE_IFELSE], +[m4_if(m4_regexp(AT_data_files, m4_patsubst([ $1 ], [[[]\|[]]\|[*.]], [\\\&])), + -1, + [$3], [$2])]) + + +# AT_CLEANUP_FILE(FILE) +# --------------------- +# Register FILE for AT_CLEANUP. +m4_define([AT_CLEANUP_FILE], +[AT_CLEANUP_FILE_IFELSE([$1], [], + [m4_append([AT_data_files], [$1 ])])]) + + +# AT_CLEANUP_FILES(FILES) +# ----------------------- +# Declare a list of FILES to clean. +m4_define([AT_CLEANUP_FILES], +[m4_foreach([AT_File], m4_quote(m4_patsubst([$1], [ *], [,])), + [AT_CLEANUP_FILE(AT_File)])]) + + +# AT_CLEANUP(FILES) +# ----------------- +# Complete a group of related tests, recursively remove those FILES +# created within the test. There is no need to list files created with +# AT_DATA. +m4_define([AT_CLEANUP], +[AT_CLEANUP_FILES([$1])dnl + ) + at_status=$? + ;; + +m4_divert([TESTS])[]dnl +m4_divert_pop()dnl +])# 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_TESTS_ALL], [ banner-]m4_defn([AT_banner_ordinal])) +m4_divert_push([TESTS])dnl + banner-AT_banner_ordinal ) [#] Banner AT_banner_ordinal. AT_LINE + cat <<\_ATEOF + +$1 + +_ATEOF + ;; + +m4_divert_pop()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 CONTENT to be evaluated, quote it twice. +m4_define([AT_DATA], +[AT_CLEANUP_FILES([$1])dnl +cat >$1 <<'_ATEOF' +$2[]_ATEOF +]) + + +# AT_CHECK(COMMANDS, [STATUS = 0], STDOUT, STDERR) +# ------------------------------------------------ +# Execute a test by performing given shell COMMANDS. These commands +# should normally exit with STATUS, while producing expected STDOUT and +# STDERR contents. +# +# 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 have the test +# suite introduces spurious failures. +# +# You might wander 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'. +# +# +# 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. +# +# 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_traceoff +$at_verbose "$srcdir/AT_LINE: AS_ESCAPE([$1])" +echo AT_LINE >at-check-line +( $at_traceon; $1 ) >at-stdout 2>at-stder1 +at_status=$? +$EGREP '^ *\+' at-stder1 >&2 +$EGREP -v '^ *\+' at-stder1 >at-stderr +at_failed=false +dnl Check stderr. +m4_case([$4], + stderr, [(echo stderr:; tee stderr <at-stderr) >&5], + ignore, [(echo stderr:; cat at-stderr) >&5], + experr, [$at_diff experr at-stderr >&5 || at_failed=:], + [], [$at_diff $at_devnull at-stderr >&5 || at_failed=:], + [echo >>at-stderr; echo "AS_ESCAPE([$4])" | $at_diff - at-stderr >&5 || at_failed=:]) +dnl Check stdout. +m4_case([$3], + stdout, [(echo stdout:; tee stdout <at-stdout) >&5], + ignore, [(echo stdout:; cat at-stdout) >&5], + expout, [$at_diff expout at-stdout >&5 || at_failed=:], + [], [$at_diff $at_devnull at-stdout >&5 || at_failed=:], + [echo >>at-stdout; echo "AS_ESCAPE([$3])" | $at_diff - at-stdout >&5 || at_failed=:]) +dnl Check exit val. Don't `skip' if we are precisely checking $? = 77. +case $at_status in +m4_case([$2], + [77], + [], + [ 77) exit 77;; +])dnl +m4_case([$2], + [ignore], + [ *);;], + [ m4_default([$2], [0])) ;; + *) $at_verbose "$srcdir/AT_LINE: exit code was $at_status, expected m4_default([$2], [0])" >&2 + at_failed=:;;]) +esac +AS_IF($at_failed, [$5], [$6]) +$at_failed && exit 1 +$at_traceon +])# AT_CHECK diff --git a/tests/atspecific.m4 b/tests/atspecific.m4 new file mode 100644 index 0000000..0b0bb8e --- /dev/null +++ b/tests/atspecific.m4 @@ -0,0 +1,185 @@ +include(atgeneral.m4) -*- Autoconf -*- +# M4 macros used in building Autoconf test suites. + +# 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 2, 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +## ---------------------------------------- ## +## Macros specialized in testing Autoconf. ## +## ---------------------------------------- ## + + +# AT_CONFIGURE_AC(BODY) +# --------------------- +# Create a full configure.ac running BODY, with a config header set up, +# AC_OUTPUT, and environment checking hooks. +m4_define([AT_CONFIGURE_AC], +[AT_CLEANUP_FILES(env-after state*)dnl +AT_DATA([configure.ac], +[[AC_INIT +AC_CONFIG_AUX_DIR($top_srcdir/config) +AC_CONFIG_HEADER(config.h:config.hin) +AC_STATE_SAVE(before)] +$1 +[AC_OUTPUT +AC_STATE_SAVE(after) +]])]) + + +# AT_CHECK_AUTOCONF(FLAGS, [EXIT-STATUS = 0], STDOUT, STDERR) +# ----------------------------------------------------------- +# Also remove `configure.in', just in case one remained from a previous +# run. +m4_define([AT_CHECK_AUTOCONF], +[AT_CLEANUP_FILES(configure.in configure)dnl +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir $1], + m4_default([$2], [0]), [$3], [$4])]) + + +# AT_CHECK_AUTOHEADER +# ------------------- +m4_define([AT_CHECK_AUTOHEADER], +[AT_CLEANUP_FILES(config.hin)dnl +AT_CHECK([autoheader --autoconf-dir .. -l $at_srcdir], 0, [], [])]) + + +# AT_CHECK_CONFIGURE(END-COMMAND, +# [EXIT-STATUS = 0], +# [SDOUT = IGNORE], STDERR) +# -------------------------------------------- +# `top_srcdir' is needed so that `./configure' finds install-sh. +# Using --srcdir is more expensive. +m4_define([AT_CHECK_CONFIGURE], +[AT_CLEANUP_FILE_IFELSE([config.hin], [AT_CLEANUP_FILE(config.h)])dnl +AT_CLEANUP_FILE_IFELSE([defs.in], [AT_CLEANUP_FILE(defs)])dnl +AT_CLEANUP_FILES(config.log config.status config.cache)dnl +AT_CHECK([top_srcdir=$top_srcdir ./configure $1], + [$2], + m4_default([$3], [ignore]), [$4], + [test $at_verbose = echo && echo "$srcdir/AT_LINE: config.log" && cat config.log])]) + + +# AT_CHECK_ENV +# ------------ +# Check that the full configure run remained in its variable name space, +# and cleaned up tmp files. +# The tests might exit prematurely when they find a problem, in +# which case `env-after' is probably missing. Don't check it then. +m4_define([AT_CHECK_ENV], +[if test -f expout; then chmod +w expout; fi +if test -f state-env.before -a -f state-env.after; then + mv state-env.before expout + AT_CHECK([cat state-env.after], 0, expout) +fi +if test -f state-ls.before -a -f state-ls.after; then + mv state-ls.before expout + AT_CHECK([cat state-ls.after], 0, expout) +fi +]) + + +# AT_CHECK_DEFINES(CONTENT) +# ------------------------- +# Verify that config.h, once stripped is CONTENT. +# Stripping consists of keeping CPP lines (i.e. containing a hash), +# but those of automatically checked features (STDC_HEADERS etc.). +# AT_CHECK_HEADER is a better name, but too close from AC_CHECK_HEADER. +m4_define([AT_CHECK_DEFINES], +[AT_CHECK([[$FGREP '#' config.h | + $EGREP -v 'STDC_HEADERS|STD(INT|LIB)|INTTYPES|MEMORY|STRING|UNISTD|SYS_(TYPES|STAT)']],, + [$1])]) + + +# AT_CHECK_AUTOUPDATE +# ------------------- +m4_define([AT_CHECK_AUTOUPDATE], +[AT_CHECK([autoupdate --version || exit 77], ignore, ignore, ignore) + AT_CHECK([autoupdate --autoconf-dir $at_top_srcdir], 0, + [], [autoupdate: `configure.ac' is updated +])]) + + +# _AT_CHECK_AC_MACRO(AC-BODY, PRE-TESTS) +# -------------------------------------- +# Create a minimalist configure.ac running the macro named +# NAME-OF-THE-MACRO, check that autoconf runs on that script, +# and that the shell runs correctly the configure. +# TOP_SRCDIR is needed to set the auxdir (some macros need `install-sh', +# `config.guess' etc.). +m4_define([_AT_CHECK_AC_MACRO], +[AT_CONFIGURE_AC([$1]) +$2 +AT_CHECK_AUTOCONF +AT_CHECK_AUTOHEADER +AT_CHECK_CONFIGURE +AT_CHECK_ENV +])# _AT_CHECK_AC_MACRO + + +# AT_CHECK_MACRO(MACRO, [MACRO-USE], [ADDITIONAL-CMDS], [AUTOCONF-FLAGS]) +# ----------------------------------------------------------------------- +# Create a minimalist configure.ac running the macro named +# NAME-OF-THE-MACRO, check that autoconf runs on that script, +# and that the shell runs correctly the configure. +# TOP_SRCDIR is needed to set the auxdir (some macros need `install-sh', +# `config.guess' etc.). +# +# New macros are not expected to depend upon obsolete macros. +m4_define([AT_CHECK_MACRO], +[AT_SETUP([$1]) +AT_CONFIGURE_AC([m4_default([$2], [$1])]) + +AT_CHECK_AUTOCONF([m4_default([$4], [-W obsolete])]) +AT_CHECK_AUTOHEADER +AT_CHECK_CONFIGURE +AT_CHECK_ENV +$3 +AT_CLEANUP()dnl +])# AT_CHECK_MACRO + + +# AT_CHECK_AU_MACRO(MACRO) +# ------------------------ +# Create a minimalist configure.ac running the macro named +# NAME-OF-THE-MACRO, autoupdate this script, check that autoconf runs +# on that script, and that the shell runs correctly the configure. +# TOP_SRCDIR is needed to set the auxdir (some macros need +# `install-sh', `config.guess' etc.). +# +# Updated configure.ac shall not depend upon obsolete macros, which votes +# in favor of `-W obsolete', but since many of these macros leave a message +# to be removed by the user once her code is adjusted, let's not check. +# +# Remove config.hin to avoid `autoheader: config.hin is unchanged'. +m4_define([AT_CHECK_AU_MACRO], +[AT_SETUP([$1]) +AT_CONFIGURE_AC([$1]) + +AT_CHECK_AUTOCONF +AT_CHECK_AUTOHEADER +AT_CHECK_CONFIGURE +AT_CHECK_ENV + +rm config.hin +AT_CHECK_AUTOUPDATE + +AT_CHECK_AUTOCONF +AT_CHECK_AUTOHEADER +AT_CHECK_CONFIGURE +AT_CHECK_ENV + +AT_CLEANUP()dnl +])# AT_CHECK_UPDATE diff --git a/tests/base.at b/tests/base.at new file mode 100644 index 0000000..726dba9 --- /dev/null +++ b/tests/base.at @@ -0,0 +1,255 @@ +# -*- autoconf -*- + +AT_BANNER([Autoconf base layer.]) + + +## ------------------------------- ## +## AC_REQUIRE: topological sort.. ## +## ------------------------------- ## + +# Check that dependencies are always properly honored. + +AT_SETUP([AC_REQUIRE: topological sort]) + +AT_DATA(configure.ac, +[[define([REQUIRE_AND_CHECK], +[AC_REQUIRE([$1])dnl +test -z "$m4_translit([$1], [A-Z], [a-z])" && AS_EXIT(1)]) + +AC_DEFUN([TEST1], +[REQUIRE_AND_CHECK([TEST2a]) +REQUIRE_AND_CHECK([TEST2b]) +test1=set]) + +AC_DEFUN([TEST2a], +[test2a=set]) + +AC_DEFUN([TEST2b], +[REQUIRE_AND_CHECK([TEST3]) +test2b=set]) + +AC_DEFUN([TEST3], +[REQUIRE_AND_CHECK([TEST2a]) +test3=set]) + +AC_PLAIN_SCRIPT()dnl +#! /bin/sh + +TEST1 +test -z "$test1" && + AC_MSG_ERROR([\$test1 is empty]) +AS_EXIT(0) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_CLEANUP + + + +## ----------------------------------------------- ## +## AC_REQUIRE and AC_DEFUN_ONCE: Require, expand. ## +## ----------------------------------------------- ## + +AT_SETUP([AC_REQUIRE & AC_DEFUN_ONCE: Require, expand]) + +AT_DATA([configure.ac], +[[AC_DEFUN([TEST], +[AC_REQUIRE([MULTI_TEST]) +AC_REQUIRE([SINGLE_TEST])]) + +AC_DEFUN([MULTI_TEST], +[multi_test=".$multi_test"]) + +AC_DEFUN_ONCE([SINGLE_TEST], +[single_test=".$single_test"]) + +AC_PLAIN_SCRIPT()dnl +#! /bin/sh + +TEST +TEST +MULTI_TEST +MULTI_TEST +SINGLE_TEST +SINGLE_TEST + +case $multi_test:$single_test in + ...:. ) AS_EXIT(0);; + ...:* ) AC_MSG_ERROR([DEFUN_ONCE is broken]);; + *:. ) AC_MSG_ERROR([DEFUN is broken (Wow, congrats!)]);; +esac +]]) + +AT_CHECK_AUTOCONF([], 0, [], +[configure.ac:18: warning: SINGLE_TEST invoked multiple times +configure.ac:19: warning: SINGLE_TEST invoked multiple times +]) + +AT_CHECK_CONFIGURE + +AT_CLEANUP + + + +## ----------------------------------------------- ## +## AC_REQUIRE and AC_DEFUN_ONCE: Expand, require. ## +## ----------------------------------------------- ## + +AT_SETUP([AC_REQUIRE & AC_DEFUN_ONCE: Expand, require]) + +AT_DATA([configure.ac], +[[AC_DEFUN([TEST], +[AC_REQUIRE([MULTI_TEST]) +AC_REQUIRE([SINGLE_TEST])]) + +AC_DEFUN([MULTI_TEST], +[multi_test=".$multi_test"]) + +AC_DEFUN_ONCE([SINGLE_TEST], +[single_test=".$single_test"]) + +AC_PLAIN_SCRIPT()dnl +#! /bin/sh + +MULTI_TEST +MULTI_TEST +SINGLE_TEST +SINGLE_TEST +TEST +TEST + +case $multi_test:$single_test in + ..:. ) AS_EXIT(0);; + ..:* ) AC_MSG_ERROR([DEFUN_ONCE is broken]);; + *:. ) AC_MSG_ERROR([DEFUN is broken (Wow, congrats!)]);; + * ) AC_MSG_ERROR([received `$multi_test:$single_test']);; +esac +]]) + +AT_CHECK_AUTOCONF([], 0, [], +[configure.ac:17: warning: SINGLE_TEST invoked multiple times +]) +AT_CHECK_CONFIGURE + +AT_CLEANUP + + + +## ------------------------- ## +## AC_REQUIRE & AC_PROVIDE. ## +## ------------------------- ## + +AT_SETUP([AC_REQUIRE & AC_PROVIDE]) + +AT_DATA([configure.ac], +[[AC_DEFUN([TEST], +[AC_REQUIRE([INNER_TEST])]) + +AC_DEFUN([INNER_TEST], +[inner_test=".$inner_test"]) + +AC_PLAIN_SCRIPT()dnl +#! /bin/sh + +AC_PROVIDE([INNER_TEST]) +TEST + +case $inner_test in + "" ) AS_EXIT(0);; + * ) AC_MSG_ERROR([received `$inner_test']);; +esac +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_CLEANUP + + +## ---------------------- ## +## AC_REQUIRE & AC_LANG. ## +## ---------------------- ## + +AT_SETUP([AC_REQUIRE & AC_LANG]) + +AT_DATA([configure.ac], +[[AC_DEFUN([AC_F77_1], +[AC_LANG_PUSH([Fortran 77]) +if test $ac_ext != f; then + AC_MSG_ERROR([F77_1: current shell language is $ac_ext, expected Fortran]) +fi +AC_LANG_POP +]) + + +AC_DEFUN([AC_F77_2], +[AC_LANG_PUSH([Fortran 77]) +AC_REQUIRE([AC_F77_1]) +if test $ac_ext != f; then + AC_MSG_ERROR([F77_2: current shell language is $ac_ext, expected Fortran]) +fi +AC_LANG_POP +]) + +AC_INIT +AC_F77_2 +AS_EXIT(0) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_CLEANUP + + +## ---------------- ## +## AC_CACHE_CHECK. ## +## ---------------- ## + +# Make sure AC_CACHE_CHECK is silent with -q. + +AT_SETUP([AC_CACHE_CHECK]) + +AT_DATA([configure.ac], +[[AC_INIT +AC_CACHE_CHECK([for nothing], + [ac_nothing], + [ac_nothing=found]) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE([-q]) + +AT_CLEANUP + + +## ---------- ## +## AC_TRY_*. ## +## ---------- ## + +AT_SETUP([AC_TRY_*]) + +AT_DATA([configure.ac], +[[AC_INIT + +if AC_TRY_COMMAND([(echo "The Cat in the Hat"; + echo "The Hat in the Cat" >&2) + | grep \^The\ Cat\ in\ the\ Hat\$ >/dev/null]); then + : +else + AC_MSG_ERROR([Didn't see the Cat in the Hat!]) +fi + +if AC_TRY_COMMAND([(echo "The Cat in the Hat"; + echo "The Hat in the Cat" >&2) + | grep \^The\ Hat\ in\ the\ Cat\$ >/dev/null]); then + AC_MSG_ERROR([Saw the Hat in the Cat!]) +fi +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE([-q]) + +AT_CLEANUP diff --git a/tests/compile.at b/tests/compile.at new file mode 100644 index 0000000..7ea207f --- /dev/null +++ b/tests/compile.at @@ -0,0 +1,277 @@ +# -*- autoconf -*- + +AT_BANNER([Low level compiling/preprocessing macros.]) + +# Since the macros which compile are required by most tests, check +# them first. But remember that looking for a compiler is even more +# primitive, so check those first. + + +## ------------------------------------- ## +## AC_LANG, AC_LANG_PUSH & AC_LANG_POP. ## +## ------------------------------------- ## + +AT_SETUP([AC_LANG, AC_LANG_PUSH & AC_LANG_POP]) + +AT_DATA([configure.ac], +[[AC_INIT +# C +AC_LANG(C) +# C +AC_LANG_PUSH(C) +# C C +AC_LANG_PUSH(C++) +# C++ C C +AC_LANG(C++) +# C++ C C +AC_LANG_PUSH(Fortran 77) +# F77 C++ C C +AC_LANG_POP(Fortran 77) +# C++ C C +AC_LANG(C++) +# C++ C C +AC_LANG_POP(C++) +# C C +AC_LANG_POP(C) +# C +]]) + +AT_CHECK_AUTOCONF +AT_CHECK([sed -n 's/^ac_ext=//p' configure], 0, +[c +c +c +cc +cc +f +cc +cc +c +c +]) + +AT_CLEANUP + + +## ------------ ## +## Extensions. ## +## ------------ ## + +# As far as we know only `foo', `foo.exe' are possible executable, +# and `foo.o', `foo.obj' are possible object files. Autoconf must not +# know that, but it is OK for the test suite to take this into account. +AT_CHECK_MACRO([Extensions], +[[AC_PROG_CC +case $ac_exeext in + '' | '.exe' ) ;; + * ) AC_MSG_ERROR([suspicious executable suffix: $ac_exeext]);; +esac + +case $ac_objext in + 'o' | 'obj' ) ;; + * ) AC_MSG_ERROR([suspicious object suffix: $ac_objext]);; +esac +AS_EXIT([0]) +]]) + + + +## -------------------------- ## +## Broken/missing compilers. ## +## -------------------------- ## + + +# Check that Autoconf correctly diagnoses broken compilers, and in +# particular, if it does not exit 77, the test suite is in trouble... +# FIXME: Once a precise message decided, check stderr of configure. +AT_SETUP([Broken/missing compilers]) + +AT_DATA([configure.ac], +[[AC_INIT +CC=no-such-compiler +AC_PROG_CC +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE([], 77, ignore, ignore) + +AT_CLEANUP + + +## ------------ ## +## C keywords. ## +## ------------ ## + +# GCC supports `const', `volatile', and `inline'. +AT_CHECK_MACRO([C keywords], +[[AC_PROG_CC +AC_C_CONST +AC_C_INLINE +AC_C_VOLATILE +case $GCC,$ac_cv_c_const,$ac_cv_c_inline,$ac_cv_c_volatile in + yes,*no*) + AC_MSG_ERROR([failed to detect `const', `inline' or `volatile' support]);; +esac +]]) + + + +## --------------------------------- ## +## AC_PROG_CPP requires AC_PROG_CC. ## +## --------------------------------- ## + +# Must invoke AC_PROG_CC. +AT_CHECK_MACRO([AC_PROG_CPP requires AC_PROG_CC], +[[AC_PROG_CPP +test -z "$CC" && + AC_MSG_ERROR([looked for a C preprocessor without looking for a compiler]) +]]) + + + +## --------------------------- ## +## AC_PROG_CPP with warnings. ## +## --------------------------- ## + + +# It's Ok for strict preprocessors to produce warnings. + +AT_SETUP([AC_PROG_CPP with warnings]) + +AT_DATA([mycpp], +[[#! /bin/sh +echo noise >&2 +exec ${1+"$@"} +]]) + +chmod +x mycpp + +_AT_CHECK_AC_MACRO( +[[AC_PROG_CPP +# If the preprocessor is not strict, just ignore +test "x$ac_c_preproc_warn_flag" = xyes && + AC_MSG_ERROR([preprocessor has no warning option], 77) +CPP="./mycpp $CPP" +AC_CHECK_HEADERS(stdio.h autoconf_io.h)]]) + +AT_CHECK_DEFINES( +[/* #undef HAVE_AUTOCONF_IO_H */ +#define HAVE_STDIO_H 1 +]) + +AT_CLEANUP + + +## ------------------------------ ## +## AC_PROG_CPP without warnings. ## +## ------------------------------ ## + +AT_SETUP([AC_PROG_CPP without warnings]) + +# Ignore if /lib/cpp doesn't work +AT_CHECK([/lib/cpp </dev/null || exit 77], [], [ignore], [ignore]) + +# A cpp which exit status is meaningless. +AT_DATA([mycpp], +[[#! /bin/sh +/lib/cpp ${1+"$@"} +exit 0 +]]) + +chmod +x mycpp + +_AT_CHECK_AC_MACRO( +[[CPP=./mycpp +AC_PROG_CPP +test "x$ac_c_preproc_warn_flag" != xyes && + AC_MSG_ERROR([failed to detect preprocessor warning option]) +AC_CHECK_HEADERS(stdio.h autoconf_io.h)]]) + +AT_CHECK_DEFINES( +[/* #undef HAVE_AUTOCONF_IO_H */ +#define HAVE_STDIO_H 1 +]) + +AT_CLEANUP + + + +## -------------------- ## +## AC_PROG_CPP via CC. ## +## -------------------- ## + + +# It's Ok for strict preprocessors to produce warnings. + +AT_SETUP([AC_PROG_CPP via CC]) + +# Ignore if /lib/cpp doesn't work +AT_CHECK([/lib/cpp </dev/null || exit 77], [], [ignore], [ignore]) + +AT_DATA([mycc], +[[#! /bin/sh +echo "Annoying copyright message" >&2 +exec "$@" +]]) + +chmod +x mycc + +# We go through the following contortions, in order to have the +# configure script go down the same codepaths as it would during a +# normal CPP selection check. If we explicitly set CPP, it goes down +# a different codepath. +_AT_CHECK_AC_MACRO( +[[AC_PROG_CC +CC="./mycc $CC" +AC_PROG_CPP +# The test $CC compiler should have been selected. +test "$CPP" != "$CC -E" && + AC_MSG_ERROR([error messages on stderr cause the preprocessor selection to fail]) + +# Exercise CPP. +AC_CHECK_HEADERS(stdio.h autoconf_io.h)]]) + +AT_CHECK_DEFINES( +[/* #undef HAVE_AUTOCONF_IO_H */ +#define HAVE_STDIO_H 1 +]) + +AT_CLEANUP + + +## ------------------ ## +## AC_TRY_LINK_FUNC. ## +## ------------------ ## + +AT_CHECK_MACRO([AC_TRY_LINK_FUNC], +[AC_TRY_LINK_FUNC(printf,, + [AC_MSG_ERROR([cannot find `printf'])]) +AC_TRY_LINK_FUNC(Be_doomed_if_your_libc_has_a_function_named_like_this, + [AC_MSG_ERROR([found a nonexistent function])])]) + + + +## --------------------- ## +## Fortran 77 Compiler. ## +## --------------------- ## + + +AT_CHECK_MACRO([GNU Fortran 77], +[[AC_LANG(Fortran 77) +AC_LANG_COMPILER + +if AC_TRY_COMMAND([$F77 --version | grep GNU >&2]); then + # Be sure to remove files which might be created by compilers that + # don't support --version. + rm -f a.exe a.out + # Has GNU in --version. + test "$G77" != yes && + AC_MSG_ERROR([failed to recognize GNU Fortran 77 compiler]) +else + # Be sure to remove files which might be created by compilers that + # don't support --version. + rm -f a.exe a.out + # Has not. + test "$G77" = yes && + AC_MSG_ERROR([incorrectly recognized a GNU Fortran 77 compiler]) +fi]]) diff --git a/tests/m4sh.at b/tests/m4sh.at new file mode 100644 index 0000000..255c185 --- /dev/null +++ b/tests/m4sh.at @@ -0,0 +1,118 @@ +# -*- Autoconf -*- + +AT_BANNER([M4sh.]) + + +## ----------------------------- ## +## AS_DIRNAME & AS_DIRNAME_SED. ## +## ----------------------------- ## + +# Build nested dirs. + +AT_SETUP([[AS_DIRNAME & AS_DIRNAME_SED]]) + +AT_DATA(configure.ac, +[[AC_PLAIN_SCRIPT()dnl +#! /bin/sh + +_AS_EXPR_PREPARE + +define([AS_DIRNAME_TEST], +[dir=`AS_DIRNAME([$1])` +test "$dir" = "$2" || + echo "dirname($1) = $dir instead of $2" >&2 + +dir=`AS_DIRNAME_SED([$1])` +test "$dir" = "$2" || + echo "dirname_sed($1) = $dir instead of $2" >&2]) + +AS_DIRNAME_TEST([//1], [//]) +AS_DIRNAME_TEST([/1], [/]) +AS_DIRNAME_TEST([./1], [.]) +AS_DIRNAME_TEST([../../2], [../..]) +AS_DIRNAME_TEST([//1/], [//]) +AS_DIRNAME_TEST([/1/], [/]) +AS_DIRNAME_TEST([./1/], [.]) +AS_DIRNAME_TEST([../../2], [../..]) +AS_DIRNAME_TEST([//1/3], [//1]) +AS_DIRNAME_TEST([/1/3], [/1]) +AS_DIRNAME_TEST([./1/3], [./1]) +AS_DIRNAME_TEST([../../2/3], [../../2]) +AS_DIRNAME_TEST([//1/3///], [//1]) +AS_DIRNAME_TEST([/1/3///], [/1]) +AS_DIRNAME_TEST([./1/3///], [./1]) +AS_DIRNAME_TEST([../../2/3///], [../../2]) +AS_DIRNAME_TEST([//1//3/], [//1]) +AS_DIRNAME_TEST([/1//3/], [/1]) +AS_DIRNAME_TEST([./1//3/], [./1]) +AS_DIRNAME_TEST([../../2//3/], [../../2]) +AS_EXIT(0) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_CLEANUP(configure) + + + +## ------------ ## +## AS_MKDIR_P. ## +## ------------ ## + +# Build nested dirs. + +AT_SETUP([[AS_MKDIR_P]]) + +AT_DATA([configure.ac], +[[AC_PLAIN_SCRIPT()dnl +#! /bin/sh + +pwd=`pwd` +set -e +# Absolute +AS_MKDIR_P(["$pwd/1/2/3/4/5/6"]) +test -d "$pwd/1/2/3/4/5/6" || + AC_MSG_ERROR([$pwd/1/2/3/4/5/6 has not been properly created]) +# Relative +AS_MKDIR_P(["a/b/c/d/e/f"]) +test -d a/b/c/d/e/f || + AC_MSG_ERROR([a/b/c/d/e/f has not been properly created]) +AS_EXIT(0) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_CLEANUP(configure 1 a) + + + + +## ----------------------------- ## +## Negated classes in globbing. ## +## ----------------------------- ## + +# It is known that `[^...]' is not universally supported, but it is +# unknown for `[!...]'. + +AT_SETUP([Negated classes in globbing]) + +AT_DATA([configure.ac], +[[AC_PLAIN_SCRIPT()dnl +#! /bin/sh + +case 'with!two!bangs' in + *[[!a-z]]*) ;; + *) AC_MSG_ERROR([[`*[!a-z]*' didn't match `with!two!bangs']]);; +esac + +case without in + *[[!a-z]]*) AC_MSG_ERROR([[`*[!a-z]*' matched `without']]);; +esac +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_CLEANUP(configure) diff --git a/tests/m4sugar.at b/tests/m4sugar.at new file mode 100644 index 0000000..9f4dab7 --- /dev/null +++ b/tests/m4sugar.at @@ -0,0 +1,139 @@ +# -*- Autoconf -*- + +AT_BANNER([M4sugar.]) + + +# Order of the tests: +# - m4_warn +# +# - m4_require +# uses warn/error code. +# +# - m4_text_wrap + +## --------- ## +## m4_warn. ## +## --------- ## + +AT_SETUP([[m4_warn]]) + +# m4_text_wrap is used to display the help strings. Also, check that +# commas are not swallowed. This can easily happen because of +# m4-listification. + +AT_DATA(configure.ac, +[[m4_warn([foo], [foo]) +m4_warn([bar], [bar]) +m4_warn([syntax], [syntax]) +]]) + +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir -o-], + 0, [], +[configure.ac:3: warning: syntax +]) + +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir -o- -Wall], + 0, [], +[configure.ac:1: warning: foo +configure.ac:2: warning: bar +configure.ac:3: warning: syntax +]) + +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir -o- -Wnone,bar], + 0, [], +[configure.ac:2: warning: bar +]) + +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir -o- -Wnone,bar,error], + 1, [], +[configure.ac:2: error: bar +configure.ac:2: the top level +]) + +AT_CLEANUP + + +## ----------------------------------- ## +## m4_require: circular dependencies. ## +## ----------------------------------- ## + +AT_SETUP([[m4_require: circular dependencies]]) + +# m4_text_wrap is used to display the help strings. Also, check that +# commas are not swallowed. This can easily happen because of +# m4-listification. + +AT_DATA([configure.ac], +[[m4_defun([foo], +[m4_require([bar])]) + +m4_defun([bar], +[m4_require([foo])]) + +m4_defun([baz], +[m4_require([foo])]) + +m4_init +baz +]]) + +AT_CHECK_AUTOCONF([], 1, [], +[[configure.ac:11: error: m4_require: circular dependency of foo +configure.ac:11: foo is required by... +configure.ac:4: bar is expanded from... +configure.ac:11: bar is required by... +configure.ac:1: foo is expanded from... +configure.ac:11: foo is required by... +configure.ac:7: baz is expanded from... +configure.ac:11: the top level +]]) + +AT_CLEANUP + + +## -------------- ## +## m4_text_wrap. ## +## -------------- ## + +AT_SETUP([[m4_text_wrap]]) + +# m4_text_wrap is used to display the help strings. Also, check that +# commas are not swallowed. This can easily happen because of +# m4-listification. + +AT_DATA([configure.ac], +[[AC_PLAIN_SCRIPT()dnl +m4_text_wrap([Short string */], [ ], [/* ], 20) + +m4_text_wrap([Much longer string */], [ ], [/* ], 20) + +m4_text_wrap([Short doc.], [ ], [ --short ], 30) + +m4_text_wrap([Short doc.], [ ], [ --too-wide], 30) + +m4_text_wrap([Super long documentation.], [ ], [ --too-wide], 30) + +m4_text_wrap([First, second , third, [,quoted]]) +]]) + +AT_DATA(expout, +[[/* Short string */ + +/* Much longer + string */ + + --short Short doc. + + --too-wide + Short doc. + + --too-wide + Super long + documentation. + +First, second , third, [,quoted] +]]) + +AT_CHECK_AUTOCONF([-o-], 0, [expout]) + +AT_CLEANUP diff --git a/tests/mktests.in b/tests/mktests.in new file mode 100755 index 0000000..6868f5b --- /dev/null +++ b/tests/mktests.in @@ -0,0 +1,230 @@ +#! /bin/sh + +# Build some of the Autoconf test files. +# Copyright 2021,2023 Thomas E. Dickey +# Copyright 2000 Free Software Foundation, Inc. + +# 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 2, 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. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# If we fail, clean up, but touch the output files. We probably failed +# because we used some non portable tool, but we just don't care: this +# shell script is a maintainer tool, and we do expect good tools. + +as_me=`echo "$0" | sed 's,.*[\\/],,'` + +trap 'echo "'"$as_me"': failed. To proceed run make check." >&2 + rm -f acdefuns audefuns requires *.tat + for file in "$@" + do + touch `echo "$file" | sed "s,.*[\\/],,;s/\..*/.at/"` + done + trap 0 + exit 1' \ + 0 1 2 15 + +# If ever something goes wrong, fail, so that the trap be launched. +set -e + +# We need arguments. +test $# != 0 + +# We need these arguments. +src="$@" + +# Set locale to C so that `sort' behaves in a uniform way. +export LANGUAGE; LANGUAGE=C +export LANG; LANG=C +export LC_ALL; LC_ALL=C + + +# requires +# -------- +# Get the list of macros that are required: there is little interest +# in testing them since they will be run but the guy who requires +# them. +cat $src | + sed -n 's/dnl.*//;s/.*AC_REQUIRE(\[*\([a-zA-Z0-9_]*\).*$/\1/p' | + sort | + uniq >requires + + +# exclude_list +# ------------ +# Macros which must not be checked at all (not by ac-macros.at, nor +# au-macros.at). +# The trailing new line is meant. +# +# - ac_cv_prog_gcc, gxx, g77 +# Not macros, just mapping from old variable name to a new one. +exclude_list='^ac_cv_prog_(gcc|gxx|g77)$ +' + + +# ac_exclude_list +# --------------- +# The test `ac-macros.at' tries to run all the macros of Autoconf to check +# for syntax problems, etc. Not all the macros can be run without argument, +# and some are already tested elsewhere. EGREP_EXCLUDE must filter out +# the macros we don't want to test in ac-macros.at. +# +# - AC_CANONICALIZE, AC_PREFIX_PROGRAM, AC_PREREQ +# Need an argument. +# - AC_CHECK decl, file, func, header, lib, member, prog, sizeof, type +# Performed in the semantics tests. +# - AC_CONFIG +# They fail when the source does not exist. +# - AC_INIT +# AC_INIT includes all the AC_INIT macros. Note that there is an +# infinite m4 recursion if AC_INIT it used twice. +# - AC_LANG* +# Heavily used by other macros. +# - AC_PATH_PROGS?, AC_F77_FUNC +# They produce `= val' because $1, the variable used to store the result, +# is empty. +# - AC_TRY, AC_.*_IFELSE, AC_RUN_LOG. +# Used in many places. +# - _AC_ +# Internal macros are used elsewhere. +# - AC_OUTPUT +# Already tested by `AT_CHECK_MACRO'. +# - AC_FD_CC +# Is a number. +# - AC_PROG_CC, AC_C_(CONST|INLINE|VOLATILE), AC_PATH_XTRA +# Checked in semantics. +# - AC_CYGWIN, AC_CYGWIN32, AC_EMXOS2, AC_MING32, AC_EXEEXT, AC_OBJEXT +# AU defined to nothing. +# - AC_PATH_XTRA +# Checked in semantics. +# - AC_SYS_RESTARTABLE_SYSCALLS, AC_FUNC_WAIT3 +# Obsolete, checked in semantics. +# +ac_exclude_list='^AC_ARG_VAR$ +^AC_CANONICALIZE|AC_PREFIX_PROGRAM|AC_PREREQ$ +^AC_CHECK_(DECL|FILE|FUNC|HEADER|LIB|MEMBER|PROG|SIZEOF|TOOL|TYPE)S?$ +^AC_CONFIG +^AC_F77_FUNC$ +^AC_INIT +^AC_LANG +^AC_LINKER_OPTION$ +^AC_LINK_FILES$ +^AC_LIST_MEMBER_OF$ +^AC_OUTPUT$ +^AC_PATH_(TOOL|PROG)S?$ +^AC_REPLACE_FUNCS$ +^AC_SEARCH_LIBS$ +^(AC_TRY.*|AC_RUN_LOG)$ +^AC_.*_IFELSE$ +^AC_FD_CC$ +^(AC_(PROG_CC|C_CONST|C_INLINE|C_VOLATILE))$ +^AC_(CYGWIN|CYGWIN32|EMXOS2|MING32|EXEEXT|OBJEXT)$ +^AC_PATH_XTRA$ +^AC_SYS_RESTARTABLE_SYSCALLS$ +^AC_FUNC_WAIT3$ +_AC_' + + +# ac_exclude_egrep +# ---------------- +# Build a single egrep pattern out of filter_macros_list. +# Sed is used to get rid of the trailing `|' coming from the trailing +# `\n' from `echo'. +ac_exclude_egrep=`echo "$exclude_list$ac_exclude_list" | tr ' +' '|' | sed 's/.$//'` + + +# au_exclude_list +# --------------- +# AC_LANG_RESTORE +# cannot be used alone. +# AC_LINK_FILES, AC_PREREQ +# need arguments and are tested elsewhere. +# AC_INIT and AC_OUTPUT +# are already in `configure.ac'. +# AC_CYGWIN, AC_MINGW32, AC_EMXOS2 +# are using AC_REQUIRE. +au_exclude_list='^AC_LANG_RESTORE$ +^AC_LINK_FILES|AC_PREREQ$ +^AC_(INIT|OUTPUT)$ +^AC_(CYGWIN|MINGW32|EMXOS2)$' + + +# au_exclude_egrep +# ---------------- +# Build a single egrep pattern out of filter_macros_list. +# Sed is used to get rid of the trailing `|' coming from the trailing +# `\n' from `echo'. +au_exclude_egrep=`echo "$exclude_list$au_exclude_list" | tr ' +' '|' | sed 's/.$//'` + + + +## ------------------------- ## +## Creating the test files. ## +## ------------------------- ## + +for file in $src +do + base=`echo "$file" | sed 's,.*[\\/],,;s/\..*//'` + # Get the list of macros which are defined in Autoconf level. + # Get rid of the macros we are not interested in. + cat $file | + sed -n -e 's/^AC_DEFUN(\[*\([a-zA-Z0-9_]*\).*$/\1/p' \ + -e 's/^AC_DEFUN_ONCE(\[*\([a-zA-Z0-9_]*\).*$/\1/p' | + sort | + uniq | + # Watch out we are `set -e': don't fail. + ( @EGREP@ -v "$ac_exclude_egrep" || true) >acdefuns + + # Get the list of macros which are defined in Autoupdate level. + cat $file | + sed -n 's/^AU_DEFUN(\[*\([a-zA-Z][a-zA-Z0-9_]*\).*$/\1/p' | + sort | + uniq | + ( @EGREP@ -v "$au_exclude_egrep" || true) > audefuns + + # Filter out required macros. + { + sed 's/^ *//' <<MK_EOF + # Generated by $as_me, do not edit by hand. -*- autoconf -*- + + AT_BANNER([Testing $base macros.]) + +MK_EOF + + echo "# Modern macros." + for macro in `cat acdefuns`; do + if @FGREP@ "$macro" requires >/dev/null 2>&1; then :; else + echo "AT_CHECK_MACRO([$macro])" + fi + done + echo + echo "# Obsolete macros." + for macro in `cat audefuns`; do + if @FGREP@ "$macro" requires >/dev/null 2>&1; then :; else + echo "AT_CHECK_AU_MACRO([$macro])" + fi + done + } >$base.tat + + # In one atomic step so that if something above fails, the trap + # preserves the old version of the file. + mv -f $base.tat $base.at +done + +rm -f acdefuns audefuns requires + +trap 0 +exit 0 diff --git a/tests/semantics.at b/tests/semantics.at new file mode 100644 index 0000000..0ca46b4 --- /dev/null +++ b/tests/semantics.at @@ -0,0 +1,378 @@ +# -*- autoconf -*- + +AT_BANNER([Semantics.]) + + + + +## -------------------------------- ## +## Members of the AC_CHECK family. ## +## -------------------------------- ## + + +# AC_CHECK_LIB +# ------------ +# Well, I can't imagine a system where `cos' is neither in libc, nor +# in libm. Nor can I imagine a lib more likely to exists than libm. +# But there are systems without libm, on which we don't want to have +# this test fail, so exit successfully if `cos' is in libc. +AT_CHECK_MACRO([AC_CHECK_LIB], +[AC_TRY_LINK_FUNC(cos, + [AC_MSG_ERROR([`cos' is in `libc'], 77)]) + +AC_CHECK_LIB(m, cos,, + [AC_MSG_ERROR([cannot find `cos' in `libm'])]) + +# No kidding, using variables was broken in 2.50 :( +ac_sin=sin +AC_CHECK_LIB(m, $ac_sin,, + [AC_MSG_ERROR([cannot find `\$ac_sin' (= `$ac_sin') in `libm'])]) + +ac_m=m +AC_CHECK_LIB($ac_m, acos,, + [AC_MSG_ERROR([cannot find `acos' in `\$ac_m' (= `$ac_m')])]) + +ac_asin=asin +AC_CHECK_LIB($ac_m, $ac_asin,, + [AC_MSG_ERROR([cannot find `\$ac_asin' (= `$ac_asin') in `\$ac_m' (= `$at_m')])]) + +# But if the bug is in the caching mechanism, then be sure we +# correctly detect failures. + +AC_CHECK_LIB(m, cossack, + [AC_MSG_ERROR([found `cossack' in `libm'])]) + +# No kidding, using variables was broken in 2.50 :( +ac_sinner=sinner +AC_CHECK_LIB(m, $ac_sinner, + [AC_MSG_ERROR([found `\$ac_sinner' (= `$ac_sinner') in `libm'])]) + +ac_m=m +AC_CHECK_LIB($ac_m, acossack, + [AC_MSG_ERROR([found `acossack' in `\$ac_m' (= `$ac_m')])]) + +ac_asinner=asinner +AC_CHECK_LIB($ac_m, $ac_asinner, + [AC_MSG_ERROR([found `\$ac_asinner' (= `$ac_asinner') in `\$ac_m' (= `$at_m')])]) + +]) + + +# AC_CHECK_DECLS +# -------------- +# Check that it performs the correct actions: +# Must define NEED_NO_DECL, but not NEED_YES_DECL. +AT_CHECK_MACRO([AC_CHECK_DECLS], +[[AC_CHECK_DECLS([yes, no],,, + [int yes = 1;])]], +[AT_CHECK_DEFINES( +[#define HAVE_DECL_NO 0 +#define HAVE_DECL_YES 1 +])]) + + +# AC_CHECK_FUNCS +# -------------- +# Check that it performs the correct actions: +# Must define HAVE_PRINTF, but not HAVE_AUTOCONF_FTNIRP +AT_CHECK_MACRO([AC_CHECK_FUNCS], +[AC_CHECK_FUNCS(printf autoconf_ftnirp)], +[AT_CHECK_DEFINES( +[/* #undef HAVE_AUTOCONF_FTNIRP */ +#define HAVE_PRINTF 1 +])]) + + +# AC_REPLACE_FUNCS +# ---------------- +# Check that it performs the correct actions: autoconf_ftnirp.c must +# be compiled, and must define HAVE_PRINTF, but not HAVE_AUTOCONF_FTNIRP +# FIXME: Maybe check the traces? +AT_SETUP([AC_REPLACE_FUNCS]) + +AT_DATA([config.in], +[@LIBOBJS@ +]) + +AT_CONFIGURE_AC( +[AC_CONFIG_FILES(config.libobjs:config.in) +AC_REPLACE_FUNCS(printf autoconf_ftnirp)]) + +AT_CHECK_AUTOCONF([-W obsolete]) +AT_CHECK_AUTOHEADER +AT_CHECK_CONFIGURE +AT_CHECK_ENV +AT_CHECK_DEFINES( +[/* #undef HAVE_AUTOCONF_FTNIRP */ +#define HAVE_PRINTF 1 +]) + +AT_CHECK([sed 's/ */ /g;s/^ //;s/ $//' config.libobjs], [], + [autoconf_ftnirp.o +]) + +AT_CLEANUP([config.libobjs]) + + +# AC_CHECK_HEADERS +# ---------------- +# Check that it performs the correct actions: +# Must define HAVE_STDIO_H, but not HAVE_AUTOCONF_IO_H. +AT_CHECK_MACRO([AC_CHECK_HEADERS], +[AC_CHECK_HEADERS(stdio.h autoconf_io.h)], +[AT_CHECK_DEFINES( +[/* #undef HAVE_AUTOCONF_IO_H */ +#define HAVE_STDIO_H 1 +])]) + + +# AC_CHECK_MEMBERS +# ---------------- +# Check that it performs the correct actions. +# Must define HAVE_STRUCT_YES_S_YES, but not HAVE_STRUCT_YES_S_NO. +AT_CHECK_MACRO([AC_CHECK_MEMBERS], +[[AC_CHECK_MEMBERS([struct yes_s.yes, struct yes_s.no],,, + [struct yes_s { int yes ;} ;])]], +[AT_CHECK_DEFINES( +[/* #undef HAVE_STRUCT_YES_S_NO */ +#define HAVE_STRUCT_YES_S_YES 1 +])]) + + +# AC_CHECK_SIZEOF +# --------------- +AT_CHECK_MACRO([AC_CHECK_SIZEOF], +[[AC_CHECK_SIZEOF(char) +AC_CHECK_SIZEOF(charchar,, +[[#include <stdio.h> +typedef char charchar[2];]]) +AC_CHECK_SIZEOF(charcharchar) + +# Exercise the code used when cross-compiling +cross_compiling=yes +AC_CHECK_SIZEOF(unsigned char) +AC_CHECK_SIZEOF(ucharchar,, +[[#include <stdio.h> +typedef unsigned char ucharchar[2];]]) +AC_CHECK_SIZEOF(ucharcharchar)]], +[AT_CHECK_DEFINES( +[#define SIZEOF_CHAR 1 +#define SIZEOF_CHARCHAR 2 +#define SIZEOF_CHARCHARCHAR 0 +#define SIZEOF_UCHARCHAR 2 +#define SIZEOF_UCHARCHARCHAR 0 +#define SIZEOF_UNSIGNED_CHAR 1 +])]) + + +# AC_CHECK_TYPES +# -------------- +# Check that it performs the correct actions. +# Must define HAVE_STRUCT_YES_S, HAVE_INT, but not HAVE_STRUCT_NO_S. +# `int' and `struct yes_s' are both checked to test both the compiler +# builtin types, and defined types. +AT_CHECK_MACRO([AC_CHECK_TYPES], +[[AC_CHECK_TYPES([int, struct yes_s, struct no_s],,, + [struct yes_s { int yes ;} ;])]], +[AT_CHECK_DEFINES( +[#define HAVE_INT 1 +/* #undef HAVE_STRUCT_NO_S */ +#define HAVE_STRUCT_YES_S 1 +])]) + + +# AC_CHECK_TYPES +# -------------- +# Check that we properly dispatch properly to the old implementation +# or to the new one. +AT_SETUP([AC_CHECK_TYPES: backward compatibility]) + +AT_DATA(configure.ac, +[[AC_INIT +define([_AC_CHECK_TYPE_NEW], [NEW]) +define([_AC_CHECK_TYPE_OLD], [OLD]) +#(cut-from-here +AC_CHECK_TYPE(ptrdiff_t) +AC_CHECK_TYPE(ptrdiff_t, int) +AC_CHECK_TYPE(quad, long long) +AC_CHECK_TYPE(table_42, [int[42]]) +# Nice machine! +AC_CHECK_TYPE(uint8_t, uint65536_t) +AC_CHECK_TYPE(a,b,c,d) +#to-here) +AC_OUTPUT +]]) + +AT_CHECK_AUTOCONF +AT_CHECK([[sed -e '/^#(cut-from-here/,/^#to-here)/!d' -e '/^#/d' configure]], + 0, + [NEW +OLD +OLD +OLD +OLD +NEW +]) + +AT_CLEANUP + + +# AC_CHECK_FILES +# -------------- +# FIXME: To really test HAVE_AC_EXISTS2 and HAVE_AC_MISSING2 we need to +# open AH_TEMPLATE to `configure.ac', which is not yet the case. +AT_CHECK_MACRO([AC_CHECK_FILES], +[touch at-exists1 at-exists2 +ac_exists2=at-exists2 +ac_missing2=at-missing2 +AC_CHECK_FILES(at-exists1 at-missing1 $ac_exists2 $ac_missing2) +rm at-exists1 at-exists2], +[AT_CHECK_DEFINES( +[#define HAVE_AT_EXISTS1 1 +/* #undef HAVE_AT_MISSING1 */ +])]) + + + +## ------------------------------ ## +## AC_CHECK_PROG & AC_PATH_PROG. ## +## ------------------------------ ## + + +# AT_CHECK_PROGS_PREPARE +# ---------------------- +# Create a sub directory `path' with 6 subdirs which all 7 contain +# an executable `tool'. `6' contains a `better' tool. +m4_define([AT_CHECK_PROGS_PREPARE], +[mkdir path + +cat >path/tool <<\EOF +#! /bin/sh +exit 0 +EOF +chmod +x path/tool + +for i in 1 2 3 4 5 6 +do + mkdir path/$i + cp path/tool path/$i +done +cp path/tool path/6/better]) + + +# -------------------------------- # +# AC_CHECK_PROG & AC_CHECK_PROGS. # +# -------------------------------- # + +AT_SETUP([AC_CHECK_PROG & AC_CHECK_PROGS]) + +AT_CHECK_PROGS_PREPARE + +AT_DATA(configure.ac, +[[AC_INIT +pwd=`pwd` +p="1${ac_path_separator}2${ac_path_separator}3${ac_path_separator}4${ac_path_separator}5${ac_path_separator}6" +path=`echo $p | sed -e 's,\([[0-9]]\),'"$pwd"'/path/\1,g'` +fail=false + +AC_CHECK_PROG(TOOL1, tool, found, not-found, $path) +test "$TOOL1" = found || fail=: + +# Yes, the semantics of this macro is weird. +AC_CHECK_PROG(TOOL2, tool,, not-found, $path) +test "$TOOL2" = not-found || fail=: + +AC_CHECK_PROG(TOOL3, tool, tool, not-found, $path, $pwd/path/1/tool) +test "$TOOL3" = $pwd/path/2/tool || fail=: + +AC_CHECK_PROG(TOOL4, better, better, not-found, $path, $pwd/path/1/tool) +test "$TOOL4" = better || fail=: + +# When a tool is not found, and no value is given for not-found, +# the variable is left empty. +AC_CHECK_PROGS(TOOL5, missing,, $path) +test -z "$TOOL5" || fail=: + +AC_CHECK_PROGS(TOOL6, missing tool better,, $path) +test "$TOOL6" = tool || fail=: + +# No AC-OUTPUT, we don't need config.status. +$fail && + AC_MSG_ERROR([[CHECK_PROG failed]]) +AS_EXIT(0) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_CLEANUP(path) + + +# ------------------------------ # +# AC_PATH_PROG & AC_PATH_PROGS. # +# ------------------------------ # + +AT_SETUP(AC_PATH_PROG & AC_PATH_PROGS) + +AT_CHECK_PROGS_PREPARE + +AT_DATA(configure.ac, +[[AC_INIT +pwd=`pwd` +p="1${ac_path_separator}2${ac_path_separator}3${ac_path_separator}4${ac_path_separator}5${ac_path_separator}6" +path=`echo $p | sed -e 's,\([[0-9]]\),'"$pwd"'/path/\1,g'` +fail=false + +AC_PATH_PROG(TOOL1, tool, not-found, $path) +test "$TOOL1" = $pwd/path/1/tool || fail=: + +AC_PATH_PROG(TOOL2, better, not-found, $path) +test "$TOOL2" = $pwd/path/6/better || fail=: + +# When a tool is not found, and no value is given for not-found, +# the variable is left empty. +AC_PATH_PROGS(TOOL3, missing,, $path) +test -z "$TOOL3" || fail=: + +AC_PATH_PROGS(TOOL4, missing tool better,, $path) +test "$TOOL4" = $pwd/path/1/tool || fail=: + +# No AC-OUTPUT, we don't need config.status. +$fail && + AC_MSG_ERROR([[PATH_PROG failed]]) +AS_EXIT(0) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_CLEANUP(path) + + + + +## -------------- ## +## AC_PATH_XTRA. ## +## -------------- ## + + +AT_SETUP([AC_PATH_XTRA]) + +_AT_CHECK_AC_MACRO([AC_PATH_XTRA]) + +# Check X_DISPLAY_MISSING. +AT_CHECK_CONFIGURE([--without-x]) +AT_CHECK_DEFINES( +[#define X_DISPLAY_MISSING 1 +]) + +AT_CLEANUP + + +## ------------------------------- ## +## Obsolete non-updatable macros. ## +## ------------------------------- ## + + +AT_CHECK_MACRO([AC_SYS_RESTARTABLE_SYSCALLS], , ,[-W no-obsolete]) +AT_CHECK_MACRO([AC_FUNC_WAIT3], , ,[-W no-obsolete]) diff --git a/tests/suite.at b/tests/suite.at new file mode 100644 index 0000000..88f64fa --- /dev/null +++ b/tests/suite.at @@ -0,0 +1,53 @@ +# Validation suite for Autoconf -*- Autoconf -*- +# Copyright 2010 Thomas E. Dickey +# Copyright 2000 Free Software Foundation, Inc. + +# Still many parts of `autoconf' are not exercised by the test suite. A few +# FIXME's, below, are used to list tests that we would need. Do you feel +# like contributing new tests? If you do, you may tell your intent to +# `autoconf@gnu.org', so no two people work at the same thing. + +AT_INIT([autoconf]) + +AT_BANNER( +[Some tests might be skipped if you don't have the software which the +macros check (e.g., a Fortran compiler).]) + +# Run the tests from the lowest level to the highest level, and from +# the most selective to the easiest. + +# The executables. +# Even the tests on M4sugar and M4sh use `autoconf', so check it first. +m4_include([tools.at]) + +# M4sugar. +m4_include([m4sugar.at]) + +# M4sh.m4. +m4_include([m4sh.at]) + +# Autoconf base macros. +m4_include([base.at]) + +# Testing config.status +# --------------------- +# Actually should be named config.status.at but I fear problems with +# the name. Does no `checking...' at all, but exercises only code +# which following section use too. Hence, run it first. +m4_include([torture.at]) + +# Checking AC_PROG_CC, AC_COMPILE_IFELSE etc. +m4_include([compile.at]) + +# Checking that AC_CHECK_FOO macros work properly. +m4_include([semantics.at]) + +# Blind testing the macros. +# Include them as is suggested for a `configure.ac', as looking for +# for types requires looking for headers etc. +m4_include([acgeneral.at]) +m4_include([acspecific.at]) +m4_include([aclang.at]) +m4_include([acheaders.at]) +m4_include([actypes.at]) +m4_include([acfunctions.at]) diff --git a/tests/tools.at b/tests/tools.at new file mode 100644 index 0000000..7c953b2 --- /dev/null +++ b/tests/tools.at @@ -0,0 +1,490 @@ +# -*- autoconf -*- + +AT_BANNER([Executables (autoheader, autoupdate...).]) + +## -------------------------------------------------------- ## +## Check that the shell scripts are syntactically correct. ## +## -------------------------------------------------------- ## + +# We use `/bin/sh -n script' to check that there are no syntax errors +# in the scripts. Although incredible, there are /bin/sh that go into +# endless loops with `-n', e.g., SunOS's: +# +# $ uname -a +# SunOS ondine 4.1.3 2 sun4m unknown +# $ cat endless.sh +# while false +# do +# : +# done +# exit 0 +# $ time sh endless.sh +# sh endless.sh 0,02s user 0,03s system 78% cpu 0,064 total +# $ time sh -nx endless.sh +# ^Csh -nx endless.sh 3,67s user 0,03s system 63% cpu 5,868 total +# +# So before using `/bin/sh -n' to check our scripts, we first check +# that `/bin/sh -n' is not broken to death. + +AT_SETUP([Syntax of the scripts]) + +# A script that never returns. We don't care that it never returns, +# broken /bin/sh loop equally with `false', but it makes it easier to +# test the robusteness in a good environment: just remove the `-n'. +AT_DATA(endless.sh, +[[while : +do + : +done +]]) + +# A script in charge of testing `/bin/sh -n'. +AT_DATA(syntax.sh, +[[(/bin/sh -n endless.sh) & +sleep 2 +if kill $! >/dev/null 2>&1; then + # We managed to kill the child, which means that we probably + # can't trust `/bin/sh -n', hence the test failed. + exit 77 +fi +]]) + +# If we can't trust sh, just skip. +AT_CHECK([/bin/sh ./syntax.sh]) + +# Specify the path to the tool, some shells don't honor PATH when +# running `sh PROG'. + +AT_CHECK([/bin/sh -n ../autoconf], 0) +AT_CHECK([/bin/sh -n ../autoreconf], 0) +AT_CHECK([/bin/sh -n ../ifnames], 0) + +# These are not built, they are in the src tree. +AT_CHECK([/bin/sh -n $top_srcdir/config/install-sh], 0) +AT_CHECK([/bin/sh -n $top_srcdir/config/missing], 0) + +AT_CLEANUP + + + + +## ----------------- ## +## AWK portability. ## +## ----------------- ## + +AT_SETUP([AWK portability]) + +AT_DATA([configure.ac], +[]) + +# Skip if we don't have GNU Awk. +AT_CHECK([gawk --version || exit 77], 0, ignore, ignore) + +# Generation of the script. +AT_CHECK([AWK='gawk --posix' autoconf --autoconf-dir .. -l $at_srcdir], 0, + [], []) +# Tracing. +AT_CHECK([AWK='gawk --posix' autoconf --autoconf-dir .. -l $at_srcdir -t AC_INIT], 0, + ignore, []) +# Syntax correctness of ifnames. +AT_CHECK([AWK='gawk --posix' ifnames /dev/null], 0, + [], []) + +AT_CLEANUP(configure) + + + + + + +## ------------------ ## +## autoconf --trace. ## +## ------------------ ## + + +# autoconf --trace: user macros +# ----------------------------- +AT_SETUP([autoconf --trace: user macros]) + +AT_DATA(configure.ac, +[[m4_define([active], [ACTIVE]) +m4_define([TRACE1], [TRACE2(m4_shift($@))]) +m4_define([TRACE2], [[$2], $1]) +TRACE1(foo, bar, baz) +TRACE1(foo, TRACE1(bar, baz)) +TRACE1(foo, active, baz) +TRACE1(foo, [active], TRACE1(active, [active])) +]]) + +# Several --traces. +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir -t TRACE1 -t TRACE2], 0, +[[configure.ac:4:TRACE1:foo:bar:baz +configure.ac:4:TRACE2:bar:baz +configure.ac:5:TRACE1:bar:baz +configure.ac:5:TRACE2:baz +configure.ac:5:TRACE1:foo::baz +configure.ac:5:TRACE2::baz +configure.ac:6:TRACE1:foo:ACTIVE:baz +configure.ac:6:TRACE2:ACTIVE:baz +configure.ac:7:TRACE1:ACTIVE:active +configure.ac:7:TRACE2:active +configure.ac:7:TRACE1:foo:active::ACTIVE +configure.ac:7:TRACE2:active::ACTIVE +]]) + +# Several line requests. +AT_CHECK([[autoconf --autoconf-dir .. -l $at_srcdir -t TRACE1:' +[$1], [$2], [$3].']], 0, +[[ +[foo], [bar], [baz]. + +[bar], [baz], []. + +[foo], [], [baz]. + +[foo], [ACTIVE], [baz]. + +[ACTIVE], [active], []. + +[foo], [active], []. +]]) + +# ${sep}@. +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir -t TRACE2:'${)===(}@'], 0, +[[[bar])===([baz] +[baz] +[])===([baz] +[ACTIVE])===([baz] +[active] +[active])===([])===([ACTIVE] +]]) + +AT_CLEANUP + + +# autoconf --trace: builtins +# -------------------------- +AT_SETUP([autoconf --trace: builtins]) + +AT_DATA(configure.ac, +[[define([active], [ACTIVE]) +]]) + +AT_CHECK([[autoconf --autoconf-dir .. -l $at_srcdir -t define | + sed -n '$p']], + 0, +[[configure.ac:1:define:active:ACTIVE +]]) + +# FIXME: Without `$1' the following test dies. Groumphf, once again to +# dive into obscure feature interaction... +# Note that using `-i' means we need the *.m4 files, not the *.m4f files, +# hence we need srcdir, not builddir. +AT_CHECK([[autoconf --autoconf-dir $top_srcdir -l $at_srcdir -t define:'$1' -i| + sed -n '$p']], + 0, +[[active +]]) + +AT_CLEANUP + + + + +## ---------------------------- ## +## autoconf: forbidden tokens. ## +## ---------------------------- ## + +# autoconf: forbidden tokens, basic +# --------------------------------- +AT_SETUP([autoconf: forbidden tokens, basic]) + +AT_DATA([configure.ac], +[[AC_PLAIN_SCRIPT()dnl +AC_FOO +_AC_BAR +m4_foo +_m4_bar +BAC_FOO +B_AC_FOO +AS_FOO +_AS_BAR +]]) + +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir], 1, [], [stderr]) +# The output of autoconf is not deterministic here because it +# uses `for (ind in array)'. So be sure to have a unique representation. +AT_CHECK([sort stderr], 0, +[[configure.ac:2: error: possibly undefined macro: AC_FOO +configure.ac:3: error: possibly undefined macro: _AC_BAR +configure.ac:4: error: possibly undefined macro: m4_foo +configure.ac:7: error: possibly undefined macro: B_AC_FOO +configure.ac:8: error: possibly undefined macro: AS_FOO +configure.ac:9: error: possibly undefined macro: _AS_BAR +]]) + +AT_CLEANUP(configure) + + +# autoconf: forbidden tokens, exceptions +# -------------------------------------- +AT_SETUP([autoconf: forbidden tokens, exceptions]) + +AT_DATA([configure.ac], +[[AC_PLAIN_SCRIPT()dnl + +# This is allowed in spite of the name. +# It is on purpose that we check the case where there are several +# tokens on the same line. +m4_pattern_allow([^AC_ALLOWED$]) +NOT_AC_ALLOWED AC_ALLOWED AC_ALLOWED_NOT + +# Test forbidding. +m4_pattern_forbid([^FORBIDDEN$]) +NOT_FORBIDDEN FORBIDDEN FORBIDDEN_NOT + +# Test Autoconf's patterns. +AC_THIS_IS_INVALID and _AC_THIS_IS_INVALID_TOO +BUT_AZ_THIS_IS_NOT ALTHOUGH_AC_THIS_IS +# This is legal, although there is `AC_DEFINE' in there. +BAC_DEFINE +# AC_THIS_IS_A_COMMENT so just shut up. +It would be very bad if Autoconf forgot to expand [AC_]OUTPUT! +]]) + +AT_CHECK([autoconf --autoconf-dir .. -l $at_srcdir], 1, [], [stderr]) +# The output of autoconf is not deterministic here because it +# uses `for (ind in array)'. So be sure to have a unique representation. +AT_CHECK([sort stderr], 0, +[[configure.ac:10: error: possibly undefined macro: FORBIDDEN +configure.ac:14: error: possibly undefined macro: AC_THIS_IS_INVALID +configure.ac:14: error: possibly undefined macro: _AC_THIS_IS_INVALID_TOO +configure.ac:15: error: possibly undefined macro: ALTHOUGH_AC_THIS_IS +configure.ac:7: error: possibly undefined macro: AC_ALLOWED_NOT +configure.ac:7: error: possibly undefined macro: NOT_AC_ALLOWED +configure:18: error: possibly undefined macro: AC_OUTPUT +]]) + +AT_CLEANUP(configure err) + + + + + +## --------- ## +## ifnames. ## +## --------- ## + +AT_SETUP([ifnames]) + +AT_DATA([iftest1.c], +[[#ifdef DEF1 +#ifndef DEF2 +#if !defined(DEF3) && defined(DEF4) /* but not defined(DEF5) */ + # if SPACES + # if TABS +/* #if C_COMMENTS */ +// #if CXX_COMMENTS +#if LINE1 = \ +LINE2 +#if (VAL1*VAL2)==VAL3+VAL4 /* Not VAL5 !!! */ +]]) + +AT_DATA([iftest2.c], +[[#ifdef IFTEST2 +#if VAL1 +]]) + +AT_CHECK([ifnames iftest1.c iftest2.c], 0, +[DEF1 iftest1.c +DEF2 iftest1.c +DEF3 iftest1.c +DEF4 iftest1.c +IFTEST2 iftest2.c +LINE1 iftest1.c +LINE2 iftest1.c +SPACES iftest1.c +TABS iftest1.c +VAL1 iftest1.c iftest2.c +VAL2 iftest1.c +VAL3 iftest1.c +VAL4 iftest1.c +], []) + +AT_CLEANUP + + + +## ------------ ## +## autoheader. ## +## ------------ ## + +# autoheader is intensively used in its modern form through this +# test suite. But we also have to check that acconfig.h still works. +# autoheader uses autoconf --trace, so traces first. + +AT_SETUP([autoheader]) + +AT_DATA(acconfig.h, +[[/* Define this to whatever you want. */ +#undef this +]]) + + +# 1. Check that `acconfig.h' is still honored. +AT_DATA(configure.ac, +[[AC_INIT +AC_CONFIG_HEADERS(config.h) +AC_DEFINE(this, "whatever you want.") +]]) + +AT_CHECK([autoheader --autoconf-dir .. -<configure.ac], 0, +[[/* config.h.in. Generated automatically from - by autoheader. */ +/* Define this to whatever you want. */ +#undef this +]], ignore) + + +# 2. Check that missing templates are a fatal error. +AT_DATA(configure.ac, +[[AC_INIT +AC_CONFIG_HEADERS(config.h) +AC_DEFINE(that, "whatever you want.") +]]) + +AT_CHECK([autoheader --autoconf-dir .. -<configure.ac], 1, [], +[autoheader: No template for symbol `that' +]) + + +# 3. Check TOP and BOTTOM. +AT_DATA(acconfig.h, +[[/* Top from acconfig.h. */ +@TOP@ +/* Middle from acconfig.h. */ +@BOTTOM@ +/* Bottom from acconfig.h. */ +]]) + +AT_DATA(configure.ac, +[[AC_INIT +AC_CONFIG_HEADERS(config.h) +AH_TOP([Top1 from configure.ac.]) +AH_TOP([Top2 from configure.ac.]) +AH_VERBATIM([Middle], [Middle from configure.ac.]) +AH_BOTTOM([Bottom1 from configure.ac.]) +AH_BOTTOM([Bottom2 from configure.ac.]) +]]) + + +# Yes, that's right: the `middle' part of `acconfig.h' is still before +# the AH_TOP part. But so what, you're not supposed to use the two +# together. +AT_CHECK([autoheader --autoconf-dir .. -<configure.ac], 0, +[[/* config.h.in. Generated automatically from - by autoheader. */ +/* Top from acconfig.h. */ + +/* Middle from acconfig.h. */ + +Top1 from configure.ac. + +Top2 from configure.ac. + +Middle from configure.ac. + +Bottom1 from configure.ac. + +Bottom2 from configure.ac. +/* Bottom from acconfig.h. */ +]], []) + + +AT_CLEANUP + + + + +## ------------ ## +## autoupdate. ## +## ------------ ## + +# Check that AC_CANONICAL_SYSTEM and AC_OUTPUT are properly updated. +AT_SETUP([autoupdate]) + +AT_DATA(configure.ac, +[[AC_INIT(Test, 1.0) +AC_CANONICAL_SYSTEM +dnl The doc says 27 is a valid fubar. +fubar=27 +AC_OUTPUT(Makefile, echo $fubar, fubar=$fubar) +]]) + +AT_DATA([expout], +[[AC_INIT([Test],[1.0]) +AC_CANONICAL_TARGET([]) +dnl The doc says 27 is a valid fubar. +fubar=27 +AC_OUTPUT(Makefile, echo $fubar, fubar=$fubar) +]]) + +# Checking `autoupdate'. +AT_CHECK_AUTOUPDATE +AT_CHECK([cat configure.ac], 0, [expout]) +# Checking that `autoupdate' is idempotent +AT_CHECK([autoupdate --autoconf-dir $top_srcdir], 0, [], + [autoupdate: `configure.ac' is unchanged +]) +AT_CHECK([cat configure.ac], 0, [expout]) + +AT_CLEANUP(configure.ac~) + + +# autoupdating AC_LINK_FILES +# -------------------------- +AT_SETUP([autoupdating AC_LINK_FILES]) + +AT_DATA(configure.ac, +[[AC_INIT +AC_LINK_FILES(dst1 dst2, src1 src2) +AC_OUTPUT +]]) + +AT_DATA(dst1, dst1 +) +AT_DATA(dst2, dst2 +) + +# Checking `autoupdate'. +AT_CHECK_AUTOUPDATE +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE +AT_CHECK([cat src1], 0, [dst1 +]) +AT_CHECK([cat src2], 0, [dst2 +]) + +AT_CLEANUP(src1 src2 configure.ac~) + + +# autoupdating AC_PREREQ +# ---------------------- +AT_SETUP([autoupdating AC_PREREQ]) + +cat >expout <<EOF +AC_PREREQ($at_version) +EOF + +AT_CHECK([autoupdate --version || exit 77], ignore, ignore, ignore) +AT_CHECK([echo "AC_PREREQ(1.0)" | + autoupdate --autoconf-dir $top_srcdir -], + 0, [expout], []) + +AT_CHECK([echo "AC_PREREQ($at_version)" | + autoupdate --autoconf-dir $top_srcdir -], + 0, [expout], []) + +AT_CHECK([echo "AC_PREREQ(999.99)" | + autoupdate --autoconf-dir $top_srcdir -], + 1, [], [ignore]) + +AT_CLEANUP diff --git a/tests/torture.at b/tests/torture.at new file mode 100644 index 0000000..786efd0 --- /dev/null +++ b/tests/torture.at @@ -0,0 +1,478 @@ +# -*- autoconf -*- + +AT_BANNER([[Testing config.status. + +## ---------------------------------------------------------------- ## +## This section of torture tests is trying to make Autoconf produce ## +## failing `configure' scripts, which must never happen. If one of ## +## these tests ever fails, it is extremely important that you ## +## report the failure to dickey@invisible-island.net. ## +## ---------------------------------------------------------------- ##]]) + + +## ------------ ## +## AC_ARG_VAR. ## +## ------------ ## + +# AT_CHECK_AC_ARG_VAR(FIRST-VALUE, SECOND-VALUE) +# ---------------------------------------------- +# Check that AC_ARG_VAR caches the latest values, diagnoses +# inconsistances, and arms config.status. +m4_define([AT_CHECK_AC_ARG_VAR], +[rm -f config.cache + +# Initial value. +m4_ifval([$1], + [precious='$1'; export precious], + [unset precious]) +AT_CHECK_CONFIGURE([--config-cache]) +AT_CHECK([cat file], [], [`$1' +]) + +# Testing --recheck. +unset precious +AT_CHECK([./config.status --recheck], [], [ignore]) +AT_CHECK([./config.status], [], [ignore]) +AT_CHECK([cat file], [], [`$1' +]) + +# Second value. +m4_ifval([$2], + [precious='$2'; export precious], + [unset precious]) +AT_CHECK_CONFIGURE([--config-cache], [1], [], [ignore]) + +])# AT_CHECK_AC_ARG_VAR + + +AT_SETUP([AC_ARG_VAR]) + +# We don't want to run this test if this shell doesn't support +# `unset'. +AT_CHECK([ +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + exit 0 +else + exit 77 +fi +]) + +AT_DATA([configure.ac], +[[AC_INIT +AC_ARG_VAR([precious], [this variable costs a lot]) +AC_OUTPUT(file) +]]) + +AT_DATA([file.in], +[[`@precious@' +]]) + +AT_CHECK_AUTOCONF + +# Set a precious variable +AT_CHECK_AC_ARG_VAR([], [apple of my eye]) + +# Unset a precious variable +AT_CHECK_AC_ARG_VAR([apple of my eye], []) + +# Change a precious variable +AT_CHECK_AC_ARG_VAR([apple of my eye], [orange of my eye]) + +AT_CLEANUP + + + + +## ---------------------------------------------- ## +## AC_CONFIG_FILES, HEADERS, LINKS and COMMANDS. ## +## ---------------------------------------------- ## + +AT_SETUP([AC_CONFIG_FILES, HEADERS, LINKS and COMMANDS]) + +AT_DATA(configure.ac, +[[AC_INIT +rm -rf header var-header file var-file link var-link command var-command +echo 'OK' >input + +# Be sure to also stress the associated INIT-CMDS. +case $what_to_test in + header) + AC_CONFIG_HEADERS(header:input);; + var-header) + AC_CONFIG_HEADERS(var-header:$header_in, [], [header_in=input]);; + + file) + AC_CONFIG_FILES(file:input);; + var-file) + AC_CONFIG_FILES(var-file:$file_in, [], [file_in=input]);; + + command) + AC_CONFIG_COMMANDS(command:input, + [cp input command]);; + var-command) + AC_CONFIG_COMMANDS(var-command:$command_in, + [cp $command_in var-command], [command_in=input]);; + + link) + AC_CONFIG_LINKS(link:input);; + var-link) + AC_CONFIG_LINKS(var-link:$link_in, [], [link_in=input]);; +esac +AC_OUTPUT +]]) + +AT_CHECK_AUTOCONF + + +# AT_CHECK_CONFIG_CREATION(THING = (header | link | file | command)) +# ------------------------------------------------------------------ +# Check that THING and var-THING (which uses variables in AC_CONFIG_THING) +# are properly created, with the right content. +# Use `grep OK' instead of a simple `cat' to avoid banners such as in +# AC_CONFIG_HEADERS. +m4_define([AT_CHECK_CONFIG_CREATION], +[AT_CHECK_CONFIGURE([what_to_test=$1]) +AT_CHECK([ls header var-header file var-file command var-command link var-link 2>/dev/null], + [ignore], [$1 +]) +AT_CHECK([grep OK $1], [], [OK +]) + +AT_CHECK_CONFIGURE([what_to_test=var-$1 --no-create]) +# config.status might be stupidly expecting data on stdin, if it's +# really broken... +AT_CHECK([./config.status var-$1 </dev/null], [], [ignore]) +AT_CHECK([ls header var-header file var-file command var-command link var-link 2>/dev/null], + [ignore], [var-$1 +]) +AT_CHECK([grep OK var-$1], [], [OK +]) +])# AT_CHECK_CONFIG_CREATION + + +# Create a file +AT_CHECK_CONFIG_CREATION(file) + +# Create a header +AT_CHECK_CONFIG_CREATION(header) + +# Execute a command +AT_CHECK_CONFIG_CREATION(command) + +# Create a link +AT_CHECK_CONFIG_CREATION(link) + +AT_CLEANUP(header file link commandvar-header var-file var-link var-command + input) + + + +## ------------------- ## +## Missing templates. ## +## ------------------- ## + +# Check that config.status detects missing input files +AT_SETUP([Missing templates]) + +AT_DATA(configure.ac, +[[AC_INIT +AC_CONFIG_FILES([nonexistent]) +AC_OUTPUT +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE([], [1], [], +[[config.status: error: cannot find input file: nonexistent.in +]]) +# Make sure that the output file doesn't exist +AT_CHECK([test -f nonexistent], 1) + +AT_CLEANUP + + + + +## ---------------------- ## +## configure invocation. ## +## ---------------------- ## + +# Check that `configure' and `config.status' honor their interface. +# +# We run `./configure one=val1 --enable-two=val2 --with-three=val3' +# and verify that (i) `configure' correctly receives the arguments and +# (ii) correctly passes them to `config.status', which we check by +# running `config.status --recheck'. + +AT_SETUP([configure invocation]) + +AT_DATA(configure.ac, +[[AC_INIT +echo "result=$one$enable_two$with_three" +AC_OUTPUT +]]) + +AT_CHECK_AUTOCONF + +AT_CHECK_CONFIGURE([one=one --enable-two=two --with-three=three | + sed -n -e 's/^result=//p'], 0, + [onetwothree +]) +AT_CHECK([./config.status --recheck | sed -n 's/^result=//p'], 0, + [onetwothree +]) + +AT_CHECK_CONFIGURE([one="\"'$ " --enable-two="\" ' $" --with-three=" \"'$"| + sed -n -e 's/^result=//p'], 0, + ["'$ " ' $ "'$ +]) +AT_CHECK([./config.status --recheck | sed -n 's/^result=//p'], 0, + ["'$ " ' $ "'$ +]) + +AT_CLEANUP(configure config.status config.log config.cache) + + + +## -------------------------------------------- ## +## Check that `#define' templates are honored. ## +## -------------------------------------------- ## + +# Use various forms of `#define' templates, and make sure there are no +# problems when a symbol is prefix of another. + +AT_SETUP([#define header templates]) + +AT_DATA([configure.ac], +[[AC_INIT +AC_CONFIG_HEADERS(config.h:config.hin) + +# I18n of dummy variables: their French translations. +AC_DEFINE(foo, toto) +AC_DEFINE(bar, tata) +AC_DEFINE(baz, titi) +AC_DEFINE(fubar, tutu) + +# Symbols which are prefixes of another. +AC_DEFINE(a, A) +AC_DEFINE(aaa, AAA) +AC_DEFINE(aa, AA) +AC_CONFIG_FILES(defs) + +# Things included in confdefs.h, but which make no sense in +# config.h, nor in $DEFS. +cat <<\EOF >>confdefs.h +/* Hi Mum! Look, I'm doing C++! */ +#ifdef __cplusplus +void exit (int status); +#endif +EOF + +# In addition of config.h output a full DEFS +AC_OUTPUT_MAKE_DEFS +DEFS_SAVED=$DEFS +AC_SUBST(DEFS_SAVED) +AC_OUTPUT +]]) + +AT_DATA([defs.in], +[[@DEFS_SAVED@ +]]) + +AT_DATA([config.hin], +[[#define foo 0 +# define bar bar +# define baz "Archimedes was sinking in his baz" +# define fubar tutu +#define a B +#define aa BB +#define aaa BBB +#undef a +#undef aa +#undef aaa +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE + +AT_DATA([expout], +[[/* config.h. Generated automatically by configure. */ +#define foo toto +# define bar tata +# define baz titi +# define fubar tutu +#define a A +#define aa AA +#define aaa AAA +#define a A +#define aa AA +#define aaa AAA +]]) +AT_CHECK([cat config.h], 0, expout) + +# Check the value of DEFS. Note the leading space. +AT_DATA([expout], +[[-Dfoo=toto -Dbar=tata -Dbaz=titi -Dfubar=tutu -Da=A -Daaa=AAA -Daa=AA] +]) + +# Because we strip trailing spaces in `testsuite' we can't leave one in +# expout, hence nuke the one left by AC_OUTPUT_MAKE_DEFS. +AT_CHECK([sed -e 's/ $//' defs], 0, expout) + +AT_CLEANUP + + + +## ------------------------- ## +## Torturing config.status. ## +## ------------------------- ## + +## Require 100 AC_DEFINE and AC_SUBST with a significantly big value. +## This is mostly to check that Autoconf produces portable sed scripts +## in config.status. sed is used to skip the first two lines +## `Generated by...'. + +AT_SETUP([Torturing config.status]) + +dnl The value used as a big value for AC_DEFINE. +dnl Don't use sh active chars here, below it is also used in a sh +dnl assignment. +m4_define([AT_BIG_VALUE], +[This value should be long enough to torture the various limits of sed and other tools used by Autoconf.]) + +m4_define([AT_DESCRIPTION], +[Define to a long string if your `Autoconf' works properly.]) + + +# AT_DUMMY_VAR(NUMBER) +# -------------------- +# Build a name used for AC_SUBST and AC_DEFINE. Put ac_ in it +# so that the check for user name space invasion does not complain +# of the new variables defined. +# +# Note that you should not use the name ac_dummy, because it will be +# turned into ac_uummy during the construction of config.status. Yes, +# this is admittedly a bug, but it would be too hard to fix this. +# There is really no point in AC_DEFINE a var named ac_d.*. +m4_define([AT_DUMMY_VAR], +[ac_Dummy_[]m4_patsubst([000$1], [.*\(...\)$], [\1])]) + + + +AT_DATA([dummy.in], +[m4_for([AT_Count], 1, 100, 1, +[@AT_DUMMY_VAR(AT_Count)@ +])]) + + +# ------------ # +# configure.ac # +# ------------ # + +AT_DATA(configure.ac, +dnl The following lines transfer AT_DUMMY_VAR, AT_DESCRIPTION, and +dnl AT_BIG_VALUE into the configure.ac as AC_DUMMY_VAR etc. +[[m4_define([AC_DUMMY_VAR],] +m4_dquote(m4_defn([AT_DUMMY_VAR]))[)]] + +[[m4_define([AC_DESCRIPTION],] +m4_dquote(m4_defn([AT_DESCRIPTION]))[)]] + +[[m4_define([AC_BIG_VALUE],] +m4_dquote(m4_defn([AT_BIG_VALUE]))[)]] + +[[# AC_DEFUBST(NAME) +# ---------------- +# Related VALUE to NAME both with AC_SUBST and AC_DEFINE. This is +# used in the torture tests. +m4_defun([AC_DEFUBST], +[AC_DUMMY_VAR($1)="AC_BIG_VALUE" +AC_DEFINE_UNQUOTED(AC_DUMMY_VAR($1), "$AC_DUMMY_VAR($1)", + AC_DESCRIPTION) +AC_SUBST(AC_DUMMY_VAR($1))]) + +AC_INIT +AC_CONFIG_HEADERS(config.h:config.hin) +AC_CONFIG_FILES(dummy) +m4_for(AC_Count, 1, 100, 1, + [AC_DEFUBST(AC_Count)]) +AC_OUTPUT +]])# configure.ac + +AT_CHECK_AUTOCONF +AT_CHECK_AUTOHEADER +AT_CHECK_CONFIGURE + +# Checking that AC_DEFINE worked properly. +AT_DATA(expout, +[m4_for(AT_Count, 1, 100, 1, +[ +/* AT_DESCRIPTION */ +[#define] AT_DUMMY_VAR(AT_Count) "AT_BIG_VALUE" +])]) +AT_CHECK([sed -n '3,$ p' config.h], 0, expout) + +# Checking that AC_SUBST worked properly. +AT_DATA(expout, +[m4_for(AT_Count, 1, 100, 1, +[AT_BIG_VALUE +])]) + +AT_CLEANUP(dummy) + + +## -------- ## +## srcdir. ## +## -------- ## + +AT_SETUP([srcdir]) + +rm -rf at-dir +mkdir at-dir +: >at-dir/bar.in +: >foo.in + +AT_DATA([configure.ac], +[[AC_INIT + +AC_CONFIG_FILES([foo at-dir/bar]) + +AC_CONFIG_COMMANDS([report], +[test -f $srcdir/configure.ac || + AC_MSG_ERROR([cannot find $srcdir/configure.ac])], + [srcdir=$srcdir]) + +AC_OUTPUT +rm -rf foo at-dir/bar +]]) + +AT_CHECK_AUTOCONF + +# In place. +AT_CHECK([./configure], [], [ignore]) + +# Relative path. +AT_CHECK([cd at-dir && ../configure], [], [ignore]) + +# Absolute path. +at_here=`pwd` +AT_CHECK([cd at-dir && $at_here/configure], [], [ignore]) + +AT_CLEANUP(at-dir foo.in foo) + + +## ----------------- ## +## Signal handling. ## +## ----------------- ## + +AT_SETUP([Signal handling]) + +AT_DATA([configure.ac], +[[AC_INIT +kill -2 $$ +exit 77 +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE([], 1, ignore, ignore) + +AT_CLEANUP |