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