views:

1451

answers:

5

I have a C/C++ source file with conditional compilation. Before I ship it to customers I want to remove most of the #if statements, so that my customers do not need to worry about passing the right -D options to the compiler.

I have this implemented and working in Python, but it only handles #ifdef and #ifndef statements properly. I need to add support for #if statements, but the syntax of #if is much more complex. (E.g. you can use &&, ||, !, brackets, relational operators, arithmetic, etc).

Is there any existing open-source code to parse and evaluate #if statements? (Preferably in Python).

The only implementation I know of is GCC, and that's much too complex for this task.

+4  A: 

Have you looked at Boost.Wave?

Carl Seleborg
A: 

The GCC preprocessor is typicallly a stand-alone program, typically called cpp. That will probably also strip off your comments, of course.

unwind
+6  A: 

Instead of reinventing the wheel, download "unifdef". If you're on some flavour of Linux, you can probably find a package for it, otherwise it's on FreshMeat

Paul Tomblin
As far as I can tell, this only supports a subset of the #if syntax. (Quite a large subset, but I was hoping for full support to avoid the risk of future "bugs because the tool does things subtly different" that Mike mentioned)
user9876
+10  A: 

How about just passing through the C preprocessor, and letting that do the job. It will get rid of all of them, so you might need to have a pre-preprocessor step and a post pre-processor step to protect things you don't want to be expanded.

  1. Change all #include to @include
  2. Pass file through preprocessor
  3. Change @include back to #include
KeithB
That also kills comments and expands all #define's.
MSalters
It also includes headers.
Jonathan Leffler
In answer to both comments, yes. Thats why there is another step to change #include (and #define, if needed) to @include/@define. Obviously, this adds complexity. If possible, Mike B's solution is the way to go.
KeithB
+12  A: 

As KeithB said, you could just let the preprocessor do this for you.

But if you're not trying to hide things (ie., there may be stuff in the conditionally compiled code that you don't want or aren't permitted to give to some one else) a much simpler option would be to just put the proper #define directives in a header that's globally included.

  • your clients don't need to worry about -D options
  • you don't have to have some custom step in your build process
  • the code you give your clients isn't potentially semi-obfuscated
  • you don't introduce bugs because the tool does things subtly different from the C preprocessor
  • you don't have to maintain some custom tool
Michael Burr
Doh. Sometimes the simplest solution is the most elusive.
KeithB