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

File: autoconf.info,  Node: Evaluation Macros,  Next: Text processing Macros,  Prev: 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 number of arguments it was passed.

 -- Macro: m4_curry (MACRO, ARG...)
     This macro performs argument currying.  The expansion of this macro
     is another macro name that expects exactly one argument; that
     argument is then appended to the ARG list, and then MACRO is
     expanded with the resulting argument list.

          m4_curry([m4_curry], [m4_reverse], [1])([2])([3])
          ⇒3, 2, 1

     Unfortunately, due to a limitation in M4 1.4.x, it is not possible
     to pass the definition of a builtin macro as the argument to the
     output of ‘m4_curry’; the empty string is used instead of the
     builtin token.  This behavior is rectified by using M4 1.6 or
     newer.

 -- 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.  This
     macro guarantees that no expansion will be concatenated with
     subsequent text; to achieve full concatenation, use
     ‘m4_unquote(m4_join([], ARG...))’.

          m4_define([ab],[1])m4_define([bc],[2])m4_define([abc],[3])dnl
          m4_do([a],[b])c
          ⇒abc
          m4_unquote(m4_join([],[a],[b]))c
          ⇒3
          m4_define([a],[A])m4_define([b],[B])m4_define([c],[C])dnl
          m4_define([AB],[4])m4_define([BC],[5])m4_define([ABC],[6])dnl
          m4_do([a],[b])c
          ⇒ABC
          m4_unquote(m4_join([],[a],[b]))c
          ⇒3

 -- 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.  One 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.  Additionally, ‘m4_expand’ is able to expand text
     that would involve an unterminated comment, whereas expanding that
     same text as the argument to ‘m4_quote’ runs into difficulty in
     finding the end of the argument.  Since manipulating diversions
     during argument collection is inherently unsafe, ‘m4_expand’ issues
     an error if ARG attempts to change the current diversion (*note
     Diversion support::).

          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
          m4_expand([# m4_echo])
          ⇒# m4_echo
          m4_quote(# m4_echo)
          )
          ⇒# m4_echo)
          ⇒

     Note that ‘m4_expand’ cannot handle an ARG that expands to literal
     unbalanced quotes, but that quadrigraphs can be used when
     unbalanced output is necessary.  Likewise, unbalanced parentheses
     should be supplied with double quoting or a quadrigraph.

          m4_define([pattern], [[!@<:@]])dnl
          m4_define([bar], [BAR])dnl
          m4_expand([case $foo in
            m4_defn([pattern])@:}@ bar ;;
            *[)] blah ;;
          esac])
          ⇒case $foo in
          ⇒  [![]) BAR ;;
          ⇒  *) blah ;;
          ⇒esac

 -- 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_reverse (ARG, ...)
     Outputs each argument with the same level of quoting, but in
     reverse order, and with space following each comma for readability.

          m4_define([active], [ACT,IVE])
          ⇒
          m4_reverse(active, [active])
          ⇒active, IVE, ACT

 -- 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

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