m4-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Better way to interpret $N as dollars, not macro argument?


From: Eric Blake
Subject: Re: Better way to interpret $N as dollars, not macro argument?
Date: Fri, 15 Aug 2014 13:07:48 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.7.0

On 08/14/2014 12:16 AM, Daniel Goldman wrote:
> I ran into a problem where $N is (of course) interpreted as $N macro
> argument, but I wanted dollar amount. Here is the actual code with the
> problem output, extracted into a separate m4 file, and with most array
> elements removed to simplify the example:
> 
> -----------------------
> 
> $ cat dollar-03.m4
> m4_changequote([[[,]]])
> 
> m4_define(RNG_NameArray_Lo_______RNG_VN_Income_Level_______,

Side note: it's a bad idea to use m4_define without quoting the first
argument.  If the define gets called more than once, then you end up
defining a completely different macro name (namely, whatever the
expansion of the original macro name was).  You should ALWAYS quote the
first argument to define.

> To fix the problem, after several other tries, this is the best I came
> up with, which later I also saw in section 5.3 of the GNU m4 manual:
> 

> m4_define(RNG_NameArray_Hi_______RNG_VN_Income_Level_______,
> [[[
>   "[[[$]]]9,999", "[[[$]]]14,999", "[[[$]]]75,000+"
> ]]])
> 

Yes, using quote marks to separate the $ from the rest of the expansion
is one option.

> 
> This works, but having to mark up each dollar sign with quote delimiters
> seems quite awkward to me. The reason I moved away from cpp was because
> of such awkward "special cases" as this.

Alas, such is life.  Another approach that I have personally used is to
delegate to helper functions that concatenate the results into the
desired output.  Instead of:

m4_define([[[foo]]], [[[[[[$]]]1 is $1]]])

I do:

m4_define([[[cat]]], [[[$1$2]]])
m4_define([[[foo]]], [[[cat($, [[[1 is $1]]])]]])

which still requires special casing $, but a little less thought on how
to add creative use of quoting.

> Anyway, my question: Is there a better way to tell m4 not to interpret
> $N as "dollar amount"? Based on the manual, the answer seems "no". But I
> thought I would ask, hoping maybe some other way...

Sadly, this is one area where M4 is locked into historical warts.  At
one point, there was an M5 language written, where you could use $$
inside any macro definition to have the expansion of that macro use one
less $ instead of treating $ as a possible parameter lead-in (thus,
m4_define([[[foo]]], [[[$1 $$1]]]) and called as foo(a) would expand to
'a $1').  It might be interesting if someone were to write a patch to
add an opt-in setting to m4 to copy from M5's dollar quoting mechanism
(of course, it must remain off by default for back-compat).  But I don't
know of anyone currently trying to write such a patch.

http://www.worldcat.org/title/users-guide-to-the-m5-macro-language/oclc/25491290

(Hmm, I know at one point I was able to read a pdf about M5 at no
charge, but can't seem to find a URL for it via a quick search today)

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]