autoconf: Evaluation Macros

1 
1 8.3.6 Evaluation Macros
1 -----------------------
1 
1 The following macros give some control over the order of the evaluation
1 by adding or removing levels of quotes.
1 
1  -- Macro: m4_apply (MACRO, LIST)
1      Apply the elements of the quoted, comma-separated LIST as the
1      arguments to MACRO.  If LIST is empty, invoke MACRO without
1      arguments.  Note the difference between `m4_indir', which expects
1      its first argument to be a macro name but can use names that are
1      otherwise invalid, and `m4_apply', where MACRO can contain other
1      text, but must end in a valid macro name.
1           m4_apply([m4_count], [])
1           =>0
1           m4_apply([m4_count], [[]])
1           =>1
1           m4_apply([m4_count], [[1], [2]])
1           =>2
1           m4_apply([m4_join], [[|], [1], [2]])
1           =>1|2
1 
1  -- Macro: m4_count (ARG, ...)
1      This macro returns the decimal count of the number of arguments it
1      was passed.
1 
1  -- Macro: m4_curry (MACRO, ARG...)
1      This macro performs argument currying.  The expansion of this
1      macro is another macro name that expects exactly one argument;
1      that argument is then appended to the ARG list, and then MACRO is
1      expanded with the resulting argument list.
1 
1           m4_curry([m4_curry], [m4_reverse], [1])([2])([3])
1           =>3, 2, 1
1 
1      Unfortunately, due to a limitation in M4 1.4.x, it is not possible
1      to pass the definition of a builtin macro as the argument to the
1      output of `m4_curry'; the empty string is used instead of the
1      builtin token.  This behavior is rectified by using M4 1.6 or
1      newer.
1 
1  -- Macro: m4_do (ARG, ...)
1      This macro loops over its arguments and expands each ARG in
1      sequence.  Its main use is for readability; it allows the use of
1      indentation and fewer `dnl' to result in the same expansion.  This
1      macro guarantees that no expansion will be concatenated with
1      subsequent text; to achieve full concatenation, use
1      `m4_unquote(m4_join([], ARG...))'.
1 
1           m4_define([ab],[1])m4_define([bc],[2])m4_define([abc],[3])dnl
1           m4_do([a],[b])c
1           =>abc
1           m4_unquote(m4_join([],[a],[b]))c
1           =>3
1           m4_define([a],[A])m4_define([b],[B])m4_define([c],[C])dnl
1           m4_define([AB],[4])m4_define([BC],[5])m4_define([ABC],[6])dnl
1           m4_do([a],[b])c
1           =>ABC
1           m4_unquote(m4_join([],[a],[b]))c
1           =>3
1 
1  -- Macro: m4_dquote (ARG, ...)
1      Return the arguments as a quoted list of quoted arguments.
1      Conveniently, if there is just one ARG, this effectively adds a
1      level of quoting.
1 
1  -- Macro: m4_dquote_elt (ARG, ...)
1      Return the arguments as a series of double-quoted arguments.
1      Whereas `m4_dquote' returns a single argument, `m4_dquote_elt'
1      returns as many arguments as it was passed.
1 
1  -- Macro: m4_echo (ARG, ...)
1      Return the arguments, with the same level of quoting.  Other than
1      discarding whitespace after unquoted commas, this macro is a no-op.
1 
1  -- Macro: m4_expand (ARG)
1      Return the expansion of ARG as a quoted string.  Whereas
1      `m4_quote' is designed to collect expanded text into a single
1      argument, `m4_expand' is designed to perform one level of expansion
1      on quoted text.  One distinction is in the treatment of whitespace
1      following a comma in the original ARG.  Any time multiple
1      arguments are collected into one with `m4_quote', the M4 argument
1      collection rules discard the whitespace.  However, with
1      `m4_expand', whitespace is preserved, even after the expansion of
1      macros contained in ARG.  Additionally, `m4_expand' is able to
1      expand text that would involve an unterminated comment, whereas
1      expanding that same text as the argument to `m4_quote' runs into
1      difficulty in finding the end of the argument.  Since manipulating
1      diversions during argument collection is inherently unsafe,
1      `m4_expand' issues an error if ARG attempts to change the current
1      diversion (⇒Diversion support).
1 
1           m4_define([active], [ACT, IVE])dnl
1           m4_define([active2], [[ACT, IVE]])dnl
1           m4_quote(active, active)
1           =>ACT,IVE,ACT,IVE
1           m4_expand([active, active])
1           =>ACT, IVE, ACT, IVE
1           m4_quote(active2, active2)
1           =>ACT, IVE,ACT, IVE
1           m4_expand([active2, active2])
1           =>ACT, IVE, ACT, IVE
1           m4_expand([# m4_echo])
1           =># m4_echo
1           m4_quote(# m4_echo)
1           )
1           =># m4_echo)
1           =>
1 
1      Note that `m4_expand' cannot handle an ARG that expands to literal
1      unbalanced quotes, but that quadrigraphs can be used when
1      unbalanced output is necessary.  Likewise, unbalanced parentheses
1      should be supplied with double quoting or a quadrigraph.
1 
1           m4_define([pattern], [[!@<:@]])dnl
1           m4_define([bar], [BAR])dnl
1           m4_expand([case $foo in
1             m4_defn([pattern])@:}@ bar ;;
1             *[)] blah ;;
1           esac])
1           =>case $foo in
1           =>  [![]) BAR ;;
1           =>  *) blah ;;
1           =>esac
1 
1  -- Macro: m4_ignore (...)
1      This macro was introduced in Autoconf 2.62.  Expands to nothing,
1      ignoring all of its arguments.  By itself, this isn't very useful.
1      However, it can be used to conditionally ignore an arbitrary
1      number of arguments, by deciding which macro name to apply to a
1      list of arguments.
1           dnl foo outputs a message only if [debug] is defined.
1           m4_define([foo],
1           [m4_ifdef([debug],[AC_MSG_NOTICE],[m4_ignore])([debug message])])
1 
1      Note that for earlier versions of Autoconf, the macro `__gnu__' can
1      serve the same purpose, although it is less readable.
1 
1  -- Macro: m4_make_list (ARG, ...)
1      This macro exists to aid debugging of M4sugar algorithms.  Its net
1      effect is similar to `m4_dquote'--it produces a quoted list of
1      quoted arguments, for each ARG.  The difference is that this
1      version uses a comma-newline separator instead of just comma, to
1      improve readability of the list; with the result that it is less
1      efficient than `m4_dquote'.
1           m4_define([zero],[0])m4_define([one],[1])m4_define([two],[2])dnl
1           m4_dquote(zero, [one], [[two]])
1           =>[0],[one],[[two]]
1           m4_make_list(zero, [one], [[two]])
1           =>[0],
1           =>[one],
1           =>[[two]]
1           m4_foreach([number], m4_dquote(zero, [one], [[two]]), [ number])
1           => 0 1 two
1           m4_foreach([number], m4_make_list(zero, [one], [[two]]), [ number])
1           => 0 1 two
1 
1  -- Macro: m4_quote (ARG, ...)
1      Return the arguments as a single entity, i.e., wrap them into a
1      pair of quotes.  This effectively collapses multiple arguments
1      into one, although it loses whitespace after unquoted commas in
1      the process.
1 
1  -- Macro: m4_reverse (ARG, ...)
1      Outputs each argument with the same level of quoting, but in
1      reverse order, and with space following each comma for readability.
1 
1           m4_define([active], [ACT,IVE])
1           =>
1           m4_reverse(active, [active])
1           =>active, IVE, ACT
1 
1  -- Macro: m4_unquote (ARG, ...)
1      This macro was introduced in Autoconf 2.62.  Expand each argument,
1      separated by commas.  For a single ARG, this effectively removes a
1      layer of quoting, and `m4_unquote([ARG])' is more efficient than
1      the equivalent `m4_do([ARG])'.  For multiple arguments, this
1      results in an unquoted list of expansions.  This is commonly used
1      with `m4_split', in order to convert a single quoted list into a
1      series of quoted elements.
1 
1    The following example aims at emphasizing the difference between
1 several scenarios: not using these macros, using `m4_defn', using
1 `m4_quote', using `m4_dquote', and using `m4_expand'.
1 
1      $ cat example.m4
1      dnl Overquote, so that quotes are visible.
1      m4_define([show], [$[]1 = [$1], $[]@ = [$@]])
1      m4_define([a], [A])
1      m4_define([mkargs], [1, 2[,] 3])
1      m4_define([arg1], [[$1]])
1      m4_divert([0])dnl
1      show(a, b)
1      show([a, b])
1      show(m4_quote(a, b))
1      show(m4_dquote(a, b))
1      show(m4_expand([a, b]))
1 
1      arg1(mkargs)
1      arg1([mkargs])
1      arg1(m4_defn([mkargs]))
1      arg1(m4_quote(mkargs))
1      arg1(m4_dquote(mkargs))
1      arg1(m4_expand([mkargs]))
1      $ autom4te -l m4sugar example.m4
1      $1 = A, $@ = [A],[b]
1      $1 = a, b, $@ = [a, b]
1      $1 = A,b, $@ = [A,b]
1      $1 = [A],[b], $@ = [[A],[b]]
1      $1 = A, b, $@ = [A, b]
1 
1      1
1      mkargs
1      1, 2[,] 3
1      1,2, 3
1      [1],[2, 3]
1      1, 2, 3
1