Paolo Bonzini <bonzini <at> gnu.org> writes: > > This patch extracts the pushdef-stack manipulation code of m4_copy into > new general-purpose macros. The resulting m4_copy implementation is quite > elegant, using m4_curry to push new definitions.
In documenting this trick for M4, I noticed that m4_curry and builtins don't mix unless you use M4 1.6 or newer (1.4.x has the limitation that builtins are silently converted to the empty string if passed through a $n reference of a text macro; it took a lot of infrastructure in m4.git branch-1.6 to overcome this limitation, and will be another couple years before we can blindly ask people to use newer m4 than 1.4.x). m4_curry([m4_define], [mylen])(m4_defn([m4_len])) results in mylen defined as [], not a synonym for <m4_len>. I also noticed that Paolo's original suggestion for m4_copy as m4_stack_foreach and m4_curry suffers a similar fate, but fortunately, my rewrite to use the faster m4_stack_foreach_sep has the serendipitous side-effect of avoiding this problem. I'm checking this in to make it clear on the limitations, and ensure we don't regress. From: Eric Blake <[email protected]> Date: Thu, 18 Dec 2008 15:55:58 -0700 Subject: [PATCH] Mention limitation of M4 1.4.x on builtin tokens. * doc/autoconf.texi (Redefined M4 Macros) <m4_dumpdef>: Document ramification of M4 1.4.x's inability to pass builtin tokens through text macros. (Evaluation Macros) <m4_curry>: Likewise. * tests/m4sugar.at (m4@&t...@_defn): Enhance test. * NEWS: Mention subtle change in m4_dumpdef semantics. Signed-off-by: Eric Blake <[email protected]> --- ChangeLog | 8 ++++++++ NEWS | 4 +++- doc/autoconf.texi | 11 +++++++++++ tests/m4sugar.at | 8 ++++++-- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 86c6c4b..c1d367a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2008-12-18 Eric Blake <[email protected]> + Mention limitation of M4 1.4.x on builtin tokens. + * doc/autoconf.texi (Redefined M4 Macros) <m4_dumpdef>: Document + ramification of M4 1.4.x's inability to pass builtin tokens + through text macros. + (Evaluation Macros) <m4_curry>: Likewise. + * tests/m4sugar.at (m4@&t...@_defn): Enhance test. + * NEWS: Mention subtle change in m4_dumpdef semantics. + Document m4_version_prereq. * doc/autoconf.texi (Number processing Macros) <m4_version_prereq>: Add documentation. diff --git a/NEWS b/NEWS index 2e7fa1e..30ac715 100644 --- a/NEWS +++ b/NEWS @@ -29,7 +29,9 @@ GNU Autoconf NEWS - User visible changes. m4_chomp m4_curry m4_default_quoted m4_esyscmd_s m4_map_args m4_map_args_pair m4_set_map -** The following m4sugar macros are documented now: +** The following m4sugar macros are documented now, but in some cases + with slightly different semantics than what the previous + undocumented version had: m4_copy m4_dumpdefs m4_rename m4_version_prereq ** The m4sugar macro m4_expand has been taught to handle unterminated diff --git a/doc/autoconf.texi b/doc/autoconf.texi index aeeb388..1e211a1 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -10563,6 +10563,12 @@ Redefined M4 Macros calls @code{m4_dumpdef} for all of the @code{m4_pushdef} stack of definitions, starting with the current, and silently does nothing if @var{name} is undefined. + +Unfortunately, due to a limitation in M4 1.4.x, any macro defined as a +builtin is output as the empty string. This behavior is rectified by +using M4 1.6 or newer. However, this behavior difference means that +...@code{m4_dumpdef} should only be used while developing m4sugar macros, +and never in the final published form of a macro. @end defmac @defmac m4_esyscmd_s (@var{command}) @@ -11270,6 +11276,11 @@ Evaluation Macros m4_curry([m4_curry], [m4_reverse], [1])([2])([3]) @result{}3, 2, 1 @end example + +Unfortunately, due to a limitation in M4 1.4.x, it is not possible to +pass the definition of a builtin macro as the argument to the output of +...@code{m4_curry}; the empty string is used instead of the builtin token. +This behavior is rectified by using M4 1.6 or newer. @end defmac @defmac m4_do (@var{arg}, @dots{}) diff --git a/tests/m4sugar.at b/tests/m4sugar.at index 36787fc..8a538f0 100644 --- a/tests/m4sugar.at +++ b/tests/m4sugar.at @@ -138,6 +138,7 @@ AT_CHECK([grep 'm4@&t...@_undefine: undefined.*oops' stderr], [0], [ignore]) # Check that pushdef stacks can be renamed. AT_CHECK_M4SUGAR_TEXT([[m4_pushdef([a], [1])dnl m4_pushdef([a], [2])dnl +m4_pushdef([a], m4_defn([m4_divnum]))dnl a b c m4_rename([a], [b])dnl a b c @@ -147,8 +148,11 @@ m4_popdef([b], [c])dnl a b c m4_popdef([b], [c])dnl a b c -]], [[2 b c -a 2 c +m4_popdef([b], [c])dnl +a b c +]], [[0 b c +a 0 c +a 0 0 a 2 2 a 1 1 a b c -- 1.6.0.4
