18

I have a number of debug statements defined in a program, and I want to be able to make a copy of the source without these statements.

In order to do this I first looked at GCC's -E command line argument, which only runs the preprocessor, however this did far more than I wanted, expanding the included files and adding #line statements.

For example:

#include <stdio.h>

#ifdef DEBUG
    #define debug( s ) puts ( s );
#else
    #define debug( s )
#endif

int main( int argc, char* argv[] )
{
    debug( "Foo" )

    puts( "Hello, World!" );

    return 0;
}

I'd want this to be processed to:

#include <stdio.h>

int main( int argc, char* argv[] )
{


    puts( "Hello, World!" );

    return 0;
}

I could then tidy that up with something like astyle and no manual work would be needed to get exactly what I want.

Is there a directive I'm missing for GCC or is there a tool capable of doing this?

Matt
  • 7,100
  • 3
  • 28
  • 58

6 Answers6

7

If -E is not helping, then try using -fdump-tree-all and if you don't see what you want the that is not-available-in (or) not-provided-by GCC.

OTOH, this question has been discussed in SO as follows, please refer the below to get some ideas.

  1. Can gcc output C code after preprocessing?
  2. How do I see a C/C++ source file after preprocessing in Visual Studio?

Hope it helps!


Hi Mat,

I saw your comment to @nos. But I have one such script handy and so sharing it with you. You can try reading my answer for a similar question here

Copy the below code in a file, say convert.sh. Assign execute permission to that file, chmod +x convert.sh and run it as follows:

$./convert.sh <filename>.c
$cat filename.c.done

The <filename>.c.done will have what you need!

#!/bin/bash

if [[ $# -ne 1 || ! -f $1 ]] ; then
    echo "Invalid args / Check file "
    exit 
fi

file_name=$1

grep '^\s*#\s*include' $file_name > /tmp/include.c
grep -Pv '^\s*#\s*include\b' $file_name > /tmp/code.c
gcc -E /tmp/code.c | grep -v ^# > /tmp/preprocessed.c
cat /tmp/include.c > $file_name.done
cat /tmp/preprocessed.c >> $file_name.done

Hope this helps!

Community
  • 1
  • 1
Sangeeth Saravanaraj
  • 16,027
  • 21
  • 69
  • 98
  • As already mentioned, I know about -E, but it does too much preprocessing, as I only want one statement resolved. So no, this question has not been discussed before as far as I know. I'll try -fdump-tree-all, but as I understand it, that is for outputting the AST after various high level optimisations. – Matt Jan 03 '12 at 15:24
  • @Mat This is a good question and deserves a +1.. so +1 from me! If you come across an answer, please do share it! – Sangeeth Saravanaraj Jan 03 '12 at 15:30
  • comment out the #includes and other macros in your file, then run gcc -E – nos Jan 03 '12 at 17:15
  • As mentioned by @nos comment out the `#includes` and run `gcc -E mac.c | sed '/^\#/d'`. It works! .. I guess writing a script using `grep` to comment out the `#includes` is not a big deal! – Sangeeth Saravanaraj Jan 03 '12 at 17:19
  • @nos, since that's as good an answer as I've seen about this, would you mind writing it as an answer in it's own right so I can mark this as answered. Having done more research that is the only way I know of to do it effectively. – Matt Jan 12 '12 at 12:09
  • That addition is perfect, so thank you. I already had a similar thing going, but doing it a bit more manually. – Matt Jan 12 '12 at 13:28
  • There is an issue with this script if some of the includes are conditionally included themselves. This will include them regardless. – Baptiste Wicht Jun 01 '16 at 07:32
5

gcc -E -nostdinc test.c produces

# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
# 9 "test.c"
int main( int argc, char* argv[] )
{


    puts( "Hello, World!" );

    return 0;
}

and an error to stderr

test.c:1:19: error: no include path in which to search for stdio.h

You can easily filter out the # lines ... and re-add the includes.

pmg
  • 106,608
  • 13
  • 126
  • 198
2

One may use tools like unifdef, unifdefall — remove preprocessor conditionals from code. (Run a "light" preprocessor for GCC)

Community
  • 1
  • 1
Marcin Zaluski
  • 687
  • 5
  • 10
2

There's no direct way to do that with the gcc preprocessor, though if you only include system headers, you might have some luck with gcc -E -nostdinc.

However, you can comment out the #include directives, and other preprocessor directives you don't want processed, and run the code through the preprocessor (gcc -E or cpp) , that way only the macro you want expanded(the ones not commented out) gets expanded.

nos
  • 223,662
  • 58
  • 417
  • 506
1

I know the question is old, but it does have an answer now. The "C Partial Preprocessor" does exactly this.

http://www.muppetlabs.com/~breadbox/software/cppp.html

For reference, if someone else still wonders (I did and found this page).

MartinN
  • 11
  • 1
0

Also cpp -P <file> [outputfile]

a.txt :

file: __FILE__
#ifdef X
"X" has been defined
#endif

cpp -P -DX a.txt