m4: Arguments

1 
1 5.2 Arguments to macros
1 =======================
1 
1 Macros can have arguments.  The Nth argument is denoted by '$n' in the
1 expansion text, and is replaced by the Nth actual argument, when the
1 macro is expanded.  Replacement of arguments happens before rescanning,
1 regardless of how many nesting levels of quoting appear in the
1 expansion.  Here is an example of a macro with two arguments.
1 
1  -- Composite: exch (ARG1, ARG2)
1      Expands to ARG2 followed by ARG1, effectively exchanging their
1      order.
1 
1      define(`exch', `$2, $1')
1      =>
1      exch(`arg1', `arg2')
1      =>arg2, arg1
1 
1    This can be used, for example, if you like the arguments to 'define'
1 to be reversed.
1 
1      define(`exch', `$2, $1')
1      =>
1      define(exch(``expansion text'', ``macro''))
1      =>
1      macro
1      =>expansion text
1 
1    ⇒Quoting Arguments, for an explanation of the double quotes.
1 (You should try and improve this example so that clients of 'exch' do
1 not have to double quote; or ⇒Answers Improved exch.).
1 
1    As a special case, the zeroth argument, '$0', is always the name of
1 the macro being expanded.
1 
1      define(`test', ``Macro name: $0'')
1      =>
1      test
1      =>Macro name: test
1 
1    If you want quoted text to appear as part of the expansion text,
1 remember that quotes can be nested in quoted strings.  Thus, in
1 
1      define(`foo', `This is macro `foo'.')
1      =>
1      foo
1      =>This is macro foo.
1 
1 The 'foo' in the expansion text is _not_ expanded, since it is a quoted
1 string, and not a name.
1 
1    GNU 'm4' allows the number following the '$' to consist of one or
1 more digits, allowing macros to have any number of arguments.  The
1 extension of accepting multiple digits is incompatible with POSIX, and
1 is different than traditional implementations of 'm4', which only
1 recognize one digit.  Therefore, future versions of GNU M4 will phase
1 out this feature.  To portably access beyond the ninth argument, you can
1 use the 'argn' macro documented later (⇒Shift).
1 
1    POSIX also states that '$' followed immediately by '{' in a macro
1 definition is implementation-defined.  This version of M4 passes the
1 literal characters '${' through unchanged, but M4 2.0 will implement an
1 optional feature similar to 'sh', where '${11}' expands to the eleventh
1 argument, to replace the current recognition of '$11'.  Meanwhile, if
1 you want to guarantee that you will get a literal '${' in output when
1 expanding a macro, even when you upgrade to M4 2.0, you can use nested
1 quoting to your advantage:
1 
1      define(`foo', `single quoted $`'{1} output')
1      =>
1      define(`bar', ``double quoted $'`{2} output'')
1      =>
1      foo(`a', `b')
1      =>single quoted ${1} output
1      bar(`a', `b')
1      =>double quoted ${2} output
1 
1    To help you detect places in your M4 input files that might change in
1 behavior due to the changed behavior of M4 2.0, you can use the
11 '--warn-macro-sequence' command-line option (⇒Invoking m4
 Operation modes.) with the default regular expression.  This will add a
1 warning any time a macro definition includes '$' followed by multiple
1 digits, or by '{'.  The warning is not enabled by default, because it
1 triggers a number of warnings in Autoconf 2.61 (and Autoconf uses '-E'
1 to treat warnings as errors), and because it will still be possible to
1 restore older behavior in M4 2.0.
1 
1      $ m4 --warn-macro-sequence
1      define(`foo', `$001 ${1} $1')
1      error->m4:stdin:1: Warning: definition of `foo' contains sequence `$001'
1      error->m4:stdin:1: Warning: definition of `foo' contains sequence `${1}'
1      =>
1      foo(`bar')
1      =>bar ${1} bar
1