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)
