From: Eric Blake Date: Tue, 11 Mar 2008 13:11:44 +0000 (-0600) Subject: Tweak m4_wrap to force FIFO or LIFO semantics. X-Git-Tag: v2.62~42 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39ed7a3e198be86c1e8d54a55ce9935784300a28;p=thirdparty%2Fautoconf.git 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) : Document argument. (Redefined M4 Macros) : Rewrite documentation to match new behavior. * tests/m4sh.at (AS_INIT cleanup): New test. * NEWS: Document the change. Signed-off-by: Eric Blake --- diff --git a/ChangeLog b/ChangeLog index 4576d29c..94168a06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2008-03-11 Eric Blake + + 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) : Document + argument. + (Redefined M4 Macros) : Rewrite documentation to match + new behavior. + * tests/m4sh.at (AS_INIT cleanup): New test. + * NEWS: Document the change. + 2008-03-10 Eric Blake Encode nested autotest data. diff --git a/NEWS b/NEWS index d6e3b3b5..79d72f1c 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 4e24e318..95939476 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -10336,29 +10336,21 @@ diversion stack. @end defmac @defmac m4_wrap (@var{text}) +@defmacx m4_wrap_lifo (@var{text}) @msindex{wrap} -This macro corresponds to @code{m4wrap}. +@msindex{wrap_lifo} +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 +@code{m4_wrap} 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. -@acronym{GNU} 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: - -@example -m4_define([foo], [bar]) -m4_define([foofoo], [OUCH]) -m4_wrap([foo]) -m4_wrap([foo]) -@result{}OUCH -@end example +Unlike the @acronym{GNU} M4 builtin, these macros only recognize one +argument, and avoid token pasting between consecutive invocations. On +the other hand, nested calls to @code{m4_wrap} from within wrapped text +work just as in the builtin. @end defmac @@ -10384,7 +10376,7 @@ guaranteed after @var{message}. @end defmac @anchor{m4_fatal} -@defmac m4_fatal +@defmac 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 98cceae7..2f930b5b 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 6689e4b8..8014f155 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], [ # . # 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 cd4a1c6f..9fc72275 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -138,7 +138,7 @@ m4_rename_m4([index]) m4_rename_m4([indir]) m4_rename_m4([len]) m4_rename([m4exit], [m4_exit]) -m4_rename([m4wrap], [m4_wrap]) +m4_undefine([m4wrap]) m4_ifdef([mkstemp],dnl added in M4 1.4.8 [m4_rename_m4([mkstemp]) m4_copy([m4_mkstemp], [m4_maketemp]) @@ -607,6 +607,31 @@ m4_define([m4_undefine], [m4_fatal([$0: undefined macro: $1])])]dnl [m4_builtin([undefine], [$1])]) +# _m4_wrap(PRE, POST) +# ------------------- +# Helper macro for m4_wrap and m4_wrap_lifo. 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 +2240,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 2b55bc9e..dc50942a 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,38 @@ ok 7 ]]) AT_CLEANUP + + +## ----------------- ## +## AS_INIT cleanup. ## +## ----------------- ## + +AT_SETUP([AS@&t@_INIT cleanup]) + +AT_KEYWORDS([m4@&t@_wrap m4@&t@_wrap_lifo]) + +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 However, nested wraps and diversions can still be used +m4_wrap([echo cleanup 3 +m4_divert_text([M4SH-INIT], [echo prep 4 +])])]) +dnl Registered before AS_INIT's cleanups +m4_wrap_lifo([echo cleanup 5 +]) +echo body +]]) + +AT_CHECK_M4SH +AT_CHECK([./script], [], [[prep 4 +body +cleanup 5 +cleanup 1 +]]) + +AT_CLEANUP