How about this perl wonder?
The test input file
Code:
#include <stdio.h>
#include <string.h>
#if defined(FOO)
#define VAR 1
#elif defined(BAR)
#define VAR 2
#else
#define VAR 4
#endif
int main()
{
printf("%d\n", VAR); /* what option did we choose ? */
return 0;
}
Which we would compile with
gcc -DFOO foo.c
Using this perl program to process it, with a little help from gcc
Code:
#!/usr/bin/perl -w
use strict;
# Invoke with the command line you would normally use
# to compile the program.
# Eg. gcc -DFOO foo.c
# Presently assumes only ONE filename, and it's the last argument
# -P - don't include lines
# -E - preprocess only
# -C - don't delete comments
my $filename = $ARGV[$#ARGV]; # the input file
my $tempfile = "$$" . "_$filename"; # a temporary file
#print "$filename $tempfile\n";
$ARGV[$#ARGV] = "";
my $cmdline = join(' ',@ARGV); # the rest of the compiler command line
$cmdline .= " -P -E -C "; # appended with the CPP magic
#print "$cmdline\n";
# copy the source code to a temp file, protecting all
# non-conditional hash directives with comments
open IFH,"$filename" or die "oops\n";
open OFH,">$tempfile" or die "oops\n";
while ( <IFH> ) {
chomp;
if ( /^\s*#/ ) { # some kind of pre-process directive
if ( ! /^\s*#\s*(if|elif|else|endif)/i ) {
# not a conditional, hide in a comment for now
$_ = "/*!!" . $_ . "!!*/";
}
}
print OFH "$_\n";
}
close IFH;
close OFH;
# run the command, and filter the output
open IFH,"$cmdline $tempfile|" or die "oops\n";
while ( <IFH> ) {
chomp;
s/\/\*!!//g; # strip out the comments used
s/!!\*\///g; # as guards in the previous step.
print "$_\n";
}
close IFH;
We can run this command, and get this output
Code:
$ ./uncond.pl gcc -DFOO foo.c
#include <stdio.h>
#include <string.h>
#define VAR 1
int main()
{
printf("%d\n", VAR); /* what option did we choose ? */
return 0;
}
Deleting the extra blank lines left by the pre-processor as it deletes stuff is left as an exercise for the reader