On Sat, 20 Aug 2011, Simon wrote:
> I followed the install.txt instructions and have been playing around
> with coccinelle-1.0.0-rc5 on Ubuntu 11.04 and have some questions:
>
> I'm interested in the idea of creating different builds of the same C source
> file by instrumenting the source file on the fly. For example, I might have
> a release build of foo.c and a debug build of foo.c. The debug version of
> foo.c might have access to reflective functions and data which are only
> available in the debug version. My idea is to use coccinelle to create those
> functions and data on the fly. A simple example is as follows: Let's say
> foo.c contains an enum. I'd like to auto-generate a reflective function
> which given an enum, returns the enum as a string for logging/debugging
> purposes. Of course, I could just write such an enum to string function
> myself, but then every time I change the enum then I'd have to update the
> enum to string function. How can I use coccinelle to give my scripts the
> info about foo.c that they need in order to auto-generate such an enum to
> string function? I have been playing around with -token_c and -type_c which
> look promising. Is this the right way to go for what I want to do? How can I
> learn more about using -token_c and understanding the output?
I'm not sure that -token_c or -type_c are what you want. Actually, I
don't know what -token_c is. When I try it, it tells me that it is an
unknown option. -type_c just pretty prints the source code with the type
information.
In general, what you want to do would be rather awkward, because
Coccinelle does not really provide facilities for converting things to
strings. Also there is no way to match only enum declarations and get the
complete information about the declaration, although that could be fixed.
If you wanted to know the fields in a structure, you could do the
following:
@r@
identifier str;
field list fs;
@@
struct str { fs } ;
@script:ocaml s@
str << r.str;
fs << r.fs;
res;
@@
res := Printf.sprintf "\"struct %s { %s };\\n\"" str fs
@@
identifier s.res;
@@
int main() {
++ printf(res);
...
}
The middle rule converts the information to a string, which the third rule
uses as an identifier, because only identifiers can be imported from a
scripting language to SmPL code. But this is a hack, because after the
transformation, the identifier will look like a string. You can use
python rather than ocaml, if you prefer. See demos/pythontococci.cocci
for an example.
> Another thing that I've been thinking about is how coccinelle deals with
> #include files. Where can I read up on its handling of included header
> files?
http://coccinelle.lip6.fr/docs/options.pdf, in the section about include
files (page 6). There is a typo - really_all_includes should be
recursive_includes.
The various options give various heuristics for finding include files.
Include files are mostly useful for giving type information. Coccinelle
tries to parse C code independent of macro definitions, so having the
macro definitions from the include files is not likely to improve parsing.
> Assuming there is a good answer to the first part of my question, in an
> extreme example, how could I get coccinelle to tell me whether INVISIBLE is
> part of cardsuit or not for my particular build? Obviously my script which
> wants to auto-generate the debug_cardsuit_enum_to_text() function needs to
> know whether DIAMONDS will be 1 or 2.
>
> enum cardsuit {
> CLUBS,
> #ifdef SECRETSUIT
> INVISIBLE,
> #endif
> DIAMONDS,
> HEARTS,
> SPADES
> };
Coccinelle is not build-sensitive at all. It has no idea whether a
particular #ifdef constant is defined. You may want to look at undertaker
(Lohmann et al). Their work is oriented towards configuration issues.
julia
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)