On Mon, 5 Apr 2010, Emese Revfy wrote:

> Dear Julia,
> I'm trying to develop a coccinelle script that would match structure 
> declarations
> whose only members are function pointers but nothing else.
> Can you tell me how it is possible to express this in coccinelle?
> I already tried this:
> 
> @structure@
> identifier idtype, y;
> type t;
> @@
> struct idtype {
>         t (*y)(...);
>         ... when = t (*y)(...);
> };
> 
> but it didn't work.

It indeed seems to only support when != in this position.  Also, if the 
when = did work, you would have to have used some other metavariables t1 
and y1; otherwise you would be looking for cases where the type and field 
name are always the same, which doesn't make much sense.

There is a way to solve the problem with what is currently supported in 
Coccinelle, but it is a bit more complicated.  Assuming you want to change 
the name of every structure with all function-type fields to "newname", 
you can use the following three rules.

1.  Find the names of all structure types having at least one field of 
function type, and the position of these fields:

@structure@
identifier idtype, y;
type t;
position p;
@@
struct idtype {
  ...
        t (*y)(...);@p
  ...
};

This is basically your rule, without the when and with the addition of the 
position variable p.  I have put the position variable on the ; because 
this is something that all field declarations have.

2.  Find structures that have at least one field of some other type.  
Being of some other type is actually indicated by the ; of the field 
declaration not being at one of the positions collected in the previous 
rule:

@bad@
identifier structure.idtype, y;
type t;
position p != structure.p;
@@

struct idtype {
  ...
        t y;@p
  ...
};

3.  Find structures that satisfy structure but don't satisfy bad.  The 
structures have only function-typed fields, ie fields whose positions were 
collected by structure:

@depends on !bad@
identifier structure.idtype;
@@
struct
- idtype
+ newname
{
  ...
};

If actually you were more interested in doing something with the 
structures that have a non-function type field, then you could just do 
that in bad.


This pattern is actually quite common.  First use one rule to find things 
of the general structure you want.  Then use another rule to match the 
instances you don't want.  Then use depends on in a third rule to process 
everything that matches the first rule but doesn't match the second one.  
Note that the inheritance of idtype in the second and third rules is quite 
important.  That cause the depends on !bad in the third rule to keep some 
values of structure.idtype and throw away other ones.

Diverging a little, you can also use python to throw some matches away, if 
the criterion for doing this requires some computation.  You could for 
example put the following as the second rule:

@script:python@
idtype << structure.idtype;
@@

if (foo(idtype)):
  cocci.include_match(False)

where foo takes the string representing the name of a matched type and 
returns true if it is considered to be undesirable in some way.  Then the 
third rule wouldn't need the depends on !bad, as the undesirable matches 
would have been immediately thrown away in the python rule.

I hope this is helpful.  It is perhaps a bit of a peculiar programming 
style :)

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

Reply via email to