selective preprocessor expansion

M

max(01)*

hi.

i want to examine preprocessed source which only has certain macros
expanded, for example i would like to have:

#include <stdio.h>
#include "other.c"
int main() {
...
}

tranformed into:

#include <stdio.h>
<insert here the result of other.c inclusion>
int main() {
...
}

so that #include <stdio.h> is not expanded... in general i would like to
have standard library header macros not expanded...

up to now i only have come up with smt like this:

#ifdef INCLUDE_STDIO
#include <stdio.h>
#endif
#include "other.c"
int main() {
...
}

so that i compile using:

$ cc -DINCLUDE_STDIO source.c

*or* i can examine preprocessed source using:

$ cc -E -P source.c

[note: this is gcc specific, but i think it is clear anyway: -D option
defines a macro, -E option does preprocessing only, -P "cleans up"
output a bit]

any simpler/better/moregeneral/morestandard/moretested method?

bye

max
 
P

Paul Mensonides

any simpler/better/moregeneral/morestandard/moretested method?

If you are willing (or can) annotate the #include directives, yes. You can
create a file called, for example, nothing.h which has no contents. Then define
a macro to remap the inclusions that you want:

#ifndef DISABLE_STD_INCLUDE
#define STD(file) <file>
#else
#define STD(file) "nothing.h"
#endif

#include STD(stdio.h)

Regards,
Paul Mensonides
 
C

Cedric LEMAIRE

I propose you to use CodeWorker, a universal parsing tool and a source
code generator, which can combinate both parsing and code generation
for transforming programs. CodeWorker is a freeware, available at
"http://www.codeworker.org".

I wrote you two little scripts that, I hope, answer your needs. Type:
codeworker ExpandIncludes.cws <c-file1> ... <c-fileN> -I <path1> ...
-I <pathn>

where the leader script "ExpandIncludes.cws" is worth:
// This function searches the location of an included file path,
// or returns an empty string if not found
function getIncludedFilePath(sInclude : value, sCSourcePath : value)
{
// do not expand the file twice
if this.findElement(sInclude.getShortFilename()) return false;
insert this[sInclude.getShortFilename()];
// normalize the path of the included file: '/' only
sInclude = sInclude.replaceString('\\', '/');
// if an absolute path, its location is known with certainty
if sInclude.startString('/') || (sInclude.charAt(1) == ':' &&
sInclude.charAt(2) == '/') {
return sInclude;
}
// is the included file relative to the C source file?
local iIndex = sCSourcePath.findLastString('/');
sCSourcePath = sCSourcePath.leftString($iIndex + 1$);
if existFile(sCSourcePath + sInclude) return sCSourcePath +
sInclude;
// if not, looks into -I switches passed on the command line
if existFile(sInclude) return sInclude;
// failure: included file not found
traceLine("warning: unable to find file \"" + sInclude + "\"");
return false;
}

// iterates all C files passed on the command line and
// expand them
foreach i in _ARGS {
translate("ExpandIncludes.cwp", project, i, i + 'c');
}

and where the BNF translation script "ExpandIncludes.cwp" is worth:
#implicitCopy // What We Parse Is What We Write

// BNF non terminal, whose production rule scans the C source and
// replaces '#include' directives having the file name between double
quotes,
// by the content of the file.
preprocessing ::=
// C++-like comments and whitespaces are ignored
// between BNF terminals and non-terminals, so C are
#ignore(C++)
[
// jumps to the next '#include' or to the next constant string
->[
// do not copy what is parsed during this sequence
// into the output file
#explicitCopy
// BNF terminals to match
'#'
"include"
// read the content of a C-like constant string
#readCString:sInputFile
// do not ignore whitespaces or comments anymore,
// up to the end of the sequence
#!ignore
->'\n'
// construct the correct path for the included file
=> local sPath = getIncludedFilePath(sInputFile,
getInputFilename());
// continue only if the path isn't empty
#check(sPath)
=> {
// the path was found, load its content and
// inject it in the output file (template-based syntax)
// after having applied the expansion on it recursively
traceLine("expand the include file \"" + sPath + "\"");
local sContent = loadFile(sPath);
sContent = translateString("ExpandIncludes.cwp", this,
sContent);
@@sContent@@
}
|
// handle the special case of constant string:
// we may encounter one with '#include ...' inside!
#readCString
// now, the danger is gone!
]
]*
// copy implicitly up to the end of the file
->#empty
;


Note that, to make the script shorter, I don't resolve the conditional
preprocessor directives and I suppose that you don't have two files
with the same name at different directories.


Regards,

Cedric
--
 
M

max(01)*

Eric said:
max(01)* said:
hi.

i want to examine preprocessed source which only has certain macros
expanded, for example i would like to have:
[...]


Question 10.18 in the comp.lang.c Frequently Asked
Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

has some pointers you may find helpful.

oops! my apologies... :-(
thank you very mucho for the pointers...
<OT> anyways, if anyone knows some technique which applies to the gnu
compiler, suggestions are welcome ;-( </OT>

bye, max
 
E

Emmanuel Delahaye

max(01)* wrote on 12/08/04 :
<OT> anyways, if anyone knows some technique which applies to the gnu
compiler, suggestions are welcome ;-( </OT>

They know:
 

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

Similar Threads

Macro expansion : Confusion 2
Preprocessor 0
Preprocessor commands usage. 11
preprocessor bug? 2
Command Line Arguments 0
macro expansion 2
Function is not worked in C 2
Macro expansion in several lines 3

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,017
Latest member
GreenAcreCBDGummiesReview

Latest Threads

Top