Document some recently added macros.

* lib/m4sugar/m4sugar.m4 (m4_map_args_w): Add optional sep
parameter.
* doc/autoconf.texi (Looping constructs) <m4_map_args_sep>
<m4_map_args_w, m4_stack_foreach, m4_stack_foreach_sep>: Document
new macros.
(Set manipulation Macros) <m4_set_map_sep>: Likewise.
* tests/m4sugar.at (m4@&t@_stack, M4 loops): Enhance tests.
* NEWS: Document new macros.

Signed-off-by: Eric Blake <ebb9@byu.net>
This commit is contained in:
Eric Blake 2008-12-19 14:06:46 -07:00
parent 44579b8316
commit 7f4d002958
5 changed files with 129 additions and 30 deletions

View File

@ -1,3 +1,15 @@
2008-12-19 Eric Blake <ebb9@byu.net>
Document some recently added macros.
* lib/m4sugar/m4sugar.m4 (m4_map_args_w): Add optional sep
parameter.
* doc/autoconf.texi (Looping constructs) <m4_map_args_sep>
<m4_map_args_w, m4_stack_foreach, m4_stack_foreach_sep>: Document
new macros.
(Set manipulation Macros) <m4_set_map_sep>: Likewise.
* tests/m4sugar.at (m4@&t@_stack, M4 loops): Enhance tests.
* NEWS: Document new macros.
2008-12-18 Eric Blake <ebb9@byu.net>
Fix separator in m4_stack_foreach_sep.

4
NEWS
View File

@ -27,7 +27,9 @@ GNU Autoconf NEWS - User visible changes.
** The following documented m4sugar macros are new:
m4_chomp m4_curry m4_default_quoted m4_esyscmd_s m4_map_args
m4_map_args_pair m4_set_map
m4_map_args_pair m4_map_args_sep m4_map_args_w m4_set_map
m4_set_map_sep m4_stack_foreach m4_stack_foreach_lifo
m4_stack_foreach_sep m4_stack_foreach_sep_lifo
** The following m4sugar macros are documented now, but in some cases
with slightly different semantics than what the previous

View File

@ -11106,7 +11106,9 @@ Note that for some forms of @var{expression}, it may be faster to use
@defmac m4_foreach_w (@var{var}, @var{list}, @var{expression})
@msindex{foreach_w}
Loop over the white-space-separated list @var{list}, assigning each value
to @var{var}, and expand @var{expression}.
to @var{var}, and expand @var{expression}. If @var{var} is only
referenced once in @var{expression}, it is more efficient to use
@code{m4_map_args_w}.
The deprecated macro @code{AC_FOREACH} is an alias of
@code{m4_foreach_w}.
@ -11179,7 +11181,8 @@ In cases where it is useful to operate on additional parameters besides
the list elements, the macro @code{m4_curry} can be used in @var{macro}
to supply the argument currying necessary to generate the desired
argument list. In the following example, @code{list_add_n} is more
efficient than @code{list_add_x}.
efficient than @code{list_add_x}. On the other hand, using
@code{m4_map_args_sep} can be even more efficient.
@example
m4_define([list], [[1], [2], [3]])dnl
@ -11218,6 +11221,30 @@ m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3], [4])
@end example
@end defmac
@defmac m4_map_args_sep (@ovar{pre}, @ovar{post}, @ovar{sep}, @var{arg}@dots{})
@msindex{map_args_sep}
Expand the sequence @code{@var{pre}[@var{arg}]@var{post}} for each
argument, additionally expanding @var{sep} between arguments. One
common use of this macro is constructing a macro call, where the opening
and closing parentheses are split between @var{pre} and @var{post}; in
particular, @code{m4_map_args([@var{macro}], [@var{arg}])} is equivalent
to @code{m4_map_args_sep([@var{macro}(], [)], [], [@var{arg}])}. This
macro provides the most efficient means for iterating over an arbitrary
list of arguments, particularly when repeatedly constructing a macro
call with more arguments than @var{arg}.
@end defmac
@defmac m4_map_args_w (@var{string}, @ovar{pre}, @ovar{post}, @ovar{sep})
@msindex{map_args_w}
Expand the sequence @code{@var{pre}[word]@var{post}} for each word in
the whitespace-separated @var{string}, additionally expanding @var{sep}
between words. This macro provides the most efficient means for
iterating over a whitespace-separated string. In particular,
@code{m4_map_args_w([@var{string}], [@var{action}(], [)])} is more
efficient than @code{m4_foreach_w([var], [@var{string}],
[@var{action}(m4_defn([var]))])}.
@end defmac
@defmac m4_shiftn (@var{count}, @dots{})
@defmacx m4_shift2 (@dots{})
@defmacx m4_shift3 (@dots{})
@ -11232,6 +11259,47 @@ of @code{m4_shiftn}, introduced in Autoconf 2.62, and are more efficient
for two and three shifts, respectively.
@end defmac
@defmac m4_stack_foreach (@var{macro}, @var{action})
@defmacx m4_stack_foreach_lifo (@var{macro}, @var{action})
@msindex{stack_foreach}
@msindex{stack_foreach_lifo}
For each of the @code{m4_pushdef} definitions of @var{macro}, expand
@var{action} with the single argument of a definition of @var{macro}.
@code{m4_stack_foreach} starts with the oldest definition, while
@code{m4_stack_foreach_lifo} starts with the current definition.
@var{action} should not push or pop definitions of @var{macro}, nor is
there any guarantee that the current definition of @var{macro} matches
the argument that was passed to @var{action}. The macro @code{m4_curry}
can be used if @var{action} needs more than one argument, although in
that case it is more efficient to use @var{m4_stack_foreach_sep}.
Due to technical limitations, there are a few low-level m4sugar
functions, such as @code{m4_pushdef}, that cannot be used as the
@var{macro} argument.
@example
m4_pushdef([a], [1])m4_pushdef([a], [2])dnl
m4_stack_foreach([a], [ m4_incr])
@result{} 2 3
m4_stack_foreach_lifo([a], [ m4_curry([m4_substr], [abcd])])
@result{} cd bcd
@end example
@end defmac
@defmac m4_stack_foreach_sep (@var{macro}, @ovar{pre}, @ovar{post}, @ovar{sep})
@defmacx m4_stack_foreach_sep_lifo (@var{macro}, @ovar{pre}, @ovar{post}, @
@ovar{sep})
@msindex{stack_foreach_sep}
@msindex{stack_foreach_sep_lifo}
Expand the sequence @code{@var{pre}[definition]@var{post}} for each
@code{m4_pushdef} definition of @var{macro}, additionally expanding
@var{sep} between definitions. @code{m4_stack_foreach_sep} visits the
oldest definition first, while @code{m4_stack_foreach_sep_lifo} visits
the current definition first. This macro provides the most efficient
means for iterating over a pushdef stack. In particular,
@code{m4_stack_foreach([@var{macro}], [@var{action}])} is short for
@code{m4_stack_foreach_sep([@var{macro}], [@var{action}(], [)])}.
@end defmac
@node Evaluation Macros
@subsection Evaluation Macros
@ -12071,7 +12139,22 @@ the element passed as an argument. This macro is faster than either
corresponding counterpart of
@code{m4_map_args([@var{action}]m4_set_listc([@var{set}]))} or
@code{m4_set_foreach([@var{set}], [var],
[@var{action}(m4_defn([var]))])}.
[@var{action}(m4_defn([var]))])}. It is possible to use @code{m4_curry}
if more than one argument is needed for @var{action}, although it is
more efficient to use @code{m4_set_map_sep} in that case.
@end defmac
@defmac m4_set_map_sep (@var{set}, @ovar{pre}, @ovar{post}, @ovar{sep})
@msindex{set_map_sep}
For each element in the set @var{set}, expand
@code{@var{pre}[element]@var{post}}, additionally expanding @var{sep}
between elements. Behavior is unspecified if the expansion recursively
lists the contents of @var{set} (although listing other sets
is acceptable), or if it modifies the set in any way other than removing
the element visited by the expansion. This macro provides the most
efficient means for non-destructively visiting the elements of a set; in
particular, @code(m4_set_map([@var{set}], [@var{action}]) is equivalent
to @code{m4_set_map_sep([@var{set}], [@var{action}(], [)])}.
@end defmac
@defmac m4_set_remove (@var{set}, @var{value}, @ovar{if-present}, @

View File

@ -1145,9 +1145,9 @@ m4_define([m4_mapall],
[_m4_foreach([m4_apply([$1],], [)], [], $2)])])
# m4_map_sep(MACRO, SEPARATOR, LIST)
# m4_mapall_sep(MACRO, SEPARATOR, LIST)
# -------------------------------------
# m4_map_sep(MACRO, [SEPARATOR], LIST)
# m4_mapall_sep(MACRO, [SEPARATOR], LIST)
# ---------------------------------------
# Invoke MACRO($1), SEPARATOR, MACRO($2), ..., MACRO($N) where $1,
# $2... $N are the elements of LIST, and are in turn lists appropriate
# for m4_apply. SEPARATOR is expanded, in order to allow the creation
@ -1207,8 +1207,8 @@ m4_define([m4_map_args_pair],
[$1([$3], [$4])[]$0([$1], [$2], m4_shift(m4_shift3($@)))])])
# m4_map_args_sep(PRE, POST, SEP, ARG...)
# ---------------------------------------
# m4_map_args_sep([PRE], [POST], [SEP], ARG...)
# ---------------------------------------------
# Expand PRE[ARG]POST for each argument, with SEP between arguments.
m4_define([m4_map_args_sep],
[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
@ -1219,11 +1219,12 @@ m4_define([m4_map_args_sep],
[$1[$4]$2[]_m4_foreach([$3[]$1], [$2], m4_shift3($@))])])
# m4_map_args_w(STRING, [PRE], [POST])
# ------------------------------------
# m4_map_args_w(STRING, [PRE], [POST], [SEP])
# -------------------------------------------
# Perform the expansion of PRE[word]POST[] for each word in STRING
# separated by whitespace. More efficient than:
# m4_foreach_w([var], [STRING], [PRE[]m4_defn([var])POST])
# Additionally, expand SEP between words.
#
# As long as we have to use m4_bpatsubst to split the string, we might
# as well make it also apply PRE and POST; this avoids iteration
@ -1234,9 +1235,9 @@ m4_define([m4_map_args_sep],
# empty elements and remove the extra layer of quoting.
m4_define([m4_map_args_w],
[_$0(_m4_split([ ]m4_flatten([$1])[ ], [[ ]+],
m4_if(m4_index([$2$3], [\]), [-1], [[$3[]$2]],
[m4_bpatsubst([[$3[]$2]], [\\], [\\\\])])),
m4_len([[]$3]), m4_len([$2[]]))])
m4_if(m4_index([$2$3$4], [\]), [-1], [[$3[]$4[]$2]],
[m4_bpatsubst([[$3[]$4[]$2]], [\\], [\\\\])])),
m4_len([[]$3[]$4]), m4_len([$4[]$2[]]))])
m4_define([_m4_map_args_w],
[m4_substr([$1], [$2], m4_eval(m4_len([$1]) - [$2] - [$3]))])
@ -1262,9 +1263,9 @@ m4_define([m4_stack_foreach_lifo],
[_m4_stack_reverse([$1], [m4_tmp-$1], [$2(_m4_defn([m4_tmp-$1]))])]dnl
[_m4_stack_reverse([m4_tmp-$1], [$1])])
# m4_stack_foreach_sep(MACRO, PRE, POST, SEP)
# m4_stack_foreach_sep_lifo(MACRO, PRE, POST, SEP)
# ------------------------------------------------
# m4_stack_foreach_sep(MACRO, [PRE], [POST], [SEP])
# m4_stack_foreach_sep_lifo(MACRO, [PRE], [POST], [SEP])
# ------------------------------------------------------
# Similar to m4_stack_foreach and m4_stack_foreach_lifo, in that every
# definition of a pushdef stack will be visited. But rather than
# passing the definition as a single argument to a macro, this variant
@ -1280,8 +1281,8 @@ m4_define([m4_stack_foreach_sep_lifo],
[_m4_stack_reverse([m4_tmp-$1], [$1])])
# _m4_stack_reverse(OLD, NEW, ACTION, SEP)
# ----------------------------------------
# _m4_stack_reverse(OLD, NEW, [ACTION], [SEP])
# --------------------------------------------
# A recursive worker for pushdef stack manipulation. Destructively
# copy the OLD stack into the NEW, and expanding ACTION for each
# iteration. After the first iteration, SEP is promoted to the front
@ -2793,8 +2794,8 @@ m4_define([m4_set_contents],
# _m4_set_contents_1(SET)
# _m4_set_contents_1c(SET)
# _m4_set_contents_2(SET, PRE, POST, SEP)
# ---------------------------------------
# _m4_set_contents_2(SET, [PRE], [POST], [SEP])
# ---------------------------------------------
# Expand to a list of quoted elements currently in the set, each
# surrounded by PRE and POST, and moving SEP in front of PRE on
# recursion. To avoid nesting limit restrictions, the algorithm must
@ -2868,9 +2869,9 @@ m4_define([m4_set_dump],
[_m4_popdef([_m4_set_size($1)])])m4_ifdef([_m4_set_cleanup($1)],
[_$0_check], [_$0])([$1], [], [$2])])
# _m4_set_dump(SET, SEP, PREP)
# _m4_set_dump_check(SET, SEP, PREP)
# ----------------------------------
# _m4_set_dump(SET, [SEP], [PREP])
# _m4_set_dump_check(SET, [SEP], [PREP])
# --------------------------------------
# Print SEP and the current element, then delete the element and
# recurse with empty SEP changed to PREP. The check variant checks
# whether the element has been previously removed. Use _m4_defn and
@ -2951,8 +2952,8 @@ m4_define([m4_set_listc],
m4_define([m4_set_map],
[m4_set_map_sep([$1], [$2(], [)])])
# m4_set_map_sep(SET, PRE, POST, SEP)
# -----------------------------------
# m4_set_map_sep(SET, [PRE], [POST], [SEP])
# -----------------------------------------
# For each element of SET, expand PRE[value]POST[], and expand SEP
# between elements.
m4_define([m4_set_map_sep],

View File

@ -60,8 +60,8 @@ m4_copy([abc], [foo])dnl
m4_stack_foreach([foo], [m4_n])
m4_stack_foreach_lifo([foo], [m4_n])
m4_stack_foreach_sep([abc], [ m4_index([abcdefghijkl],], [)])
m4_define([colon], [:])dnl
m4_stack_foreach_sep_lifo([abc], [<], [>], [colon])
m4_define([colon], [:])m4_define([lt], [<])m4_define([gt], [>])dnl
m4_stack_foreach_sep_lifo([abc], [lt], [gt], [colon])
m4_pushdef([xyz], [123])dnl
m4_pushdef([xyz], [456])dnl
m4_define([doit], [[$1](m4_stack_foreach_sep([xyz], [m4_dquote(], [)], [,]))
@ -1029,7 +1029,8 @@ myvar
m4_map_args_w([a b c, d,e f
g], [ ], [|])
m4_map_args_w([a b], [\1], [/])
m4_map_args_w([a b], [/], [\1])
m4_define([dashes], [--])dnl
m4_map_args_w([a b c], [/], [\1], [dashes])
dnl only one side effect expansion, prior to visiting list elements
m4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [m4_errprintn(i)])dnl
dnl shifting forms an important part of loops
@ -1070,7 +1071,7 @@ m4_shiftn(3,1,2,3):m4_shiftn(3,1,2,3,4)
outer value
a| b| c,| d,e| f| g|
\1a/\1b/
/a\1/b\1
/a\1--/b\1--/c\1
::4
:4
]], [[hi