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) <m4_do>: Document the
behavior.
* tests/m4sugar.at (m4@&t@_do): New test.

Signed-off-by: Eric Blake <ebb9@byu.net>
This commit is contained in:
Eric Blake 2008-07-29 14:17:03 -06:00
parent 8f5c14ff91
commit a40eef5129
5 changed files with 66 additions and 8 deletions

View File

@ -1,5 +1,14 @@
2008-07-29 Eric Blake <ebb9@byu.net>
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) <m4_do>: 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.

View File

@ -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{})

View File

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

View File

@ -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], [$*])

View File

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