m4: Pseudo Arguments
5.3 Special arguments to macros
===============================
There is a special notation for the number of actual arguments supplied,
and for all the actual arguments.
The number of actual arguments in a macro call is denoted by ‘$#’ in
the expansion text.
-- Composite: nargs (...)
Expands to a count of the number of arguments supplied.
define(`nargs', `$#')
⇒
nargs
⇒0
nargs()
⇒1
nargs(`arg1', `arg2', `arg3')
⇒3
nargs(`commas can be quoted, like this')
⇒1
nargs(arg1#inside comments, commas do not separate arguments
still arg1)
⇒1
nargs((unquoted parentheses, like this, group arguments))
⇒1
Remember that ‘#’ defaults to the comment character; if you forget
quotes to inhibit the comment behavior, your macro definition may not
end where you expected.
dnl Attempt to define a macro to just `$#'
define(underquoted, $#)
oops)
⇒
underquoted
⇒0)
⇒oops
The notation ‘$*’ can be used in the expansion text to denote all the
actual arguments, unquoted, with commas in between. For example
define(`echo', `$*')
⇒
echo(arg1, arg2, arg3 , arg4)
⇒arg1,arg2,arg3 ,arg4
Often each argument should be quoted, and the notation ‘$@’ handles
that. It is just like ‘$*’, except that it quotes each argument. A
simple example of that is:
define(`echo', `$@')
⇒
echo(arg1, arg2, arg3 , arg4)
⇒arg1,arg2,arg3 ,arg4
Where did the quotes go? Of course, they were eaten, when the
expanded text were reread by ‘m4’. To show the difference, try
define(`echo1', `$*')
⇒
define(`echo2', `$@')
⇒
define(`foo', `This is macro `foo'.')
⇒
echo1(foo)
⇒This is macro This is macro foo..
echo1(`foo')
⇒This is macro foo.
echo2(foo)
⇒This is macro foo.
echo2(`foo')
⇒foo
⇒Trace, if you do not understand this. As another example of the
difference, remember that comments encountered in arguments are passed
untouched to the macro, and that quoting disables comments.
define(`echo1', `$*')
⇒
define(`echo2', `$@')
⇒
define(`foo', `bar')
⇒
echo1(#foo'foo
foo)
⇒#foo'foo
⇒bar
echo2(#foo'foo
foo)
⇒#foobar
⇒bar'
A ‘$’ sign in the expansion text, that is not followed by anything
‘m4’ understands, is simply copied to the macro expansion, as any other
text is.
define(`foo', `$$$ hello $$$')
⇒
foo
⇒$$$ hello $$$
If you want a macro to expand to something like ‘$12’, the judicious
use of nested quoting can put a safe character between the ‘$’ and the
next character, relying on the rescanning to remove the nested quote.
This will prevent ‘m4’ from interpreting the ‘$’ sign as a reference to
an argument.
define(`foo', `no nested quote: $1')
⇒
foo(`arg')
⇒no nested quote: arg
define(`foo', `nested quote around $: `$'1')
⇒
foo(`arg')
⇒nested quote around $: $1
define(`foo', `nested empty quote after $: $`'1')
⇒
foo(`arg')
⇒nested empty quote after $: $1
define(`foo', `nested quote around next character: $`1'')
⇒
foo(`arg')
⇒nested quote around next character: $1
define(`foo', `nested quote around both: `$1'')
⇒
foo(`arg')
⇒nested quote around both: arg