manpagez: man pages & more
info autoconf
Home | html | info | man

File: autoconf.info,  Node: Looping constructs,  Next: Evaluation Macros,  Prev: Conditional constructs,  Up: Programming in M4sugar

8.3.5 Looping constructs
------------------------

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

 -- Macro: m4_argn (N, [ARG]...)
     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...]))’.

 -- Macro: m4_car (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.

 -- Macro: m4_cdr (ARG...)
     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

 -- Macro: m4_for (VAR, FIRST, LAST, [STEP], EXPRESSION)
     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.

 -- Macro: m4_foreach (VAR, LIST, 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’.

 -- Macro: m4_foreach_w (VAR, LIST, EXPRESSION)
     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’.

 -- Macro: m4_map (MACRO, LIST)
 -- Macro: m4_mapall (MACRO, LIST)
 -- Macro: m4_map_sep (MACRO, SEPARATOR, LIST)
 -- Macro: m4_mapall_sep (MACRO, SEPARATOR, LIST)
     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

 -- Macro: m4_map_args (MACRO, ARG...)
     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

 -- Macro: m4_map_args_pair (MACRO, [MACRO-END = MACRO], 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

 -- Macro: m4_map_args_sep ([PRE], [POST], [SEP], ARG...)
     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.

 -- Macro: m4_map_args_w (STRING, [PRE], [POST], [SEP])
     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]))])’.

 -- Macro: m4_shiftn (COUNT, ...)
 -- Macro: m4_shift2 (...)
 -- Macro: m4_shift3 (...)
     ‘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.

 -- Macro: m4_stack_foreach (MACRO, ACTION)
 -- Macro: m4_stack_foreach_lifo (MACRO, ACTION)
     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

 -- Macro: m4_stack_foreach_sep (MACRO, [PRE], [POST], [SEP])
 -- Macro: m4_stack_foreach_sep_lifo (MACRO, [PRE], [POST], [SEP])
     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(], [)])’.

© manpagez.com 2000-2024
Individual documents may contain additional copyright information.