Next: Evaluation Macros, Previous: Conditional constructs, Up: Programming in M4sugar
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
Expands to the quoted first element of the comma-separated quoted list. Often 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 element of the comma-separated quoted list, or the empty string if list had only one element. 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 withm4_map_sep
).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
Loop over the white-space-separated list list, assigning each value to var, and expand expression.
The deprecated macro
AC_FOREACH
is an alias ofm4_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 macrosm4_map
andm4_map_sep
ignore empty argument descriptions, whilem4_mapall
andm4_mapall_sep
invoke macro with no arguments. The macrosm4_map_sep
andm4_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
m4_shiftn
performs count iterations ofm4_shift
, along with validation that enough arguments were passed in to match the shift count, and that the count is positive.m4_shift2
andm4_shift3
are specializations ofm4_shiftn
, introduced in Autoconf 2.62, and are more efficient for two and three shifts, respectively.