Eric Blake <ebb9 <at> byu.net> writes: > The new definition of m4_defun_once (which is an alias to AC_DEFUN_ONCE) used > in this patch exploits internal knowledge of m4sugar primitives for optimal m4 > speed; the version of the patch that I am submitting to gnulib does the same > thing, but with a bit more overhead, because it only uses public API available > since at least 2.59.
That patch produced a spurious blank line if you require'd a defun_once macro inside the body of a defun'd macro [1], but not if you directly expanded it [2]; and inconsistent with defun'd macros [3]: m4_defun_once([a],[1])dnl m4_defun_once([b],[2])dnl m4_defun([c],[3])dnl m4_defun([d],[m4_require([a])b[]m4_require([c])4])dnl d 1 2 3 4 I'm applying this, which normalizes the number of newlines when a defun_once macro is hoisted, whether that hoisting occurred from direct expansion or a require. This patch also has the benefit of fewer repetitions of the macro body, for definite memory savings and a slight speedup. More and more, I get the impression that my m4sugar code looks like black magic to the casual onlooker. Apologies to those who think I don't comment my code enough for all the tricks I pull off. Meanwhile, I've applied the patch that fixes Ralf's report about another false positive expand-before-require (in part, because detecting whether we are in a nested require vs. direct expansion in this patch relied on using the variables introduced in the patch for Ralf's issue). I'm also applying the first of my 2- patch series that uses AC_DEFUN_ONCE in more places (ie. AC_CANONICAL_HOST and AC_USE_SYSTEM_EXTENSIONS, but not AC_PROG_MKDIR_P). From: Eric Blake <[email protected]> Date: Wed, 28 Jan 2009 16:14:13 -0700 Subject: [PATCH] Reduce blank lines in AC_DEFUN_ONCE macros. * lib/m4sugar/m4sugar.m4 (m4_defun_once): Avoid redundant blank line when a defun_once macro is required. (_m4_defun_once): New helper macro, for less memory use. * tests/m4sugar.at (m4@&t...@_require: nested): Adjust test. Signed-off-by: Eric Blake <[email protected]> --- ChangeLog | 6 ++++++ lib/m4sugar/m4sugar.m4 | 18 ++++++++++++------ tests/m4sugar.at | 5 +---- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index e50376e..33cadf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-01-28 Eric Blake <[email protected]> + Reduce blank lines in AC_DEFUN_ONCE macros. + * lib/m4sugar/m4sugar.m4 (m4_defun_once): Avoid redundant blank + line when a defun_once macro is required. + (_m4_defun_once): New helper macro, for less memory use. + * tests/m4sugar.at (m4@&t...@_require: nested): Adjust test. + Silence another false positive expand-before-require. * lib/m4sugar/m4sugar.m4 (_m4_defun_pro_outer) (_m4_defun_epi_outer, _m4_require_call, m4_provide): Track name diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4 index 0af1f56..55dc644 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -1939,12 +1939,17 @@ m4_define([m4_defun_init], # # If _m4_divert_dump is empty, we are called at the top level; # otherwise, we must ensure that we are required in front of the -# current defun'd macro. +# current defun'd macro. Use a helper macro so that EXPANSION need +# only occur once in the definition of NAME, since it might be large. m4_define([m4_defun_once], [m4_define([m4_location($1)], m4_location)]dnl -[m4_define([$1], [m4_pushdef([$1])m4_if(_m4_divert_dump, [], - [_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])], - [_m4_require_call([$1], [$2[]m4_provide([$1])], _m4_divert_dump)])])]) +[m4_define([$1], [_m4_defun_once([$1], [$2], m4_if(_m4_divert_dump, [], + [[_m4_defun_pro([$1])m4_unquote(], [)_m4_defun_epi([$1])]], +m4_ifdef([_m4_diverting([$1])], [-]), [-], [[m4_unquote(], [)]], + [[_m4_require_call([$1],], [, _m4_divert_dump)]]))])]) + +m4_define([_m4_defun_once], +[m4_pushdef([$1])$3[$2[]m4_provide([$1])]$4]) # m4_pattern_forbid(ERE, [WHY]) @@ -1978,8 +1983,9 @@ m4_define([m4_before], # ----------------------------------------------------------- # If NAME-TO-CHECK has never been expanded (actually, if it is not # m4_provide'd), expand BODY-TO-EXPAND *before* the current macro -# expansion. Once expanded, emit it in _m4_divert_dump. Keep track -# of the m4_require chain in _m4_expansion_stack. +# expansion; follow the expansion with a newline. Once expanded, emit +# it in _m4_divert_dump. Keep track of the m4_require chain in +# _m4_expansion_stack. # # The normal cases are: # diff --git a/tests/m4sugar.at b/tests/m4sugar.at index 5f3c01f..6286af2 100644 --- a/tests/m4sugar.at +++ b/tests/m4sugar.at @@ -461,8 +461,7 @@ dnl Check m4_defun_once behavior AT_CHECK_M4SUGAR_TEXT([[ m4_defun_once([a], [[a]])dnl m4_defun([b], [[b]m4_require([a])])dnl -m4_defun([c], [[c] -a[]m4_require([b])])dnl +m4_defun([c], [[c]a[]m4_require([b])])dnl c a m4_defun_once([d], [[d]m4_require([a])])dnl @@ -475,10 +474,8 @@ a b c - d e - f ]]) -- 1.6.0.4
