Next: Evaluation Macros, Previous: Conditional constructs, Up: Programming in M4sugar [Contents][Index]
The following macros are useful in implementing recursive algorithms in
M4, including loop operations. An M4 list is formed by quoting a list
of quoted elements; generally the lists are comma-separated, although
m4_foreach_w
is whitespace-separated. For example, the list
‘[[a], [b,c]]’ contains two elements: ‘[a]’ and ‘[b,c]’.
It is common to see lists with unquoted elements when those elements are
not likely to be macro names, as in ‘[fputc_unlocked,
fgetc_unlocked]’.
Although not generally recommended, it is possible for quoted lists to have side effects; all side effects are expanded only once, and prior to visiting any list element. On the other hand, the fact that unquoted macros are expanded exactly once means that macros without side effects can be used to generate lists. For example,
m4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [i]) error→hi ⇒123 m4_define([list], [[1], [2], [3]]) ⇒ m4_foreach([i], [list], [i]) ⇒123
Extracts argument n (larger than 0) from the remaining arguments. If there are too few arguments, the empty string is used. For any n besides 1, this is more efficient than the similar ‘m4_car(m4_shiftn([n], [], [arg…]))’.
Expands to the quoted first arg. Can be used with m4_cdr
to recursively iterate
through a list. Generally, when using quoted lists of quoted elements,
m4_car
should be called without any extra quotes.
Expands to a quoted list of all but the first arg, or the empty
string if there was only one argument. Generally, when using quoted
lists of quoted elements, m4_cdr
should be called without any
extra quotes.
For example, this is a simple implementation of m4_map
; note how
each iteration checks for the end of recursion, then merely applies the
first argument to the first element of the list, then repeats with the
rest of the list. (The actual implementation in M4sugar is a bit more
involved, to gain some speed and share code with m4_map_sep
, and
also to avoid expanding side effects in ‘$2’ twice).
m4_define([m4_map], [m4_ifval([$2], [m4_apply([$1], m4_car($2))[]$0([$1], m4_cdr($2))])])dnl m4_map([ m4_eval], [[[1]], [[1+1]], [[10],[16]]]) ⇒ 1 2 a
Loop over the numeric values between first and last including bounds by increments of step. For each iteration, expand expression with the numeric value assigned to var. If step is omitted, it defaults to ‘1’ or ‘-1’ depending on the order of the limits. If given, step has to match this order. The number of iterations is determined independently from definition of var; iteration cannot be short-circuited or lengthened by modifying var from within expression.
Loop over the comma-separated M4 list list, assigning each value to var, and expand expression. The following example outputs two lines:
m4_foreach([myvar], [[foo], [bar, baz]], [echo myvar ])dnl ⇒echo foo ⇒echo bar, baz
Note that for some forms of expression, it may be faster to use
m4_map_args
.
Loop over the white-space-separated list list, assigning each value
to var, and expand expression. If var is only
referenced once in expression, it is more efficient to use
m4_map_args_w
.
The deprecated macro AC_FOREACH
is an alias of
m4_foreach_w
.
Loop over the comma separated quoted list of argument descriptions in
list, and invoke macro with the arguments. An argument
description is in turn a comma-separated quoted list of quoted elements,
suitable for m4_apply
. The macros m4_map
and
m4_map_sep
ignore empty argument descriptions, while
m4_mapall
and m4_mapall_sep
invoke macro with no
arguments. The macros m4_map_sep
and m4_mapall_sep
additionally expand separator between invocations of macro.
Note that separator is expanded, unlike in m4_join
. When
separating output with commas, this means that the map result can be
used as a series of arguments, by using a single-quoted comma as
separator, or as a single string, by using a double-quoted comma.
m4_map([m4_count], []) ⇒ m4_map([ m4_count], [[], [[1]], [[1], [2]]]) ⇒ 1 2 m4_mapall([ m4_count], [[], [[1]], [[1], [2]]]) ⇒ 0 1 2 m4_map_sep([m4_eval], [,], [[[1+2]], [[10], [16]]]) ⇒3,a m4_map_sep([m4_echo], [,], [[[a]], [[b]]]) ⇒a,b m4_count(m4_map_sep([m4_echo], [,], [[[a]], [[b]]])) ⇒2 m4_map_sep([m4_echo], [[,]], [[[a]], [[b]]]) ⇒a,b m4_count(m4_map_sep([m4_echo], [[,]], [[[a]], [[b]]])) ⇒1
Repeatedly invoke macro with each successive arg as its only
argument. In the following example, three solutions are presented with
the same expansion; the solution using m4_map_args
is the most
efficient.
m4_define([active], [ACTIVE])dnl m4_foreach([var], [[plain], [active]], [ m4_echo(m4_defn([var]))]) ⇒ plain active m4_map([ m4_echo], [[[plain]], [[active]]]) ⇒ plain active m4_map_args([ m4_echo], [plain], [active]) ⇒ plain active
In cases where it is useful to operate on additional parameters besides
the list elements, the macro m4_curry
can be used in macro
to supply the argument currying necessary to generate the desired
argument list. In the following example, list_add_n
is more
efficient than list_add_x
. On the other hand, using
m4_map_args_sep
can be even more efficient.
m4_define([list], [[1], [2], [3]])dnl m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl dnl list_add_n(N, ARG...) dnl Output a list consisting of each ARG added to N m4_define([list_add_n], [m4_shift(m4_map_args([,m4_curry([add], [$1])], m4_shift($@)))])dnl list_add_n([1], list) ⇒2,3,4 list_add_n([2], list) ⇒3,4,5 m4_define([list_add_x], [m4_shift(m4_foreach([var], m4_dquote(m4_shift($@)), [,add([$1],m4_defn([var]))]))])dnl list_add_x([1], list) ⇒2,3,4
arg…) For every pair of arguments arg, invoke macro with two arguments. If there is an odd number of arguments, invoke macro-end, which defaults to macro, with the remaining argument.
m4_map_args_pair([, m4_reverse], [], [1], [2], [3]) ⇒, 2, 1, 3 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3]) ⇒, 2, 1, [3] m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3], [4]) ⇒, 2, 1, 4, 3
Expand the sequence pre[arg]post
for each
argument, additionally expanding sep between arguments. One
common use of this macro is constructing a macro call, where the opening
and closing parentheses are split between pre and post; in
particular, m4_map_args([macro], [arg])
is equivalent
to m4_map_args_sep([macro(], [)], [], [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 arg.
Expand the sequence pre[word]post
for each word in
the whitespace-separated string, additionally expanding sep
between words. This macro provides the most efficient means for
iterating over a whitespace-separated string. In particular,
m4_map_args_w([string], [action(], [)])
is more
efficient than m4_foreach_w([var], [string],
[action(m4_defn([var]))])
.
m4_shiftn
performs count iterations of m4_shift
,
along with validation that enough arguments were passed in to match the
shift count, and that the count is positive. m4_shift2
and
m4_shift3
are specializations
of m4_shiftn
, introduced in Autoconf 2.62, and are more efficient
for two and three shifts, respectively.
For each of the m4_pushdef
definitions of macro, expand
action with the single argument of a definition of macro.
m4_stack_foreach
starts with the oldest definition, while
m4_stack_foreach_lifo
starts with the current definition.
action should not push or pop definitions of macro, nor is
there any guarantee that the current definition of macro matches
the argument that was passed to action. The macro m4_curry
can be used if action needs more than one argument, although in
that case it is more efficient to use m4_stack_foreach_sep.
Due to technical limitations, there are a few low-level m4sugar
functions, such as m4_pushdef
, that cannot be used as the
macro argument.
m4_pushdef([a], [1])m4_pushdef([a], [2])dnl m4_stack_foreach([a], [ m4_incr]) ⇒ 2 3 m4_stack_foreach_lifo([a], [ m4_curry([m4_substr], [abcd])]) ⇒ cd bcd
Expand the sequence pre[definition]post
for each
m4_pushdef
definition of macro, additionally expanding
sep between definitions. m4_stack_foreach_sep
visits the
oldest definition first, while 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,
m4_stack_foreach([macro], [action])
is short for
m4_stack_foreach_sep([macro], [action(], [)])
.
Next: Evaluation Macros, Previous: Conditional constructs, Up: Programming in M4sugar [Contents][Index]