views:

376

answers:

2

I've been working on a (nearly finished) Javascript project for a little over 14 months now. The project started out as a hack I expected to finish overnight, but over time the Javascript part has grown up to be 68 separate files and 10,314 non-empty lines, sadly currently dependent on the C preprocessor for building.

It's hard to explain how I ended up using cpp for the Javascript: this was only a hack, and I needed something that gave me macro expansion, ifdef, define, and includes without too much effort. After about 3 second's consideration, I realized cpp was "perfect" for the task:

  • Provide a LOG() macro that disappears in release mode.
  • Provide an ASSERT() macro that disappears in release mode, and generates exceptions tagged with original file and line number.
  • Swap LOG() and ASSERT() implementations for code that allows producing a "checked" build, which logs events in a compact form as they occur, that are reported back to the server if a crash occurs.
  • Replacing PROJECT_SOME_CONFIG_VAR_NAME with "1", based on a configuration file shared with the Python backend.

Like all true hacks, this hack is now so hard-coded into the project that I truly hate to even think about the work that will be required to replace it. My project is reaching the stage where I want to move the code base to its own dedicated test server (rather than my laptop), however on setting up a Linux instance, I've discovered that GNU cpp versions after 4.1 no longer preprocess the Javascript with crashing out with an error.

Rather than add a specific version of GCC to the list of build requirements, I figured now would be a good time to truly fix this mess. My problem is, though, that I can't find a replacement preprocessor with the same power and features as cpp! I have considered m4, but m4 is a world of pain unto itself. Other Javascript-specific preprocessors I have found lack all the features I am currently depending on, e.g.:

  • __FILE__ & __LINE__
  • Variadic macros
  • Include guards
  • Token concatenation
  • Conditional compilation

I am seriously considering implementing a brand new preprocessor just for Javascript, that completely borrows the C preprocessor syntax since it has worked so well. I'm just wondering if there are better options before doing so. :) Perhaps there is already a cpp-like generic preprocessor I could swap in? The work required to replace all the preprocessor syntax in those 68 files approaches the amount of work required to simply reimplement the preprocessor.

I'm quite surprised I ever made it so far while relying on the C preprocessor; it is more effective at this task than healthy for the mind to comprehend. Another option open to me is statically building versions of cpp-4.1 for Linux, Darwin-i386, Win32, and storing those binaries in the project's repository.

Help!

+1  A: 

Have you already tried mcpp? It's a "portable C preprocessor"

Should that fail, you could try using a generic macro processor (like gema) and build enough cpp on top of it.

Remo.D
Thanks for the link to mcpp: it gets quite far in "-@old" mode, but seems to be failing because I'm using single quote characters for strings (character literals in C).Investigating gema momentarily.
David Wilson
Awarding you the answer to this question, since it was the most useful. In the end I decided to bite the bullet and convert the entire codebase to Google Closure, as it has nearly all the features I need in pure Javascript, and the compiler gives the same benefits at 'deployment' time (linking it together and removing debug code).
David Wilson
A: 

Did you try M4?

null