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