Re: safe define

Eric Blake <[email protected]> Mon, 11 May 2015 08:24:47 -0600
Newsgroups gmane.comp.gnu.m4.general
Organization Red Hat, Inc.
Message-ID <[email protected]>
On 05/11/2015 04:08 AM, Werner LEMBERG wrote:
> 
> Folks,
> 
> 
> has someone ever written a `safe define' macro that makes the defined
> macro expands to itself if called without any argument?

Yes, the manual even has a section on how to do it:
https://www.gnu.org/software/m4/manual/m4.html#Composition

> 
>   sdefine({foo}, {bar})
> 
>   foo    =>  foo
>   foo()  =>  bar
> 

Looks like you have done changequote({,}) so I'll keep with that in my
response.

> I tried the following, and I failed (due to lack of experience
> w.r.t. quoting tricks, I think) – I have difficulties to delay the
> expansion of `$#'...
> 
> Below, I've marked the problematic spots with (nonexisting)
> pseudo-functions.
> 
>   define({sdefine},
>     {define({$1},
>        {ifelse(delay_expansion_of({$#}),
>                {0},
>                {{$1}},
>                {expand_at_definition_time(shift($@))})})})

define({sdefine}, {_$0({$1}, {$2}, {$}{#}, {$}{0})})
define({_sdefine}, {define({$1}, {ifelse({$3}, 0, {{$4}}, {$2})})})

The trick is realizing you need two functions: the outer sdefine that
uses quoting tricks to pass a literal $# and $0 to the inner function,
and the inner function that then does the desired define using the
literal strings in the right place.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org
signature.asc (application/pgp-signature, 604 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
Comment: Public key at http://people.redhat.com/eblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBCAAGBQJVULuvAAoJEKeha0olJ0NqHjQH/2GTrKAj7DGXtiaGM8/wl1de
Ajh5jeaLxloPFsgmXcEBGXME7iQLsdVNdjGsFXgrEPIv62GhUjsd8G1PvJTl5dwe
0FtXCOY/ULwcZXmrsTm3vFuE+udd/fh1ZSeb1YE1NPFFCHDfx/MEq56FafwXMhM+
YgGj9SkWeI67FYJaT1XzwvIplgADmHoETkAyim9MFbSoSs1SeNOUDO4wGOSFHL5L
ex+LVDTXsNG/UkD/UTiJ5ACYpS91ZZ47ttLe2y6m1DAF+dgxnpVjXoIwALFDp4aX
oEI7ED8S5JCuwCA70Uc8CnE6M2Y7y/LntDc4arFVgQMZjgDWPXYWGR2y1sSvqEg=
=82Kk
-----END PGP SIGNATURE-----