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)