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

Daniel Goldman <[email protected]> Fri, 15 Aug 2014 10:58:13 -0700
Newsgroups gmane.comp.gnu.m4.general
Message-ID <[email protected]>
Doug,

Thanks for responding, trying to help.

On 8/14/2014 7:22 AM, Doug McIlroy wrote:
>
> A well constructed document likely doesn't interleave macro definitions
> with the text that contains the dollar signs you want to protect. In that
> case an easy fix is to transliterate the literal dollar signs into another
> character during macro processing. Two helpful utilities are tr and sed.

In case any confusion (not sure), the dollar signs I want to protect are 
within the macro definitions, not within the text being transformed by 
m4. My example again:

m4_define(RNG_NameArray_Lo_______RNG_VN_Income_Level_______,
[[[
        "0", "$10,000", "$75,000"
]]])

>
> If the definitions are in an include() file, then a wrapper like this
> may suffice (quotes protect the dollar signs from the shell):
>
>          tr '$' @ | m4 | tr @ '$'
>

The definitions are in a separate file. But it seems to me adding the 
step you suggest would not suffice, because then the $N macro arguments 
get messed up. The problem is the next m4_define might have $1, $2, etc. 
Would get converted to @1, @2, etc. :(

> If the definitions are at the beginning, not protected in an include file,
> you could signal the end of definitions with a comment like #ENDDEF or
> a dummy definition like define(ENDDEF)dnl() and use sed to process
> the rest of the file:
>
>          sed '/ENDDEF/,$y/$/@/' | m4 | sed 'y/@/$/'
>

Same problem as previous suggestion. Macro arguments get damaged.

> Jon Bentley, who often combines m4 with troff, which also uses $
> as a metacharacter, does the reverse. He uses @ as the
> argument indicator and preprocesses the definitions:
>
>          sed '1,/ENDDEF/y/@/$/' | m4 | troff

I'm sure this works for Jon as a stopgap, but is a stopgap, and does not 
work as a general solution. From little to fatal problem: 1) Adds more 
steps to the process. Each step makes the process slower, more 
error-prone, harder to maintain. 2) Uses kludgy @1, @2, etc. instead of 
standard $1, $2 arguments. You mentioned "well constructed documents". I 
don't consider changing basic syntax to result in a "well constructed 
document". What is someone else going to think when they see 
non-standard, kludgy usage? How much time will they waste trying to 
figure it out? 3) Finally, the @ character is used in email addresses 
and other ways, so fatally messes things up, results in gotchas and 
surprises. BTW, if I was actually going to do this, I would use some 
unique sequence (not @) that I knew for sure would not otherwise occur. 
I've had a lot of experience doing this to "fix up" cpp deficiencies.

I said in my post the reason I moved away from cpp was because of such 
awkward "special cases" as this. I was specifically referring to the 
need for using tr and sed (and others) to take care of "special cases". 
Yes, tr and sed (along with other unix utilities) can "do anything". But 
the more they are used, the more the result resembles a Rube Goldberg 
contraption. I've been down that path with cpp, it's not pretty. As a 
general pre-processor, I don't think m4 should need to be "fixed up" 
with additional "pre-pre-processing" and "post-pre-processing" steps. 
Especially because named arguments (in the future) would 100% get rid of 
this problem, and are much better in any case.

To repeat my original question, I was wondering if there was a better 
way to tell m4 not to interpret $N as "dollar amount", better than just 
manually marking up each $ with quote delimiters.

Thanks,
Daniel

>
> Doug
>