Utility to partially preprocess

  • Thread starter Chris Croughton
  • Start date
C

Chris Croughton

I have a requirement to partially preprocess C code. By 'partially' I
mean that I need to define some macros (to the utility) and have it
preprocess only those macros, leaving everything else intact. A
compiler's preprocessor won't do this, since it will also process macros
defined in the code (and in standard header files) and strip out
everything. For instance, given source like:

#include <stdio.h>
#if defined(AAA)
void doSomeCode(void)
{
# if AAA > 1
printf("do something %d\n", AAA);
# else
printf("do something else\n");
# endif
}
#else
#include <math.h>
#define PI (4 * atan(1.0))
void doSomeCode(void)
{
printf("something completely different - PI = %f\n", PI);
}
#endif

I would want the output to be:

AAA undefined:

#include <stdio.h>
#include <math.h>
#define PI (4 * atan(1.0))
void doSomeCode(void)
{
printf("something completely different - PI = %f\n", PI);
}

AAA = 0 or 1

#include <stdio.h>
void doSomeCode(void)
{
printf("do something else\n");
}

AAA = 2

#include <stdio.h>
void doSomeCode(void)
{
printf("do something %d\n", 2);
}

OK, it's a silly example, but the idea should show. Note that using the
C preprocessor would have expanded the header files, which is not
wanted...

One purpose is to take some code which has got horribly crufty, with
lots of specific conditional compilation for things which no longer
exist (in particular things which were needed for pre-standard and
non-standard compilers), and reduce it for a simpler case. Yes, this
can be done "by hand" but this is prone to error and very time-consuming
with a large amount of code.

Another purpose is as a general utility for pre-parsing header and code
files for distribution, so that the destination system does not have to
include "config.h" (or equivalent) every time.

My question is:

Does such a utility exist as Free Software? Licence is unimportant as
long as it is compatible with other Free Software -- (L)GPL, BSD and
'Infozip' licences particularly. Source code as Standard C so it will
compile anywhere (so can't depend on yacc or lex, unless the generated
code from them is Standard C).

If not, I need to write my own. If it does exist already, I would
rather not re-invent the wheel...

Chris C
 
C

Chris Torek

I have a requirement to partially preprocess C code. By 'partially' I
mean that I need to define some macros (to the utility) and have it
preprocess only those macros, leaving everything else intact. ...

If you only want certain #ifdef's taken out, the "unifdef" utility
(of which there are no doubt multiple versions) will do the trick.
For something more complicated, look for the "scpp" program -- the
"selective C preprocessor", written some time in the 1980s in
pre-ANSI C.
 
C

Chris Croughton

If you only want certain #ifdef's taken out, the "unifdef" utility
(of which there are no doubt multiple versions) will do the trick.
For something more complicated, look for the "scpp" program -- the
"selective C preprocessor", written some time in the 1980s in
pre-ANSI C.

Thanks, the man for scpp sounds like about what I want, but the only
copies (3 of them) I could find won't compile (lots of lex and
lex-generated code errors). I gather from searches that I'm not the
only one to find that with 'modern' utilities (I'm using Debian
GNU/Linux 'woody' (stable), gcc 2.95.4, lex 2.5.4, yacc (GNU bison)
1.35).

However, reading about it has given me ideas for writing my own. It's
been quite a long time since I wrote a C parser in pure C, the last time
was pre-ANSI, probably about the same time as scpp, but a limited
pre-processor is not too bad (only half of the operators are valid, and
I don't need to worry about program structure at all).

Any recommendations for (non-gcc) C compilers to test compatibility?

Chris C
 
J

jacob navia

Chris said:
I have a requirement to partially preprocess C code. By 'partially' I
mean that I need to define some macros (to the utility) and have it
preprocess only those macros, leaving everything else intact. A
compiler's preprocessor won't do this, since it will also process macros
defined in the code (and in standard header files) and strip out
everything. For instance, given source like:

#include <stdio.h>
#if defined(AAA)
void doSomeCode(void)
{
# if AAA > 1
printf("do something %d\n", AAA);
# else
printf("do something else\n");
# endif
}
#else
#include <math.h>
#define PI (4 * atan(1.0))
void doSomeCode(void)
{
printf("something completely different - PI = %f\n", PI);
}
#endif

I would want the output to be:

AAA undefined:

#include <stdio.h>
#include <math.h>
#define PI (4 * atan(1.0))
void doSomeCode(void)
{
printf("something completely different - PI = %f\n", PI);
}

AAA = 0 or 1

#include <stdio.h>
void doSomeCode(void)
{
printf("do something else\n");
}

AAA = 2

#include <stdio.h>
void doSomeCode(void)
{
printf("do something %d\n", 2);
}

OK, it's a silly example, but the idea should show. Note that using the
C preprocessor would have expanded the header files, which is not
wanted...

One purpose is to take some code which has got horribly crufty, with
lots of specific conditional compilation for things which no longer
exist (in particular things which were needed for pre-standard and
non-standard compilers), and reduce it for a simpler case. Yes, this
can be done "by hand" but this is prone to error and very time-consuming
with a large amount of code.

Another purpose is as a general utility for pre-parsing header and code
files for distribution, so that the destination system does not have to
include "config.h" (or equivalent) every time.

My question is:

Does such a utility exist as Free Software? Licence is unimportant as
long as it is compatible with other Free Software -- (L)GPL, BSD and
'Infozip' licences particularly. Source code as Standard C so it will
compile anywhere (so can't depend on yacc or lex, unless the generated
code from them is Standard C).

If not, I need to write my own. If it does exist already, I would
rather not re-invent the wheel...

Chris C

Using the lcc-win32 compiler system you write:

browsegen -showifdeflines foo.c

and it will write in the standard output the line number
of the lines #ifdefed out in the file foo.c.
This allows the IDE to show ifdefed lines in gray color,
but you can use the output as you want, of course.

http://www.cs.virginia.edu/~lcc-win32
 
C

Chris Croughton

Using the lcc-win32 compiler system you write:

browsegen -showifdeflines foo.c

And this compiler is:

Free Software?
Standard C source code which will "compile anywhere"?

Er, not as far as I can see from that web page. It seems to be Win32
binary only.
and it will write in the standard output the line number
of the lines #ifdefed out in the file foo.c.
This allows the IDE to show ifdefed lines in gray color,
but you can use the output as you want, of course.

Very useful, indeed. But presumably it also notices macros in header
files and in the code when it decides what is #ifdefed out as well (i.e.
lines which it ignores when compiling), which is not useful in my case
(I need it to only notice the ones I specify).

I get "530 Sorry, the maximum number of allowed clients (30) are already
connected" on all of the links -- except the one to the mirror site at Q
Software Solutions (http://www.q-software-solutions.com/lccwin32) which
gives 404 "The requested URL /lccwin32 was not found on this server."

Chris C
 
C

CBFalconer

Chris said:
On 1 Nov 2004 19:34:11 GMT, Chris Torek

Thanks, the man for scpp sounds like about what I want, but the only
copies (3 of them) I could find won't compile (lots of lex and
lex-generated code errors). I gather from searches that I'm not the
only one to find that with 'modern' utilities (I'm using Debian
GNU/Linux 'woody' (stable), gcc 2.95.4, lex 2.5.4, yacc (GNU bison)
1.35).

I couldn't find any scpp source via google. Where did you locate
them?
 
J

jacob navia

Chris said:
And this compiler is:

Free Software?
Standard C source code which will "compile anywhere"?

Er, not as far as I can see from that web page. It seems to be Win32
binary only.

It is free software as far as you do not have to pay anything to
use it.

lcc-win32 runs only in the win32 susbsystem of windows.
Very useful, indeed. But presumably it also notices macros in header
files and in the code when it decides what is #ifdefed out as well (i.e.
lines which it ignores when compiling), which is not useful in my case
(I need it to only notice the ones I specify).

It will follow included files of course, and accept command line
parameters like
browsegen -DsomeMacro=SOME_MACRO
or similar

If you do not want it to follow any includes, just put your
source in a directory where none of them will be found...
VERY EASY :)

I get "530 Sorry, the maximum number of allowed clients (30) are already
connected" on all of the links -- except the one to the mirror site at Q
Software Solutions (http://www.q-software-solutions.com/lccwin32) which
gives 404 "The requested URL /lccwin32 was not found on this server."

Chris C

Sorry but the compiler is very popular and there are a lot of people
downloading.

jacob
 
C

Chris Croughton


That was (I think) the first one I tried. Also:

ftp://ftp.uu.net/usenet/comp.sources.unix/volume3/scpp
(two shar files from Usenet, possibly the original version)

ftp://isgate.is/pub/unix/sec1/scpp.tar.Z

http://ftp.unicamp.br/pub/unix-c/languages/c/scpp.tar.gz

I searched google using: '"selective C preprocessor" scpp' (just using
'scpp' turns up a mass of unrelated things, organisations using those
initials etc.).

All seem to have the same problem, they find a lex rule which doesn't
work (I don't remember enough lex to see why) and the compilation finds
a load of undefined variables.

I haven't tried them using Unix 7 under the PDP-11 emulator, though...

I'm making progress on my own version. It can read files and tokenise
preprocessor lines (and gets the interaction with comments and
continuation lines correct), and has a database for the preprocessor
variables. Next is to replace tokens by the defined macros, then comes
the expression parsing...

Chris C
 
B

Ben Pfaff

Chris Croughton said:
All seem to have the same problem, they find a lex rule which doesn't
work (I don't remember enough lex to see why) and the compilation finds
a load of undefined variables.

If you're using flex, use 2.5.4a or older with old software.
Newer versions are somewhat incompatible.
 
C

CBFalconer

Chris said:
.... snip ...

I'm making progress on my own version. It can read files and
tokenise preprocessor lines (and gets the interaction with
comments and continuation lines correct), and has a database for
the preprocessor variables. Next is to replace tokens by the
defined macros, then comes the expression parsing...

Go for it. You may have need for a place store a symbol table and
macro expansions. Try my hashlib for that. Available on my site,
download section.
 
C

Chris Croughton

If you're using flex, use 2.5.4a or older with old software.
Newer versions are somewhat incompatible.

I am using 2.5.4 (that's what it calls itself, Debian calls it
2.5.4a-24). It seems to generate invalid code:

It generates code using 'yyconst', which it doesn't declare anywhere
(presumably it's supposed to be defined as 'const').

It generates code using 'yy_cp' which likewise isn't (always)
declared (it's declared in some funcxtions but not in others).

It generates some code right at the end which shouldn't be there.

The first is relatively easy to fix (run it through sed), the other two
I have no idea about...

(Same happens with Cygwin, which uses the same version of flex.)

Chris C
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top