autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC] improve autotest syntax checks


From: Eric Blake
Subject: Re: [RFC] improve autotest syntax checks
Date: Tue, 11 Mar 2008 07:22:53 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080213 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Ralf Wildenhues on 3/7/2008 11:30 AM:
| Hello Eric,
|
| This patch series is OK, but please look at the nits below.
| Thanks for your good work on this!

I'm committing the first two in the series as is, since there were no
nits.  As for the remaining two, here is the revised version for another
round of reviews.  Rather than adding a cleanup parameter to
m4_init/AS_INIT, I made m4_wrap guarantee FIFO behavior and added
m4_wrap_lifo, then used these calls in the proper order.  I tested with
both M4 1.4.10b (where m4wrap is LIFO) and the M4 argv_ref branch (will
become M4 1.4.11 or maybe 1.5, where m4wrap is FIFO).

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkfWh60ACgkQ84KuGfSFAYD3/QCgmrvxEBVs6SpmreqK93sirkhK
bxIAmwS8ltaTOAwOhxr4UIMjJ6PnlTEQ
=QYBZ
-----END PGP SIGNATURE-----
>From aaf35d7985a94338621fe3577003a8c379162252 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Tue, 11 Mar 2008 07:11:44 -0600
Subject: [PATCH] Tweak m4_wrap to force FIFO or LIFO semantics.

* lib/m4sugar/m4sugar.m4 (m4_wrap): Override M4 implementation.
(m4_wrap_lifo, _m4_wrap): New macros.
* lib/m4sugar/m4sh.m4 (AS_INIT): Combine all cleanup into known
order, prior to m4sugar's.
(_AS_DETECT_BETTER_SHELL): Use cleanup parameter, rather than
m4_wrap.
* lib/autotest/general.m4 (AT_INIT): Combine all cleanup into
known order, prior to m4sh's.
* doc/autoconf.texi (Diagnostic Macros) <m4_fatal>: Document
argument.
(Redefined M4 Macros) <m4_wrap>: Rewrite documentation to match
new behavior.
* tests/m4sh.at (AS_INIT cleanup): New test.
* NEWS: Document the change.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog               |   18 ++++++++++++++++++
 NEWS                    |    6 +++++-
 doc/autoconf.texi       |   34 ++++++++++++----------------------
 lib/autotest/general.m4 |    3 ++-
 lib/m4sugar/m4sh.m4     |   10 ++++++----
 lib/m4sugar/m4sugar.m4  |   26 +++++++++++++++++++++++++-
 tests/m4sh.at           |   35 +++++++++++++++++++++++++++++++++--
 7 files changed, 101 insertions(+), 31 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4576d29..94168a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2008-03-11  Eric Blake  <address@hidden>
+
+       Tweak m4_wrap to force FIFO or LIFO semantics.
+       * lib/m4sugar/m4sugar.m4 (m4_wrap): Override M4 implementation.
+       (m4_wrap_lifo, _m4_wrap): New macros.
+       * lib/m4sugar/m4sh.m4 (AS_INIT): Combine all cleanup into known
+       order, prior to m4sugar's.
+       (_AS_DETECT_BETTER_SHELL): Use cleanup parameter, rather than
+       m4_wrap.
+       * lib/autotest/general.m4 (AT_INIT): Combine all cleanup into
+       known order, prior to m4sh's.
+       * doc/autoconf.texi (Diagnostic Macros) <m4_fatal>: Document
+       argument.
+       (Redefined M4 Macros) <m4_wrap>: Rewrite documentation to match
+       new behavior.
+       * tests/m4sh.at (AS_INIT cleanup): New test.
+       * NEWS: Document the change.
+
 2008-03-10  Eric Blake  <address@hidden>
 
        Encode nested autotest data.
diff --git a/NEWS b/NEWS
index d6e3b3b..79d72f1 100644
--- a/NEWS
+++ b/NEWS
@@ -111,6 +111,10 @@ GNU Autoconf NEWS - User visible changes.
      m4_cmp  m4_list_cmp  m4_join  m4_map  m4_map_sep  m4_sign
      m4_text_box  m4_text_wrap  m4_version_compare
 
+   - The m4_wrap macro used to have unspecified order, but now
+     guarantees FIFO order.  m4_wrap_lifo was added to guarantee LIFO
+     order.
+
    - Packages using the undocumented m4sugar macro m4_PACKAGE_VERSION
      should consider using the new AC_AUTOCONF_VERSION instead.
 
@@ -139,7 +143,7 @@ GNU Autoconf NEWS - User visible changes.
 ** The following m4sugar macros are new:
    m4_append_uniq_w  m4_apply  m4_combine  m4_cond  m4_count
    m4_dquote_elt  m4_echo  m4_expand  m4_ignore  m4_make_list  m4_max
-   m4_min  m4_newline  m4_shift2  m4_shift3  m4_unquote
+   m4_min  m4_newline  m4_shift2  m4_shift3  m4_unquote  m4_wrap_lifo
 
 ** Warnings are now generated by default when an installer invokes
    'configure' with an unknown --enable-* or --with-* option.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 4e24e31..3cdad19 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10336,29 +10336,19 @@ diversion stack.
 @end defmac
 
 @defmac m4_wrap (@var{text})
address@hidden m4_wrap_lifo (@var{text})
 @msindex{wrap}
-This macro corresponds to @code{m4wrap}.
address@hidden
+These macros correspond to @code{m4wrap}.  Posix requires arguments of
+multiple wrap calls to be reprocessed at @acronym{EOF} in the same order
+as the original calls (first-in, first-out).  @acronym{GNU} M4 versions
+through 1.4.10, however, reprocess them in reverse order (last-in,
+first-out).  Both orders are useful, therefore, you can rely on
address@hidden to provide FIFO semantics and @code{m4_wrap_lifo} for
+LIFO semantics, regardless of the underlying @acronym{GNU} M4 version.
 
-Posix requires arguments of multiple @code{m4wrap} calls to be
-reprocessed at @acronym{EOF} in the same order as the original calls.
address@hidden M4 versions through 1.4.x, however, reprocess them in
-reverse order.  Your code should not depend on the order.
-
-Also, Posix requires @code{m4wrap} to ignore its second and succeeding
-arguments, but @acronym{GNU} M4 versions through 1.4.x concatenate the
-arguments with intervening spaces.  Your code should not pass more than
-one argument.
-
-You are encouraged to end @var{text} with @samp{[]}, to avoid unexpected
-token pasting between consecutive invocations of @code{m4_wrap}, as in:
-
address@hidden
-m4_define([foo], [bar])
-m4_define([foofoo], [OUCH])
-m4_wrap([foo])
-m4_wrap([foo])
address@hidden
address@hidden example
+Unlike the @acronym{GNU} M4 builtin, these macros only recognize one
+argument, and avoid token pasting between consecutive invocations.
 @end defmac
 
 
@@ -10384,7 +10374,7 @@ guaranteed after @var{message}.
 @end defmac
 
 @anchor{m4_fatal}
address@hidden m4_fatal
address@hidden m4_fatal (@var{message})
 @msindex{fatal}
 Report a severe error @var{message} prefixed with the current location,
 and have @command{autom4te} die.
diff --git a/lib/autotest/general.m4 b/lib/autotest/general.m4
index 98cceae..2f930b5 100644
--- a/lib/autotest/general.m4
+++ b/lib/autotest/general.m4
@@ -194,6 +194,7 @@ m4_define([AT_ordinal], 0)
 m4_define([AT_banner_ordinal], 0)
 m4_define([AT_groups_all], [])
 m4_define([AT_help_all], [])
+m4_wrap([_AT_FINISH])
 AS_INIT[]dnl
 m4_divert_push([DEFAULTS])dnl
 AT_COPYRIGHT(
@@ -403,7 +404,7 @@ esac]
 # Whether -C is in effect.
 at_change_dir=false
 m4_divert_pop([DEFAULTS])dnl
-m4_wrap([m4_divert_text([DEFAULTS],
+m4_define([_AT_FINISH], [m4_divert_text([DEFAULTS],
 [
 # List of the tested programs.
 at_tested='m4_ifdef([AT_tested],
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index 6689e4b..8014f15 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -2,8 +2,8 @@
 # M4 sugar for common shell constructs.
 # Requires GNU M4 and M4sugar.
 #
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free
-# Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# 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
@@ -237,7 +237,7 @@ m4_expand_once([m4_append([_AS_DETECT_SUGGESTED_BODY], [
 # <http://lists.gnu.org/archive/html/autoconf-patches/2006-03/msg00081.html>.
 #
 m4_defun_once([_AS_DETECT_BETTER_SHELL],
-[m4_wrap([m4_divert_text([M4SH-SANITIZE], [
+[m4_append([_AS_CLEANUP], [m4_divert_text([M4SH-SANITIZE], [
 AS_REQUIRE([_AS_UNSET_PREPARE])dnl
 if test "x$CONFIG_SHELL" = x; then
   AS_IF([_AS_RUN([_AS_DETECT_REQUIRED_BODY]) 2>/dev/null],
@@ -1647,7 +1647,9 @@ _AS_RUN([_AS_SHELL_FN_WORK]) || {
 # -------
 # Initialize m4sh.
 m4_define([AS_INIT],
-[m4_init
+[# Wrap our cleanup prior to m4sugar's cleanup.
+m4_wrap([_AS_CLEANUP])
+m4_init
 
 # Forbidden tokens and exceptions.
 m4_pattern_forbid([^_?AS_])
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index cd4a1c6..8d5288f 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -138,7 +138,6 @@ m4_rename_m4([index])
 m4_rename_m4([indir])
 m4_rename_m4([len])
 m4_rename([m4exit], [m4_exit])
-m4_rename([m4wrap], [m4_wrap])
 m4_ifdef([mkstemp],dnl added in M4 1.4.8
 [m4_rename_m4([mkstemp])
 m4_copy([m4_mkstemp], [m4_maketemp])
@@ -607,6 +606,30 @@ m4_define([m4_undefine],
          [m4_fatal([$0: undefined macro: $1])])]dnl
 [m4_builtin([undefine], [$1])])
 
+# _m4_wrap(PRE, POST)
+# -------------------
+# Allows nested calls to m4_wrap within wrapped text.
+m4_define([_m4_wrap],
+[m4_ifdef([$0_text],
+         [m4_define([$0_text], [$1]m4_builtin([defn], [$0_text])[$2])],
+         [m4_builtin([m4wrap], [$0_text(m4_builtin([popdef],
+  [$0_text]))])m4_define([$0_text], [$1$2])])])
+
+# m4_wrap(TEXT)
+# -------------
+# Append TEXT to the list of hooks to be executed at the end of input.
+# Whereas the order of the original may be LIFO in the underlying m4,
+# this version is always FIFO.
+m4_define([m4_wrap],
+[_m4_wrap([], [$1[]])])
+
+# m4_wrap_lifo(TEXT)
+# ------------------
+# Prepend TEXT to the list of hooks to be executed at the end of input.
+# Whereas the order of m4_wrap may be FIFO in the underlying m4, this
+# version is always LIFO.
+m4_define([m4_wrap_lifo],
+[_m4_wrap([$1[]])])
 
 ## ------------------------- ##
 ## 7. Quoting manipulation.  ##
@@ -2215,6 +2238,7 @@ m4_if(m4_sysval, [0], [],
 
 # m4_init
 # -------
+# Initialize the m4sugar language.
 m4_define([m4_init],
 [# All the M4sugar macros start with `m4_', except `dnl' kept as is
 # for sake of simplicity.
diff --git a/tests/m4sh.at b/tests/m4sh.at
index 2b55bc9..29392b0 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -2,8 +2,8 @@
 
 AT_BANNER([M4sh.])
 
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
-# Foundation, Inc.
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# 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
@@ -758,3 +758,34 @@ ok 7
 ]])
 
 AT_CLEANUP
+
+
+## ----------------- ##
+## AS_INIT cleanup.  ##
+## ----------------- ##
+
+AT_SETUP([AS@&address@hidden cleanup])
+
+AT_KEYWORDS([m4@&address@hidden m4@&address@hidden)
+
+AT_DATA_M4SH([script.as], [[dnl
+dnl Registered before AS_INIT's cleanups
+m4_wrap([echo cleanup 1
+])
+AS_INIT
+dnl Registered after AS_INIT's cleanups, thus goes to KILL diversion
+m4_wrap([echo cleanup 2
+])
+dnl Registered before AS_INIT's cleanups
+m4_wrap_lifo([echo cleanup 3
+])
+echo body
+]])
+
+AT_CHECK_M4SH
+AT_CHECK([./script], [], [[body
+cleanup 3
+cleanup 1
+]])
+
+AT_CLEANUP
-- 
1.5.4


>From 3896053aa67797b68ce22c2fcfd916f75c0cb491 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Wed, 5 Mar 2008 13:39:23 -0700
Subject: [PATCH] Improve error messages for common testsuite bugs.

* lib/autotest/general.m4 (_AT_DEFINE_INIT, _AT_DEFINE_SETUP): New
macros for defining order-enforced macros.
(AT_INIT, AT_SETUP, AT_CLEANUP, AT_BANNER, AT_XFAIL_IF)
(AT_CAPTURE_FILE, AT_DATA, AT_CHECK, AT_CHECK_NOESCAPE): Add error
messages when order violations are detected.
* tests/autotest.at (AT_CHECK_AT_SYNTAX): New helper macro.
(AT_SETUP without AT_INIT, AT_BANNER without AT_INIT)
(AT_CLEANUP without AT_INIT, Missing AT_CLEANUP)
(AT_CHECK without AT_SETUP, AT_DATA without AT_SETUP)
(AT_XFAIL_IF without AT_DATA, AT_KEYWORDS without AT_SETUP,
(AT_CLEANUP without AT_SETUP, AT_BANNER inside AT_SETUP)
(AT_SETUP inside AT_SETUP, Multiple AT_INIT)
(Banner-only test suite): New tests.
Reported by Christopher Hulbert.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog               |   16 ++++++++
 lib/autotest/general.m4 |   55 +++++++++++++++++++++--------
 tests/autotest.at       |   89 ++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 144 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 94168a0..c6cc1e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2008-03-11  Eric Blake  <address@hidden>
 
+       Improve error messages for common testsuite bugs.
+       * lib/autotest/general.m4 (_AT_DEFINE_INIT, _AT_DEFINE_SETUP): New
+       macros for defining order-enforced macros.
+       (AT_INIT, AT_SETUP, AT_CLEANUP, AT_BANNER, AT_XFAIL_IF)
+       (AT_CAPTURE_FILE, AT_DATA, AT_CHECK, AT_CHECK_NOESCAPE): Add error
+       messages when order violations are detected.
+       * tests/autotest.at (AT_CHECK_AT_SYNTAX): New helper macro.
+       (AT_SETUP without AT_INIT, AT_BANNER without AT_INIT)
+       (AT_CLEANUP without AT_INIT, Missing AT_CLEANUP)
+       (AT_CHECK without AT_SETUP, AT_DATA without AT_SETUP)
+       (AT_XFAIL_IF without AT_DATA, AT_KEYWORDS without AT_SETUP,
+       (AT_CLEANUP without AT_SETUP, AT_BANNER inside AT_SETUP)
+       (AT_SETUP inside AT_SETUP, Multiple AT_INIT)
+       (Banner-only test suite): New tests.
+       Reported by Christopher Hulbert.
+
        Tweak m4_wrap to force FIFO or LIFO semantics.
        * lib/m4sugar/m4sugar.m4 (m4_wrap): Override M4 implementation.
        (m4_wrap_lifo, _m4_wrap): New macros.
diff --git a/lib/autotest/general.m4 b/lib/autotest/general.m4
index 2f930b5..c4cff41 100644
--- a/lib/autotest/general.m4
+++ b/lib/autotest/general.m4
@@ -181,19 +181,37 @@ m4_define([_AT_NORMALIZE_TEST_GROUP_NUMBER],
   done'
 ])
 
+# _AT_DEFINE_INIT(NAME, [DEFINITION])
+# -----------------------------------
+# Define macro NAME to die if invoked prior to AT_INIT, and to DEFINITION
+# after AT_INIT.
+m4_define([_AT_DEFINE_INIT],
+[m4_define($@)m4_pushdef([$1], [m4_fatal([$1: missing AT_INIT detected])])dnl
+m4_append([_AT_DEFINE_INIT_LIST], [[$1]], [,])])
+
+# _AT_DEFINE_SETUP(NAME, [DEFINITION])
+# -----------------------------------
+# Define macro NAME to die if invoked outside AT_SETUP/AT_CLEANUP, and
+# to DEFINITION otherwise.
+m4_define([_AT_DEFINE_SETUP],
+[m4_define([$1], [m4_ifndef([AT_ingroup],
+ [m4_fatal([$1: missing AT_SETUP detected])])$2])])
+
 
 # AT_INIT([TESTSUITE-NAME])
 # -------------------------
 # Begin test suite.
 m4_define([AT_INIT],
-[m4_pattern_forbid([^_?AT_])
+[m4_pushdef([AT_INIT], [m4_fatal([$0: invoked multiple times])])
+m4_pattern_forbid([^_?AT_])
 m4_pattern_allow([^_AT_T_EOF$])
 m4_define([AT_TESTSUITE_NAME],
-         m4_defn([AT_PACKAGE_STRING])[ test suite]m4_ifval([$1], [: $1]))
+  m4_defn([AT_PACKAGE_STRING])[ test suite]m4_ifval([$1], [m4_expand([: $1])]))
 m4_define([AT_ordinal], 0)
 m4_define([AT_banner_ordinal], 0)
 m4_define([AT_groups_all], [])
 m4_define([AT_help_all], [])
+m4_foreach([AT_name], [_AT_DEFINE_INIT_LIST], [m4_popdef(m4_defn([AT_name]))])
 m4_wrap([_AT_FINISH])
 AS_INIT[]dnl
 m4_divert_push([DEFAULTS])dnl
@@ -404,7 +422,9 @@ esac]
 # Whether -C is in effect.
 at_change_dir=false
 m4_divert_pop([DEFAULTS])dnl
-m4_define([_AT_FINISH], [m4_divert_text([DEFAULTS],
+m4_define([_AT_FINISH],
+[m4_ifdef([AT_ingroup], [m4_fatal([missing AT_CLEANUP detected])])dnl
+m4_divert_text([DEFAULTS],
 [
 # List of the tested programs.
 at_tested='m4_ifdef([AT_tested],
@@ -1401,8 +1421,10 @@ $1])])# AT_COPYRIGHT
 # ---------------------
 # Start a group of related tests, all to be executed in the same subshell.
 # The group is testing what DESCRIPTION says.
-m4_define([AT_SETUP],
-[m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])])
+_AT_DEFINE_INIT([AT_SETUP],
+[m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])],
+  [m4_define([AT_ingroup])])
+m4_ifdef([AT_keywords], [m4_undefine([AT_keywords])])
 m4_define([AT_capture_files], [])
 m4_define([AT_line], AT_LINE)
 m4_define([AT_xfail], [at_xfail=no])
@@ -1426,7 +1448,7 @@ m4_divert_push([TEST_SCRIPT])dnl
 # -----------------------------
 # Set up the test to be expected to fail if SHELL-EXPRESSION evaluates to
 # true (exitcode = 0).
-m4_define([AT_XFAIL_IF],
+_AT_DEFINE_SETUP([AT_XFAIL_IF],
 [dnl
 dnl Try to limit the amount of conditionals that we emit.
 m4_case([$1],
@@ -1442,7 +1464,7 @@ m4_case([$1],
 # ---------------------
 # Declare a list of keywords associated to the current test group.
 # The list is stored in lower case, since the -k option is case-insensitive.
-m4_define([AT_KEYWORDS],
+_AT_DEFINE_SETUP([AT_KEYWORDS],
 [m4_append_uniq_w([AT_keywords], m4_tolower([[$1]]))])
 
 
@@ -1450,7 +1472,7 @@ m4_define([AT_KEYWORDS],
 # ---------------------
 # If the current test group does not behave as expected, save the contents of
 # FILE in the test suite log.
-m4_define([AT_CAPTURE_FILE],
+_AT_DEFINE_SETUP([AT_CAPTURE_FILE],
 [m4_append_uniq([AT_capture_files], ["$1"], [ \
 ])])
 
@@ -1458,8 +1480,10 @@ m4_define([AT_CAPTURE_FILE],
 # AT_CLEANUP
 # ----------
 # Complete a group of related tests.
-m4_define([AT_CLEANUP],
-[m4_append([AT_help_all],
+_AT_DEFINE_INIT([AT_CLEANUP],
+[m4_ifdef([AT_ingroup], [m4_undefine([AT_ingroup])],
+  [m4_fatal([$0: missing AT_SETUP detected])])dnl
+m4_append([AT_help_all],
 m4_defn([AT_ordinal]);m4_defn([AT_line]);m4_defn([AT_description]);dnl
 m4_ifdef([AT_keywords], [m4_defn([AT_keywords])]);
 )dnl
@@ -1484,8 +1508,9 @@ m4_divert_pop([TEST_GROUPS])dnl Back to KILL.
 # Start a category of related test groups.  If multiple groups are executed,
 # output TEXT as a banner without any shell expansion, prior to any test
 # from the category.  If TEXT is empty, no banner is printed.
-m4_define([AT_BANNER],
-[m4_define([AT_banner_ordinal], m4_incr(AT_banner_ordinal))
+_AT_DEFINE_INIT([AT_BANNER],
+[m4_ifdef([AT_ingroup], [m4_fatal([$0: nested AT_SETUP detected])])dnl
+m4_define([AT_banner_ordinal], m4_incr(AT_banner_ordinal))
 m4_divert_text([BANNERS],
 address@hidden:@ Banner AT_banner_ordinal. AT_LINE
 @%:@ Category starts at test group m4_incr(AT_ordinal).
@@ -1499,7 +1524,7 @@ at_banner_text_[]AT_banner_ordinal="AS_ESCAPE([$1])"])dnl
 # an end of line.
 # This macro is not robust to active symbols in CONTENTS *on purpose*.
 # If you don't want CONTENTS to be evaluated, quote it twice.
-m4_define([AT_DATA],
+_AT_DEFINE_SETUP([AT_DATA],
 [cat >$1 <<'_ATEOF'
 $2[]_ATEOF
 ])
@@ -1545,7 +1570,7 @@ $2[]_ATEOF
 # out, since most shells when tracing include subshell traces in stderr.
 # This may cause spurious failures when the test suite is run with `-x'.
 #
-m4_define([AT_CHECK],
+_AT_DEFINE_SETUP([AT_CHECK],
 [_AT_CHECK([$1],[$2],[$3],[$4],[$5],[$6],1)])
 
 # AT_CHECK_NOESCAPE(COMMANDS, [STATUS = 0], STDOUT, STDERR,
@@ -1553,7 +1578,7 @@ m4_define([AT_CHECK],
 # ---------------------------------------------------------
 # Like AT_CHECK, but do not AS_ESCAPE shell metacharacters in the STDOUT
 # and STDERR arguments before running the comparison.
-m4_define([AT_CHECK_NOESCAPE],
+_AT_DEFINE_SETUP([AT_CHECK_NOESCAPE],
 [_AT_CHECK([$1],[$2],[$3],[$4],[$5],[$6])])
 
 
diff --git a/tests/autotest.at b/tests/autotest.at
index fea0adc..3ba3ebf 100644
--- a/tests/autotest.at
+++ b/tests/autotest.at
@@ -81,7 +81,20 @@ AT_INIT([artificial test suite])
 AT_SETUP([my only test])
 $2
 AT_CLEANUP
-]], m4_shift2($@))])
+]], m4_shift2($@))]) # AT_CHECK_AT_TEST
+
+# AT_CHECK_AT_SYNTAX(TITLE, SUITE, MESSAGE)
+# -----------------------------------------
+# Create a test named TITLE that tries compiling SUITE with syntax
+# errors with autotest.  Expect a failed compilation, and grep for
+# MESSAGE occuring within the error output.
+m4_define([AT_CHECK_AT_SYNTAX],
+[AT_SETUP([$1])
+AT_CHECK_AT_PREP([micro-suite], [$2], [1], [], [stderr])
+AT_CHECK([grep '$3' stderr], [0], [ignore])
+AT_CLEANUP
+])# AT_CHECK_AT_SYNTAX
+
 
 # AT_NO_CMDSUBST
 # --------------
@@ -109,12 +122,86 @@ AT_CHECK_AT([Empty test suite],
 [[AT_INIT([empty test suite])
 ]])
 
+AT_CHECK_AT([Banner-only test suite],
+[[AT_INIT([empty test suite])
+AT_BANNER([banner])
+]])
+
 # Next level of emptiness.
 AT_CHECK_AT_TEST([Empty test], [])
 
 # And finally, an empty check should not cause a syntax error.
 AT_CHECK_AT_TEST([Empty check], [AT_CHECK])
 
+# Check for sensible error messages for common bugs.
+AT_CHECK_AT_SYNTAX([AT@&address@hidden without AT@&address@hidden,
+[[AT_SETUP([only test])
+AT_CHECK([:])
+AT_CLEANUP
+]], [AT@&address@hidden: missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden without AT@&address@hidden,
+[[AT_BANNER([just a banner])
+]], [AT@&address@hidden: missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden without AT@&address@hidden,
+[[AT_CLEANUP
+]], [AT@&address@hidden: missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([Missing AT@&address@hidden,
+[[AT_INIT([incomplete test suite])
+AT_SETUP([only test])
+AT_CHECK([:])
+]], [missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden without AT@&address@hidden,
+[[AT_INIT([incomplete test suite])
+AT_CHECK([:])
+]], [AT@&address@hidden: missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden without AT@&address@hidden,
+[[AT_INIT([incomplete test suite])
+AT_DATA([file])
+]], [AT@&address@hidden: missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden without AT@&address@hidden,
+[[AT_INIT([incomplete test suite])
+AT_XFAIL_IF([:])
+]], [AT@&address@hidden: missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden without AT@&address@hidden,
+[[AT_INIT([incomplete test suite])
+AT_KEYWORDS([keyword])
+]], [AT@&address@hidden: missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden without AT@&address@hidden,
+[[AT_INIT([incomplete test suite])
+AT_CLEANUP
+]], [AT@&address@hidden: missing AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden inside AT@&address@hidden,
+[[AT_INIT([incomplete test suite])
+AT_SETUP([only test])
+AT_BANNER([banner])
+AT_CHECK([:])
+AT_CLEANUP
+]], [AT@&address@hidden: nested AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([AT@&address@hidden inside AT@&address@hidden,
+[[AT_INIT([incomplete test suite])
+AT_SETUP([only test])
+ AT_SETUP([nested test])
+ AT_CHECK([:])
+ AT_CLEANUP
+AT_CHECK([:])
+AT_CLEANUP
+]], [AT@&address@hidden: nested AT@&address@hidden detected])
+
+AT_CHECK_AT_SYNTAX([Multiple AT@&address@hidden,
+[[AT_INIT([[suite, take one]])
+AT_INIT([repeat])
+]], [AT@&address@hidden: invoked multiple times])
+
 # Check for tested programs.  autoconf should only appear once.
 AT_CHECK_AT([Tested programs],
 [[AT_INIT([programs test suite])
-- 
1.5.4


reply via email to

[Prev in Thread] Current Thread [Next in Thread]