summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2020-10-10 15:47:01 -0400
committerZack Weinberg <zackw@panix.com>2020-11-30 11:45:27 -0500
commit82bc59ff70c5923a1e3be9953763e080b6634c28 (patch)
tree1220622fee9dd4953f2df93697006e4957098147
parent8bf19fe82e08a98babbbfa5d7b8a42b6ee6b594f (diff)
downloadautoconf-82bc59ff70c5923a1e3be9953763e080b6634c28.tar.gz
Rewrite mktests.sh in Perl.
This is probably marginally faster since it doesn’t have to read the .m4 files twice or muck around with temporary files and subprocesses, but the actual point of this rewrite is that it will make it easier to provide additional arguments to AT_CHECK_MACRO and AT_CHECK_AU_MACRO on a per-macro basis; this capability will be added and used in the next patch. In *this* patch, the ac*.at files are not functionally changed at all. (The comments come out slightly differently, though.) * tests/mktests.sh: Delete and... * tests/mktests.pl: ...rewrite in Perl. * tests/local.mk: Update to match.
-rw-r--r--tests/local.mk6
-rw-r--r--tests/mktests.pl307
-rwxr-xr-xtests/mktests.sh251
3 files changed, 310 insertions, 254 deletions
diff --git a/tests/local.mk b/tests/local.mk
index 93e14ed3..3b8688cf 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -21,7 +21,7 @@
# project, remember to distribute both testsuite and package.m4.
EXTRA_DIST += \
tests/local.at \
- tests/mktests.sh \
+ tests/mktests.pl \
tests/atlocal.in \
tests/wrapper.as \
tests/statesave.m4
@@ -200,10 +200,10 @@ $(TESTSUITE_GENERATED_AT): tests/mktests.stamp
$(MAKE) $(AM_MAKEFLAGS) tests/mktests.stamp; \
fi
-tests/mktests.stamp : tests/mktests.sh $(AUTOCONF_FILES)
+tests/mktests.stamp : tests/mktests.pl $(AUTOCONF_FILES)
@rm -f tests/mktests.tmp
@touch tests/mktests.tmp
- $(SHELL) $(srcdir)/tests/mktests.sh $(AUTOCONF_FILES)
+ $(PERL) $(srcdir)/tests/mktests.pl tests $(AUTOCONF_FILES)
@mv -f tests/mktests.tmp $@
CLEANFILES += tests/mktests.tmp tests/mktests.stamp
diff --git a/tests/mktests.pl b/tests/mktests.pl
new file mode 100644
index 00000000..2571ef21
--- /dev/null
+++ b/tests/mktests.pl
@@ -0,0 +1,307 @@
+#! /usr/bin/perl
+
+# Build some of the Autoconf test files.
+
+# Copyright (C) 2000-2017, 2020 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 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+
+# ac_exclude_list
+# ---------------
+# Check all AC_DEFUN'ed macros with AT_CHECK_MACRO, except these.
+# Not every macro can be run without arguments, and some are already
+# tested elsewhere.
+my @ac_exclude_list = (
+ # Internal macros are used elsewhere.
+ qr/^_?_AC_/,
+
+ # Used in many places.
+ qr/^AC_.*_IFELSE$/,
+ qr/^AC_LANG/,
+ qr/^AC_RUN_LOG$/,
+ qr/^AC_TRY/,
+
+ # Need an argument.
+ qr/^AC_(CANONICALIZE|PREFIX_PROGRAM|PREREQ)$/,
+ qr/^AC_(SEARCH_LIBS|REPLACE_FUNCS)$/,
+ qr/^AC_(CACHE_CHECK|COMPUTE)_INT$/,
+ qr/^AC_ARG_VAR$/,
+ qr/^AC_REQUIRE_SHELL_FN$/,
+
+ # Performed in the semantics tests.
+ qr/^AC_CHECK_(
+ ALIGNOF|DECL|FILE|FUNC|HEADER|LIB|MEMBER
+ |PROG|SIZEOF|(TARGET_)?TOOL|TYPE
+ )S?$/x,
+ qr/^AC_PATH_PROGS_FEATURE_CHECK$/,
+
+ # Fail when the source does not exist.
+ qr/^AC_CONFIG/,
+
+ # AU defined to nothing.
+ qr/^AC_(CYGWIN|CYGWIN32|EMXOS2|MING32|EXEEXT|OBJEXT)$/,
+
+ # Produce "= val" because $1, the variable used to store the result,
+ # is empty.
+ qr/^AC_(F77|FC)_FUNC$/,
+ qr/^AC_FC_(PP_)?SRCEXT$/,
+ qr/^AC_PATH_((TARGET_)?TOOL|PROG)S?$/,
+
+ # Is a number.
+ qr/^AC_FD_CC$/,
+
+ # Obsolete, but needs to be AC_DEFUNed and cannot safely be called
+ # without arguments. Tested in tools.at.
+ qr/^AC_(DIAGNOSE|FATAL|FOREACH|OBSOLETE|WARNING)$/,
+
+ # Require a file that is not shipped with Autoconf. But it should.
+ qr/^AC_FUNC_(GETLOADAVG|FNMATCH_GNU)$/,
+ qr/^AC_REPLACE_FNMATCH$/,
+
+ # Obsolete, checked in semantics.
+ qr/^AC_FUNC_WAIT3$/,
+ qr/^AC_FUNC_SETVBUF_REVERSED$/,
+ qr/^AC_SYS_RESTARTABLE_SYSCALLS$/,
+
+ # Not intended to be invoked at the top level.
+ qr/^AC_INCLUDES_DEFAULT$/,
+
+ # AC_INIT includes all the AC_INIT macros.
+ # There is an infinite m4 recursion if AC_INIT is used twice.
+ qr/^AC_INIT/,
+
+ # Checked in semantics.
+ qr/^AC_(PROG_CC|C_CONST|C_VOLATILE)$/,
+ qr/^AC_PATH_XTRA$/,
+
+ # Use without an argument is obsolete.
+ # Checked in semantics.
+ qr/^AC_PROG_LEX$/,
+
+ # Requires a working C++ compiler, which is not a given.
+ qr/^AC_PROG_CXX_C_O$/,
+
+ # Already tested by AT_CHECK_MACRO.
+ qr/^AC_OUTPUT$/,
+
+ # Tested alongside m4_divert_text.
+ qr/^AC_PRESERVE_HELP_ORDER$/,
+
+ # Tested in erlang.at.
+ qr/^AC_ERLANG_SUBST_(INSTALL_LIB_SUBDIR|ROOT_DIR)$/,
+ qr/^AC_ERLANG_CHECK_LIB$/,
+);
+
+# au_exclude_list
+# ---------------
+# Check all AU_DEFUN'ed macros with AT_CHECK_AU_MACRO, except these.
+my @au_exclude_list = (
+ # Empty.
+ qr/^AC_(C_CROSS|PROG_CC_(C[89]9|STDC))$/,
+
+ # Use AC_REQUIRE.
+ qr/^AC_(CYGWIN|MINGW32|EMXOS2)$/,
+
+ # Already in configure.ac.
+ qr/^AC_(INIT|OUTPUT)$/,
+
+ # AC_LANG_SAVE needs user interaction to be removed.
+ # AC_LANG_RESTORE cannot be used alone.
+ qr/^AC_LANG_(SAVE|RESTORE)$/,
+
+ # Need arguments. Tested in tools.at.
+ qr/^AC_(DIAGNOSE|FATAL|OBSOLETE|WARNING)$/,
+ qr/^AC_(FOREACH|LINK_FILES|PREREQ)$/,
+
+ # Not macros, just mapping from old variable name to a new one.
+ qr/^ac_cv_prog_(gcc|gxx|g77)$/,
+);
+
+
+# skip_macro MACRO, EXCLUDE-LIST
+# ------------------------------
+# Returns truthy if any of the regexes in EXCLUDE-LIST match MACRO.
+sub skip_macro
+{
+ my $macro = shift;
+ for my $pat (@_)
+ {
+ return 1 if $macro =~ $pat;
+ }
+ return 0;
+}
+
+
+# scan_m4_files
+# -------------
+# Scan all of the Autoconf source files and produce lists of macros
+# to be tested
+sub scan_m4_files
+{
+ my @macros_to_test;
+ my %required_macros;
+
+ for my $file (@_)
+ {
+ open my $fh, "<", $file
+ or die "$file: $!\n";
+
+ my (@ac_macros, @au_macros);
+ while (<$fh>)
+ {
+ chomp;
+ s/\bdnl\b.*$//;
+ if (/\bAC_REQUIRE\(\[*([a-zA-Z0-9_]+)/)
+ {
+ $required_macros{$1} = 1;
+ }
+ elsif (/^AC_DEFUN(?:_ONCE)?\(\[*([a-zA-Z0-9_]+)/)
+ {
+ push @ac_macros, $1
+ unless skip_macro $1, @ac_exclude_list;
+ }
+ elsif (/^AU_DEFUN?\(\[*([a-zA-Z0-9_]+)/)
+ {
+ push @au_macros, $1
+ unless skip_macro $1, @au_exclude_list;
+ }
+ }
+ push @macros_to_test, [ $file, \@ac_macros, \@au_macros ];
+ }
+
+ # Filter out macros that are AC_REQUIREd by some other macro;
+ # it's not necessary to test them directly.
+ my @pruned_macros_to_test;
+ for my $elt (@macros_to_test)
+ {
+ my ($file, $ac_macros, $au_macros) = @$elt;
+ my (@pruned_ac_macros, @pruned_au_macros);
+
+ for my $macro (@$ac_macros)
+ {
+ push @pruned_ac_macros, $macro
+ unless defined $required_macros{$macro};
+ }
+ for my $macro (@$au_macros)
+ {
+ push @pruned_au_macros, $macro
+ unless defined $required_macros{$macro};
+ }
+
+ push @pruned_macros_to_test, [
+ $file, \@pruned_ac_macros, \@pruned_au_macros
+ ];
+ }
+
+ return @pruned_macros_to_test;
+}
+
+
+# make_read_only FILE
+# -------------------
+# Make FILE read-only on disk. Also clears the execute and special bits.
+sub make_read_only
+{
+ my $f = shift;
+ my $mode = (stat $f)[2];
+ die "stat($f): $!\n" unless defined $mode;
+ # clear all the bits in $mode except r--r--r--
+ $mode &= 00444;
+ chmod $mode, $f or die "making $f read-only: $!\n";
+}
+
+
+# create_test_files OUTDIR, M4-FILES...
+# -----------------
+# Main loop: for each file listed in M4-FILES, generate an .at file
+# named "ac${file}.at" that does cursory tests on each of the macros
+# defined in $file.
+sub create_test_files
+{
+ my $outdir = shift;
+ if (@_ == 0)
+ {
+ print STDERR "usage: $0 outdir m4-files...\n";
+ exit 1;
+ }
+
+ for my $elt (scan_m4_files @_)
+ {
+ my ($file, $ac_macros, $au_macros) = @$elt;
+
+ my $base = $file;
+ $base =~ s|^.*/([^/.]+)(?:.[^/]*)?$|$1|;
+
+ my $tmpout = "${outdir}/ac${base}.tat";
+ my $out = "${outdir}/ac${base}.at";
+
+ open my $fh, ">", $tmpout
+ or die "$tmpout: $!\n";
+
+ print $fh <<"EOF";
+# -*- autotest -*-
+# Generated by $0 from $file.
+# Do not edit this file by hand.
+
+EOF
+
+ if (@$ac_macros || @$au_macros)
+ {
+ print $fh "AT_BANNER([Testing autoconf/$base macros.])\n";
+
+ if (@$ac_macros)
+ {
+ print $fh "\n# Modern macros.\n";
+ print $fh "AT_CHECK_MACRO([$_])\n" for sort @$ac_macros;
+ }
+ if (@$au_macros)
+ {
+ print $fh "\n# Obsolete macros.\n";
+ print $fh "AT_CHECK_AU_MACRO([$_])\n" for sort @$au_macros;
+ }
+ }
+ else
+ {
+ print $fh "# Nothing to test.\n";
+ }
+
+ close $fh or die "writing to $tmpout: $!\n";
+ make_read_only $tmpout;
+ rename $tmpout, $out or die "updating $out: $!\n";
+ }
+}
+
+create_test_files @ARGV;
+exit 0;
+
+### Setup "GNU" style for perl-mode and cperl-mode.
+## Local Variables:
+## perl-indent-level: 2
+## perl-continued-statement-offset: 2
+## perl-continued-brace-offset: 0
+## perl-brace-offset: 0
+## perl-brace-imaginary-offset: 0
+## perl-label-offset: -2
+## cperl-indent-level: 2
+## cperl-brace-offset: 0
+## cperl-continued-brace-offset: 0
+## cperl-label-offset: -2
+## cperl-extra-newline-before-brace: t
+## cperl-merge-trailing-else: nil
+## cperl-continued-statement-offset: 2
+## End:
diff --git a/tests/mktests.sh b/tests/mktests.sh
deleted file mode 100755
index 34458a27..00000000
--- a/tests/mktests.sh
+++ /dev/null
@@ -1,251 +0,0 @@
-#! /bin/sh
-
-# Build some of the Autoconf test files.
-
-# Copyright (C) 2000-2017, 2020 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 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-# Set locale to C so that `sort' behaves in a uniform way.
-LANGUAGE=C; export LANGUAGE
-LANG=C; export LANG
-LC_ALL=C; export LC_ALL
-
-# Default AWK.
-: ${AWK=awk}
-
-# If we fail, clean up, but touch the output files. We probably failed
-# because we used some non-portable tool.
-
-as_me=`echo "$0" | sed 's|.*[\\/]||'`
-
-outdir=tests
-acdefuns=$outdir/acdefuns.tmp
-audefuns=$outdir/audefuns.tmp
-requires=$outdir/requires.tmp
-
-trap 'echo "'"$as_me"': failed." >&2
- rm -f $acdefuns $audefuns $requires $outdir/*.tat
- trap "" 0
- exit 1' \
- 0 1 2 15
-
-# If ever something goes wrong, fail, so that the trap is launched.
-set -e
-
-# We expect a list of autoconf source files as arguments.
-test $# -gt 0
-
-# requires
-# --------
-# Get the list of macros that are required: there is little interest
-# in testing them since they will be run by the guy who requires them.
-sed -n 's/dnl.*//;s/.*AC_REQUIRE(\[*\([a-zA-Z0-9_]*\).*$/\1/p' "$@" |
- sort -u >$requires
-
-
-# exclude_list
-# ------------
-# Macros which must not be checked at all (not with AT_CHECK_MACRO nor
-# AT_CHECK_AU_MACRO).
-exclude_list='
- # Not a macro name at all.
- /^$/ {next}
-
- # Not macros, just mapping from old variable name to a new one.
- /^ac_cv_prog_(gcc|gxx|g77)$/ {next}
-'
-
-
-# ac_exclude_list
-# ---------------
-# We try to test all the Autoconf macros with AT_CHECK_MACRO to check
-# for syntax problems, etc. Not every macros can be run without
-# arguments, and some are already tested elsewhere. AC_EXCLUDE_LIST
-# filters out the macros we don't want to test.
-ac_exclude_list='
- # Internal macros are used elsewhere.
- /^_?_AC_/ {next}
-
- # Used in many places.
- /^AC_.*_IFELSE$/ {next}
- /^AC_LANG/ {next}
- /^AC_RUN_LOG$/ {next}
- /^AC_TRY/ {next}
-
- # Need an argument.
- /^AC_(CANONICALIZE|PREFIX_PROGRAM|PREREQ)$/ {next}
- /^AC_(SEARCH_LIBS|REPLACE_FUNCS)$/ {next}
- /^AC_(CACHE_CHECK|COMPUTE)_INT$/ {next}
- /^AC_ARG_VAR$/ {next}
- /^AC_REQUIRE_SHELL_FN$/ {next}
-
- # Performed in the semantics tests.
- /^AC_CHECK_(ALIGNOF|DECL|FILE|FUNC|HEADER|LIB|MEMBER|PROG|SIZEOF|(TARGET_)?TOOL|TYPE)S?$/ {next}
- /^AC_PATH_PROGS_FEATURE_CHECK$/ {next}
-
- # Fail when the source does not exist.
- /^AC_CONFIG/ {next}
-
- # AU defined to nothing.
- /^AC_(CYGWIN|CYGWIN32|EMXOS2|MING32|EXEEXT|OBJEXT)$/ {next}
-
- # Produce "= val" because $1, the variable used to store the result,
- # is empty.
- /^AC_(F77|FC)_FUNC$/ {next}
- /^AC_FC_(PP_)?SRCEXT$/ {next}
- /^AC_PATH_((TARGET_)?TOOL|PROG)S?$/ {next}
-
- # Is a number.
- /^AC_FD_CC$/ {next}
-
- # Obsolete, but needs to be AC_DEFUNed and cannot safely be called
- # without arguments. Tested in tools.at.
- /^AC_(DIAGNOSE|FATAL|FOREACH|OBSOLETE|WARNING)$/ {next}
-
- # Require a file that is not shipped with Autoconf. But it should.
- /^AC_FUNC_(GETLOADAVG|FNMATCH_GNU)$/ {next}
- /^AC_REPLACE_FNMATCH$/ {next}
-
- # Obsolete, checked in semantics.
- /^AC_FUNC_WAIT3$/ {next}
- /^AC_FUNC_SETVBUF_REVERSED$/ {next}
- /^AC_SYS_RESTARTABLE_SYSCALLS$/ {next}
-
- # Not intended to be invoked at the top level.
- /^AC_INCLUDES_DEFAULT$/ {next}
-
- # AC_INIT includes all the AC_INIT macros.
- # There is an infinite m4 recursion if AC_INIT is used twice.
- /^AC_INIT/ {next}
-
- # Checked in semantics.
- /^AC_(PROG_CC|C_CONST|C_VOLATILE)$/ {next}
- /^AC_PATH_XTRA$/ {next}
-
- # Use without an argument is obsolete.
- # Checked in semantics.
- /^AC_PROG_LEX$/ {next}
-
- # Requires a working C++ compiler, which is not a given.
- /^AC_PROG_CXX_C_O$/ {next}
-
- # Already tested by AT_CHECK_MACRO.
- /^AC_OUTPUT$/ {next}
-
- # Tested alongside m4_divert_text.
- /^AC_PRESERVE_HELP_ORDER$/ {next}
-
- # Tested in erlang.at.
- /^AC_ERLANG_SUBST_(INSTALL_LIB_SUBDIR|ROOT_DIR)$/ {next}
- /^AC_ERLANG_CHECK_LIB$/ {next}
-'
-
-
-# ac_exclude_script
-# -----------------
-# Build a single awk script out of the above.
-ac_exclude_script="$exclude_list $ac_exclude_list {print}"
-
-
-# au_exclude_list
-# ---------------
-# Check all AU_DEFUN'ed macros with AT_CHECK_AU_MACRO, except these.
-au_exclude_list='
- # Empty.
- /^AC_(C_CROSS|PROG_CC_(C[89]9|STDC))$/ {next}
-
- # Use AC_REQUIRE.
- /^AC_(CYGWIN|MINGW32|EMXOS2)$/ {next}
-
- # Already in configure.ac.
- /^AC_(INIT|OUTPUT)$/ {next}
-
- # AC_LANG_SAVE needs user interaction to be removed.
- # AC_LANG_RESTORE cannot be used alone.
- /^AC_LANG_(SAVE|RESTORE)$/ {next}
-
- # Need arguments. Tested in tools.at.
- /^AC_(DIAGNOSE|FATAL|OBSOLETE|WARNING)$/ {next}
- /^AC_(FOREACH|LINK_FILES|PREREQ)$/ {next}
-'
-
-# au_exclude_script
-# -----------------
-# Build a single awk script out of the above.
-au_exclude_script="$exclude_list $au_exclude_list {print}"
-
-
-## ------------------------- ##
-## Creating the test files. ##
-## ------------------------- ##
-
-for file in "$@"
-do
- base=`echo "$file" | sed 's|.*[\\/]||;s|\..*||'`
- acbase=$outdir/ac$base
- # Get the list of macros which are defined in Autoconf level.
- # Get rid of the macros we are not interested in.
- sed -n -e 's/^AC_DEFUN(\[*\([a-zA-Z0-9_]*\).*$/\1/p' \
- -e 's/^AC_DEFUN_ONCE(\[*\([a-zA-Z0-9_]*\).*$/\1/p' $file |
- $AWK "$ac_exclude_script" |
- sort -u >$acdefuns
-
- # Get the list of macros which are defined in Autoupdate level.
- sed -n 's/^AU_DEFUN(\[*\([a-zA-Z][a-zA-Z0-9_]*\).*$/\1/p' $file |
- $AWK "$au_exclude_script" |
- sort -u >$audefuns
-
- # Filter out required macros.
- {
- sed 's/^ *//' <<MK_EOF
- # Generated by $as_me. -*- Autotest -*-
-
- ## --------------------- ##
- ## Do not edit by hand. ##
- ## --------------------- ##
-
- # Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- # 2010 Free Software Foundation, Inc.
-
- AT_BANNER([Testing autoconf/$base macros.])
-
-MK_EOF
-
- echo "# Modern macros."
- comm -23 $acdefuns $requires | sed 's/.*/AT_CHECK_MACRO([&])/'
- echo
- echo "# Obsolete macros."
- comm -23 $audefuns $requires | sed 's/.*/AT_CHECK_AU_MACRO([&])/'
- } >$acbase.tat
-
- # In one atomic step so that if something above fails, the trap
- # preserves the old version of the file. If there is nothing to
- # check, output /rien du tout/[1].
- if grep AT_CHECK $acbase.tat >/dev/null 2>&1; then
- mv -f $acbase.tat $acbase.at
- else
- rm -f $acbase.tat $acbase.at
- touch $acbase.at
- fi
- # Help people not to update these files by hand.
- chmod a-w $acbase.at
-done
-
-rm -f $acdefuns $audefuns $requires
-
-trap '' 0
-exit 0
-
-# [1] En franc,ais dans le texte.