Next: , Previous: Looping constructs, Up: Programming in M4sugar


8.3.6 Evaluation Macros

The following macros give some control over the order of the evaluation by adding or removing levels of quotes.

— Macro: m4_apply (macro, list)

Apply the elements of the quoted, comma-separated list as the arguments to macro. If list is empty, invoke macro without arguments. Note the difference between m4_indir, which expects its first argument to be a macro name but can use names that are otherwise invalid, and m4_apply, where macro can contain other text, but must end in a valid macro name.

          m4_apply([m4_count], [])
          =>0
          m4_apply([m4_count], [[]])
          =>1
          m4_apply([m4_count], [[1], [2]])
          =>2
          m4_apply([m4_join], [[|], [1], [2]])
          =>1|2
     
— Macro: m4_count (arg, ...)

This macro returns the decimal count of the number of arguments it was passed.

— Macro: m4_do (arg, ...)

This macro loops over its arguments and expands each arg in sequence. Its main use is for readability; it allows the use of indentation and fewer dnl to result in the same expansion.

— Macro: m4_dquote (arg, ...)

Return the arguments as a quoted list of quoted arguments. Conveniently, if there is just one arg, this effectively adds a level of quoting.

— Macro: m4_dquote_elt (arg, ...)

Return the arguments as a series of double-quoted arguments. Whereas m4_dquote returns a single argument, m4_dquote_elt returns as many arguments as it was passed.

— Macro: m4_echo (arg, ...)

Return the arguments, with the same level of quoting. Other than discarding whitespace after unquoted commas, this macro is a no-op.

— Macro: m4_expand (arg)

Return the expansion of arg as a quoted string. Whereas m4_quote is designed to collect expanded text into a single argument, m4_expand is designed to perform one level of expansion on quoted text. The distinction is in the treatment of whitespace following a comma in the original arg. Any time multiple arguments are collected into one with m4_quote, the M4 argument collection rules discard the whitespace. However, with m4_expand, whitespace is preserved, even after the expansion of macros contained in arg.

Note that m4_expand cannot parse everything. The expansion of arg must not contain unbalanced quotes (although quadrigraphs can get around this), nor unbalanced parentheses (portable shell case statements are a major culprit here, but creative shell comments can get around this).

          m4_define([active], [ACT, IVE])dnl
          m4_define([active2], [[ACT, IVE]])dnl
          m4_quote(active, active)
          =>ACT,IVE,ACT,IVE
          m4_expand([active, active])
          =>ACT, IVE, ACT, IVE
          m4_quote(active2, active2)
          =>ACT, IVE,ACT, IVE
          m4_expand([active2, active2])
          =>ACT, IVE, ACT, IVE
     
— Macro: m4_ignore (...)

This macro was introduced in Autoconf 2.62. Expands to nothing, ignoring all of its arguments. By itself, this isn't very useful. However, it can be used to conditionally ignore an arbitrary number of arguments, by deciding which macro name to apply to a list of arguments.

          dnl foo outputs a message only if [debug] is defined.
          m4_define([foo],
          [m4_ifdef([debug],[AC_MSG_NOTICE],[m4_ignore])([debug message])])
     

Note that for earlier versions of Autoconf, the macro __gnu__ can serve the same purpose, although it is less readable.

— Macro: m4_make_list (arg, ...)

This macro exists to aid debugging of M4sugar algorithms. Its net effect is similar to m4_dquote—it produces a quoted list of quoted arguments, for each arg. The difference is that this version uses a comma-newline separator instead of just comma, to improve readability of the list; with the result that it is less efficient than m4_dquote.

          m4_define([zero],[0])m4_define([one],[1])m4_define([two],[2])dnl
          m4_dquote(zero, [one], [[two]])
          =>[0],[one],[[two]]
          m4_make_list(zero, [one], [[two]])
          =>[0],
          =>[one],
          =>[[two]]
          m4_foreach([number], m4_dquote(zero, [one], [[two]]), [ number])
          => 0 1 two
          m4_foreach([number], m4_make_list(zero, [one], [[two]]), [ number])
          => 0 1 two
     
— Macro: m4_quote (arg, ...)

Return the arguments as a single entity, i.e., wrap them into a pair of quotes. This effectively collapses multiple arguments into one, although it loses whitespace after unquoted commas in the process.

— Macro: m4_unquote (arg, ...)

This macro was introduced in Autoconf 2.62. Expand each argument, separated by commas. For a single arg, this effectively removes a layer of quoting, and m4_unquote([arg]) is more efficient than the equivalent m4_do([arg]). For multiple arguments, this results in an unquoted list of expansions. This is commonly used with m4_split, in order to convert a single quoted list into a series of quoted elements.

The following example aims at emphasizing the difference between several scenarios: not using these macros, using m4_defn, using m4_quote, using m4_dquote, and using m4_expand.

     $ cat example.m4
     dnl Overquote, so that quotes are visible.
     m4_define([show], [$[]1 = [$1], $[]@ = [$@]])
     m4_define([a], [A])
     m4_define([mkargs], [1, 2[,] 3])
     m4_define([arg1], [[$1]])
     m4_divert([0])dnl
     show(a, b)
     show([a, b])
     show(m4_quote(a, b))
     show(m4_dquote(a, b))
     show(m4_expand([a, b]))
     
     arg1(mkargs)
     arg1([mkargs])
     arg1(m4_defn([mkargs]))
     arg1(m4_quote(mkargs))
     arg1(m4_dquote(mkargs))
     arg1(m4_expand([mkargs]))
     $ autom4te -l m4sugar example.m4
     $1 = A, $@ = [A],[b]
     $1 = a, b, $@ = [a, b]
     $1 = A,b, $@ = [A,b]
     $1 = [A],[b], $@ = [[A],[b]]
     $1 = A, b, $@ = [A, b]
     
     1
     mkargs
     1, 2[,] 3
     1,2, 3
     [1],[2, 3]
     1, 2, 3