Reputation: 940
I have a lot of preprocessing magic happening in header files. I'd like to view the results of such magic on my source file, but without all the #include stuff there.
For example, when I run the preprocessor on
#include<stdio.h>
#define astring "hello world"
int main()
{
printf("%s\n",astring);
return 0;
}
I get 27k lines of output. I'd like just the last 7 or so lines in this case.
Sometimes I want the results of certain include directives, others (like nearly always the system headers) I'd like to ignore.
Rarely I'll have include directives in unusual spots, these too I'd like the option of omitting or keeping output.
Are there any tools/methods out there to help me?
EDIT: The goal is not to get compilable code. In my case the preprocessor functionally changes the source code (for example using the preprocessor to implement template like functionality in c) and viewing the postprocessed source is useful for debugging. I'm using the gnu cpreprocessor through gcc/g++, which as far as i know is calling cpp.
Upvotes: 1
Views: 648
Reputation: 241841
A possible simple solution is to insert start and end markers around the program text whose expansion you care about. While you cannot insert markers using comments, you can achieve the same effect with #pragma
directives, at least with common C compilers.
According to the standard (§6.10.6) a pragma directive is either recognised by the implementation and then has implementation-defined behaviour (which might cause the compilation to fail) or it is not recognised by the implementation, in which case it is ignored. Since implementation-defined behaviour must be documented by a conforming implementation, it should, in theory, be possible to ascertain which pragmas are recognised by the implementation, and then you can use anything which doesn't match that pattern. In practice, it is rarely that simple, but in general the first token following "#pragma" will identify the compiler or subsystem, so most pragmas recognised by gcc will start with the token GCC
. (There are lots of legacy pragmas, though.)
So you might have to experiment a bit, but at least on the compilers I had kicking around, the lines
#pragma X_PPTRACE 0
and
#pragma X_PPTRACE 1
were just passed through by the preprocessor (albeit with a warning enabled by -Wall
), allowing for a very simple awk program:
gcc -Wall -Wno-unknown-pragmas -E ... |
awk '/#pragma[[:space:]]+X_PPTRACE/{trace=$3;}trace'
Upvotes: 1
Reputation: 7324
I came up with this just playing around with gcc -E
and awk
. I noticed that gcc -E
outputs lines of the format # <linenum> "<filename>" <other stuff>
when going into other files. So basically, if I can keep track of that filename I can print out the lines I care about.
I'm not skilled in awk
so there may be a more efficient way to do this.
gcc -E example.c | awk '
/^#/ { filename = $3 }
!/^#/ {
if (filename == "\"example.c\"")
print $0
}'
If the line starts with #
, then store the filename. Otherwise, if the filename is the one I care about, print out the line. Replace example.c
with your filename.
For your example this outputs:
int main()
{
printf("%s\n","hello world");
return 0;
}
I'm not sure if it's 100% correct (I don't know if there can be other lines starting with #
for example). You can play around with it to get to something you want.
Upvotes: 1