[Top][All Lists]

[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


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:

       "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.



reply via email to

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