From: Eric Blake Date: Tue, 29 Jul 2008 20:17:03 +0000 (-0600) Subject: Tweak m4_do semantics. X-Git-Tag: v2.63~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a40eef5129fccd8238dfd130d5a0ad9baf296127;p=thirdparty%2Fautoconf.git Tweak m4_do semantics. * lib/m4sugar/m4sugar.m4 (m4_do): Don't concat final argument with subsequent text. * lib/m4sugar/foreach.m4 (m4_do): Don't concat intermediate arguments, and avoid infinite loop. * doc/autoconf.texi (Evaluation Macros) : Document the behavior. * tests/m4sugar.at (m4@&t@_do): New test. Signed-off-by: Eric Blake --- diff --git a/ChangeLog b/ChangeLog index fe6d7b71e..93c8f78e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2008-07-29 Eric Blake + Tweak m4_do semantics. + * lib/m4sugar/m4sugar.m4 (m4_do): Don't concat final argument with + subsequent text. + * lib/m4sugar/foreach.m4 (m4_do): Don't concat intermediate + arguments, and avoid infinite loop. + * doc/autoconf.texi (Evaluation Macros) : Document the + behavior. + * tests/m4sugar.at (m4@&t@_do): New test. + Optimize m4_for. * lib/m4sugar/m4sugar.m4 (m4_for): Use fewer macros. (_m4_for): Take additional parameter, for fewer m4_indir calls. diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 7dc44053f..d27aeb283 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -10882,7 +10882,24 @@ passed. @msindex{do} This macro loops over its arguments and expands each @var{arg} in sequence. Its main use is for readability; it allows the use of -indentation and fewer @code{dnl} to result in the same expansion. +indentation and fewer @code{dnl} to result in the same expansion. This +macro guarantees that no expansion will be concatenated with subsequent +text; to achieve full concatenation, use @code{m4_unquote(m4_join([], +@var{arg@dots{}}))}. + +@example +m4_define([ab],[1])m4_define([bc],[2])m4_define([abc],[3])dnl +m4_do([a],[b])c +@result{}abc +m4_unquote(m4_join([],[a],[b]))c +@result{}3 +m4_define([a],[A])m4_define([b],[B])m4_define([c],[C])dnl +m4_define([AB],[4])m4_define([BC],[5])m4_define([ABC],[6])dnl +m4_do([a],[b])c +@result{}ABC +m4_unquote(m4_join([],[a],[b]))c +@result{}3 +@end example @end defmac @defmac m4_dquote (@var{arg}, @dots{}) diff --git a/lib/m4sugar/foreach.m4 b/lib/m4sugar/foreach.m4 index bedb4f5a4..3997ff27a 100644 --- a/lib/m4sugar/foreach.m4 +++ b/lib/m4sugar/foreach.m4 @@ -141,10 +141,11 @@ m4_define([_m4_shiftn], # unnecessary dnl's and have the macros indented properly. # # Here, we use the temporary macro _m4_do, defined as -# $1$2...$n[]_m4_popdef([_m4_do]) +# $1[]$2[]...[]$n[]_m4_popdef([_m4_do]) m4_define([m4_do], -[m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [1], [$#], [1], - [$_$0])[[]_m4_popdef([_$0])])_$0($@)]) +[m4_if([$#], [0], [], + [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [1], [$#], [1], + [$_$0[[]]])[_m4_popdef([_$0])])_$0($@)])]) # m4_dquote_elt(ARGS) # ------------------- @@ -200,7 +201,7 @@ m4_define([m4_join], # # A bit easier than m4_join. m4_foreach to the rescue. m4_define([m4_joinall], -[[$2]m4_if([$#], [1], [], [$#], [2], [], +[[$2]m4_if(m4_eval([$# <= 2]), [1], [], [m4_foreach([_m4_arg], [m4_shift2($@)], [[$1]_m4_defn([_m4_arg])])])]) diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4 index 11692afe4..b67b1adee 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -692,11 +692,12 @@ m4_define([m4_count], [$#]) # ------------------ # This macro invokes all its arguments (in sequence, of course). It is # useful for making your macros more structured and readable by dropping -# unnecessary dnl's and have the macros indented properly. +# unnecessary dnl's and have the macros indented properly. No concatenation +# occurs after a STRING; use m4_unquote(m4_join(,STRING)) for that. m4_define([m4_do], [m4_if([$#], 0, [], - [$#], 1, [$1], - [$1[]m4_do(m4_shift($@))])]) + [$#], 1, [$1[]], + [$1[]$0(m4_shift($@))])]) # m4_dquote(ARGS) @@ -816,6 +817,8 @@ m4_define([m4_reverse], # expansion. For one argument, m4_unquote([arg]) is more efficient than # m4_do([arg]), but for multiple arguments, the difference is that # m4_unquote separates arguments with commas while m4_do concatenates. +# Follow this macro with [] if concatenation with subsequent text is +# undesired. m4_define([m4_unquote], [$*]) diff --git a/tests/m4sugar.at b/tests/m4sugar.at index 92945a474..ce119e08d 100644 --- a/tests/m4sugar.at +++ b/tests/m4sugar.at @@ -237,6 +237,34 @@ m4_split([a )}@&t@>=- b -=<@&t@{( c]) AT_CLEANUP +## ------- ## +## m4_do. ## +## ------- ## + +AT_SETUP([m4@&t@_do]) + +AT_CHECK_M4SUGAR_TEXT( +[[m4_define([ab], [1])m4_define([bc], [2])m4_define([abc], [3])dnl +m4_define([AB], [4])m4_define([BC], [5])m4_define([ABC], [6])dnl +m4_do +m4_do([a]) +m4_do([a], [b])c +m4_unquote(m4_join([], [a], [b]))c +m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl +m4_do([a], [b])c +m4_unquote(m4_join([], [a], [b]))c +]], +[[ +a +abc +3 +ABC +3 +]]) + +AT_CLEANUP + + ## ----------- ## ## m4_append. ## ## ----------- ##