On Tue, 29 Mar 2011, Alexander Monakov wrote:

> Hi,
> 
> I'm trying to figure out how to use a counter (updated from a python
> script) in a transformation rule. Suppose I want to rewrite
> 
>   bar();
>   bar();
>   bar();
> 
> into
> 
>   bar(0);
>   bar(1);
>   bar(2);
> 
> I've concocted the following recipe but it doesn't work.
> 
> @script:python defcounter@
> counter;
> @@
> counter = 0
> coccinelle.counter = 0
> 
> @matchbar@
> position barp;
> identifier defcounter.counter;
> @@
> - bar@barp();
> + bar(counter);
> 
> @script:python@
> dummy << matchbar.barp;
> @@
> counter = counter + 1
> coccinelle.counter = counter
> print coccinelle.counter
> 
> I guess I need more magic to update the right counter. Any suggestions?

@initialize:python@
ctr = 0

@matchbar@
position barp;
@@
bar@barp();

@script:python defcounter@
dummy << matchbar.barp;
counter;
@@
ctr = ctr + 1
coccinelle.counter = ctr

@@
position matchbar.barp;
identifier defcounter.counter;
@@
- bar@barp();
+ bar(counter);

This is for the case where you want one counter for all of the files you 
are treating.  If you want a separate counter per file, then change the 
first rule to:

@script:python@
@@
ctr = 0

That will get executed once per file.  It would also be possible to have a 
spearate counter per function, but then you would have to match each 
function separately.  Write back if that is what you want and don't see 
how to do it.

Another, more concise solution, is:

@@
fresh identifier x = "";
@@

- bar();
+ bar(x);

This is a fresh identifier where the identifier begins with an empty 
string.  It turns out to give the same thing.

An interesting thing is that Coccinelle reparses the code that is 
generated.  So if you want to make another rule that processes your calls 
to bar, then the argument should be an expression or an int, not an 
identifier, because 1, 2, etc are reparsed as integers.

julia
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)

Reply via email to