Re: Print literal $0 value

Eric Blake <[email protected]> Sat, 7 Jul 2018 20:12:19 -0500
Newsgroups gmane.comp.gnu.m4.general
Organization Red Hat, Inc.
Message-ID <[email protected]>
On 07/07/2018 06:29 PM, Charlie Sale wrote:
> 
> Hello M4
> 
> I am trying to write an m4 macro that has the literal $0 character
> in its expansion. Basically, I'm trying to do something like this:
> 
> define(`my_macro', `/$1/ { print $0 }')

That looks awfully like you are generating an awk script as your output. 
  If so, awk allows whitespace between $ and 0, which means the easiest 
solution that is still a valid awk script is:

define(`my_macro', `/$1/ { print $ 0 }')

> my_macro(`foo')
> --> /foo/ { print $0 }
> 
> Whenever I use the above macro, it turns into this unterminating
> recursive loop that re-expands the macro in the back. I am aware
> that the token $0 prints the name of the defined macro in M4, but
> I would like to print the literal characters instead. How can I do
> this?

But if my earlier comment is wrong, or if you want to learn the solution 
that works anywhere, the answer lies in using creative quoting so that 
the macro definition itself does not contain $ and 0 next to one 
another.  One way:

define(`my_macro', `/$1/ { print $`'0 }')

where the nested empty quote is removed when reparsing the macro 
expansion, and served to separate $ from 0.

And if all else fails (that is, if you come up with situations where 
nested quoting doesn't play nicely with what you have), you can always 
create a helper macro:

define(`_my_macro', `/$1/ { print $$2 }')
define(`my_macro', `_$0(`$1', 0)')

where you pass in half of the problematic string as a separate argument.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org