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