ANN: xcpp C preprocessor now available

C

Chris Croughton

xcpp is a rewrite from scratch of the scpp and other preprocessors (I
haven't found one that compiles and works, so I wrote my own). It is
designed to remove redundant conditional compilation, and replace known
defined symbols, while leaving anything it doesn't know about intact
(whereas the ordinary C preprocessor will remove everything).

I've written it using only standard C, as far as I can tell it should
"compile anywhere". I would be very interested in reports of it passing
or failing under non-gcc compilers (the only one I have here is gcc,
2.95 and 3.3). Similarly, the makefile is very simple (not autoconf!)
and should work with minimal changes (possibly the compiler name and
flags).

It has limitations:

Macros with parameters are not supported. If they are used, they
won't do the right thing. The next version should support macros with
parameters (fixed number of parameters, anyway, I'm not sure about
variable ones).

If it knows what to do with a #if, it will do it without exception.
This means that if there is a #if 0 'commenting' out code it will
remove that, and that if it can simplify an expression it will (so if
it has, after expansion, #if A > 3 + 1 it will simplify it to
#if A > 4). The next version should support a means of changing this
(telling it to leave things alone if it hasn't done any expansion, or
if the expansion doesn't evaluate to a number). It also doesn't have
an option yet to leave blank lines when it deletes stuff to leave the
line numbering intact.

It does all arithmetic as long int, not (as the C99 standard says)
using the biggest integer type available. I can't see any way of
doing the latter in a portable way without auto-configuration scripts
(if anyone else can, please tell me!), since I want it to be C89
standard compatible.

Anyway, share and enjoy! The licence is the one used by Zlib, with
obvious changes (me not them!), which is about as permissive as I can
get. Bug reports and comments welcome (yes, I know the code is not very
well commented -- OK, most of it is hardly commented at all!)...

URL: http://keristor.net/stuff/xcpp-0.1.0.tar.gz

Chris C
 
B

Ben Pfaff

Chris Croughton said:
It does all arithmetic as long int, not (as the C99 standard says)
using the biggest integer type available. I can't see any way of
doing the latter in a portable way without auto-configuration scripts
(if anyone else can, please tell me!), since I want it to be C89
standard compatible.

#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
#else
typedef long int intmax_t;
#endif

This has the minimal caveat that a malicious C89 compiler author
could define __STDC_VERSION__ to whatever he wanted, but that's
only interesting if you're a pedant of legendary status.
 
C

Chris Croughton

#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
#else
typedef long int intmax_t;
#endif

This has the minimal caveat that a malicious C89 compiler author
could define __STDC_VERSION__ to whatever he wanted, but that's
only interesting if you're a pedant of legendary status.

Unless there are some C99 compilers out there without C99 libraries and
headers. As I recall gcc (among others) has said that the library is
not their responsibility, it's the responsibility of the OS to provide
it. Or is that just the library object/archive, and the headers are
still the responsibility of the compiler?

If it's guaranteed that a C99 compiler will include all of the standard
headers, I can also use stdbool.h, which would be nice (of course, I
would still have to define it for the C89 case)...

Chris C
 
C

Chris Croughton

#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
#else
typedef long int intmax_t;
#endif

This has the minimal caveat that a malicious C89 compiler author
could define __STDC_VERSION__ to whatever he wanted, but that's
only interesting if you're a pedant of legendary status.

It also fails if the other headers declare intmax_t, for instance by
pulling in types.h which pulls in stdint.h. I've got round that one
(gcc 3.3 under Cygwin, for example) by doing the horrible

#undef intmax_t
#define intmax_t xcpp_intmax_t
typedef long int intmax_t;

But that is nasty. And just because a compiler is C99 standard it
doesn't mean that the library is (Cygwin, for example, doesn't have
strtoimax or the j length format specification). I don't see any way
round it except by having the person installing it edit make flags (or
writing my own conversion routines)...

Chris C
 
B

Ben Pfaff

Chris Croughton said:
#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
#else
typedef long int intmax_t;
#endif

This has the minimal caveat that a malicious C89 compiler author
could define __STDC_VERSION__ to whatever he wanted, but that's
only interesting if you're a pedant of legendary status.

It also fails if the other headers declare intmax_t, for instance by
pulling in types.h which pulls in stdint.h. [...]

As long as you stick to standard headers that won't happen.
 
C

Chris Croughton

Chris Croughton said:
It does all arithmetic as long int, not (as the C99 standard says)
using the biggest integer type available. I can't see any way of
doing the latter in a portable way without auto-configuration scripts
(if anyone else can, please tell me!), since I want it to be C89
standard compatible.

#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
#else
typedef long int intmax_t;
#endif

This has the minimal caveat that a malicious C89 compiler author
could define __STDC_VERSION__ to whatever he wanted, but that's
only interesting if you're a pedant of legendary status.

It also fails if the other headers declare intmax_t, for instance by
pulling in types.h which pulls in stdint.h. [...]

As long as you stick to standard headers that won't happen.

As I said, it does. GCC 3.3.3 under Cygwin, using only:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>

stdlib.h pulls in types.h, which pulls in stdint.h even in C89 ('strict
ANSI') mode (there is no test of that in types.h). Which is a PITA.

I've got round it, and the lack of some routines and functionality in
the library (missing strtoimax and strtoumax, and printf and similar
don't support the C99 format size options like j) by writing my own
routines from scratch, and using macros from stdint.h and limits.h to
determine my own "maximum integer type".

Now, where do I find a machine where CHAR_BIT is not 8, to really try to
break things?

Chris C
 
B

Ben Pfaff

Chris Croughton said:
Chris Croughton said:
It also fails if the other headers declare intmax_t, for instance by
pulling in types.h which pulls in stdint.h. [...]

As long as you stick to standard headers that won't happen.

As I said, it does. GCC 3.3.3 under Cygwin, using only:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>

stdlib.h pulls in types.h, which pulls in stdint.h even in C89 ('strict
ANSI') mode (there is no test of that in types.h). Which is a PITA.

I don't think that's standard conforming, but I suppose whether
it is or is not is of little practical utility.
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top