mirror of
git://git.sv.gnu.org/autoconf
synced 2024-11-27 01:49:56 +08:00
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:
parent
44579b8316
commit
7f4d002958
12
ChangeLog
12
ChangeLog
@ -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
4
NEWS
@ -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
|
||||
|
@ -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}, @
|
||||
|
@ -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],
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user