manpagez: man pages & more
info m4
Home | html | info | man

File: m4.info,  Node: Pseudo Arguments,  Next: Undefine,  Prev: Arguments,  Up: Definitions

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

*Note 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

© manpagez.com 2000-2025
Individual documents may contain additional copyright information.