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 <ebb9@byu.net>
This commit is contained in:
Eric Blake 2008-03-11 07:11:44 -06:00
parent f79a05503d
commit 39ed7a3e19
7 changed files with 109 additions and 31 deletions

View File

@ -1,3 +1,21 @@
2008-03-11 Eric Blake <ebb9@byu.net>
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 <ebb9@byu.net>
Encode nested autotest data.

6
NEWS
View File

@ -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.

View File

@ -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.

View File

@ -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],

View File

@ -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_])

View File

@ -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.

View File

@ -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