Hi Julia,
FYI this is what -token_c does for me:
$ cat foo.c
#include <stdio.h>
int
main(void)
{
printf("hello world!\n");
}
$ spatch -tokens_c foo.c
init_defs_builtins: /usr/local/share/coccinelle/standard.h
Tag100 (("#include ", "<stdio.h>", (0), ((("#include <stdio.h>", 0, 1, 0,
"foo.c")), (0), ((0, 0, 0, 0)))))
Tag2 (((("\n", 18, 1, 18, "foo.c")), (0), ((0, 0, 0, 0))))
Tag2 (((("\n", 19, 2, 0, "foo.c")), (0), ((0, 0, 0, 0))))
Tag50 (((("int", 20, 3, 0, "foo.c")), (0), ((0, 0, 0, 0))))
Tag2 (((("\n", 23, 3, 3, "foo.c")), (0), ((0, 0, 0, 0))))
Tag8 (("main", ((("main", 24, 4, 0, "foo.c")), (0), ((0, 0, 0, 0)))))
Tag11 (((("(", 28, 4, 4, "foo.c")), (0), ((0, 0, 0, 0))))
Tag56 (((("void", 29, 4, 5, "foo.c")), (0), ((0, 0, 0, 0))))
Tag12 ((((")", 33, 4, 9, "foo.c")), (0), ((0, 0, 0, 0))))
Tag2 (((("\n", 34, 4, 10, "foo.c")), (0), ((0, 0, 0, 0))))
Tag13 (((("{", 35, 5, 0, "foo.c")), (0), ((0, 0, 0, 0))))
Tag2 (((("\n ", 36, 5, 1, "foo.c")), (0), ((0, 0, 0, 0))))
Tag8 (("printf", ((("printf", 41, 6, 4, "foo.c")), (0), ((0, 0, 0, 0)))))
Tag11 (((("(", 47, 6, 10, "foo.c")), (0), ((0, 0, 0, 0))))
Tag7 ((("hello world!\\n", 1), ((("\"hello world!\\n\"", 48, 6, 11,
"foo.c")), (0), ((0, 0, 0, 0)))))
Tag12 ((((")", 64, 6, 27, "foo.c")), (0), ((0, 0, 0, 0))))
Tag29 ((((";", 65, 6, 28, "foo.c")), (0), ((0, 0, 0, 0))))
Tag2 (((("\n", 66, 6, 29, "foo.c")), (0), ((0, 0, 0, 0))))
Tag14 (((("}", 67, 7, 0, "foo.c")), (0), ((0, 0, 0, 0))))
Tag2 (((("\n", 68, 7, 1, "foo.c")), (0), ((0, 0, 0, 0))))
Tag126 (((("", 69, 7, 0, "foo.c")), (0), ((0, 0, 0, 0))))
--
Simon
On Sat, Aug 20, 2011 at 10:11 PM, Julia Lawall <[email protected]> wrote:
> 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)