Run preprocessor only but with only for certain st

2019-02-03 06:53发布

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?

5条回答
一夜七次
2楼-- · 2019-02-03 07:30

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.

查看更多
在下西门庆
3楼-- · 2019-02-03 07:30

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).

查看更多
来,给爷笑一个
4楼-- · 2019-02-03 07:31

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.

查看更多
Root(大扎)
5楼-- · 2019-02-03 07:35

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

查看更多
爷、活的狠高调
6楼-- · 2019-02-03 07:48

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!

查看更多
登录 后发表回答