[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Better way to interpret $N as dollars, not macro argument?
From: |
Daniel Goldman |
Subject: |
Re: Better way to interpret $N as dollars, not macro argument? |
Date: |
Fri, 15 Aug 2014 10:58:13 -0700 |
User-agent: |
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 |
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