preprocessorm4

Conditional compilation/interpretation using m4


I would like to use m4 as a preprocessor for a couple of different scripting languages that lack this facility.

In particular, I need to emulate the C preprocessor (cpp) functionality of conditional code inclusion:

#if something

some
long
code
block

#else

alternate
code
block

#if something-else

do
more
stuff

#endif

#endif

m4's ifelse() does not particularly lend itself to long code blocks, so it seems I essentially need to write m4 macros to emulate this, by testing the condition and then using divert to include or exclude blocks as appropriate.

The tricky part will be keeping track of nesting levels; as far as I can tell, I will have to implement my own stack within m4 to do this. This seems conceptually straightforward, and I'm sure with a day or two of hacking I can have a working system.

But it feels like reinventing the wheel — I surely can't be the first person with this need. Existing, tested, robust solutions are surely better than whatever I can hack together as an m4 rank beginner.

Are there common m4 idioms for this? Is there existing open-source m4 code to do this? Poking around in search engines didn't turn up anything useful.

(Using cpp itself won't work for reasons given in cpp's own documentation: "It will choke on input which does not obey C's lexical rules." It seems gpp has this functionality out of the box, so using that might make more sense, but I prefer the ubiquity of m4 if it's not too painful to make m4 do this.)


Solution

  • I was also looking for this, and ended up writing my own. Here is a link to the code on my wiki:

    http://www.eugeneweb.com/wiki/Sites/M4Macros

    I defined the names without the #'s eg. IF, ELSE, ENDIF, etc... Also M4 requires parens to hold the arguments where CPP (Mostly) does not. I also added a selective invoke to protect macros with side effects from invocation in an unselected block. Ciao.