On Sun, 20 Feb 2011, Oliver McFadden wrote:

> Hi,
> 
> I am wondering whether it would be possible for Coccinelle to
> automatically remove unnecessary braces as detected by Linux's
> checkpatch.pl
> 
> For example, here is the original code:
> 
> > void Vec3Lerp(vec3_t a, const vec3_t b, const vec3_t c, const float frac)
> > {
> >     int i;
> > 
> >     if (frac <= 0.0) {
> >             for (i = 0; i < 3; i++) {
> >                     a[i] = b[i];
> >             }
> >     } else if (frac >= 1.0) {
> >             for (i = 0; i < 3; i++) {
> >                     a[i] = c[i];
> >             }
> >     } else {
> >             for (i = 0; i < 3; i++) {
> >                     a[i] = b[i] + frac * (c[i] - b[i]);
> >             }
> >     }
> > }
> 
> I would like to automatically translate such code into:
> 
> > void Vec3Lerp(vec3_t a, const vec3_t b, const vec3_t c, const float frac)
> > {
> >     int i;
> > 
> >     if (frac <= 0.0)
> >             for (i = 0; i < 3; i++)
> >                     a[i] = b[i];
> >     else if (frac >= 1.0)
> >             for (i = 0; i < 3; i++)
> >                     a[i] = c[i];
> >     else
> >             for (i = 0; i < 3; i++)
> >                     a[i] = b[i] + frac * (c[i] - b[i]);
> > }
> 
> Would this be possible, also taking into account the fact that the
> single-statement's can be nested? (As in this vector linear
> interpolation example given above.)

I think it should be fine.  If you make a semantic patch that only removes 
the braces, as follows:

@@
statement S;
@@

- {
S
- }

then the nested case will take care of itself.  On the other hand, if you 
do:

@@
statement S;
@@

- { S }
+ S

then the nested case will cause problems because you are proposing to 
write back S as is and to make a transformation within S.

The other problem is that sometimes you can't make the transformation, eg 
in:

if (x) { if (y) z(); }
else a();

For this, you should match the cases you don't want to transform (perhaps 
only this one?) and then transform the rest.  That would be:

@r@
statement S1,S2;
position p;
@@

if (...) {@p if (...) S1 } else S2

@@
statement S;
position p != r.p;
@@

@@
statement S;
@@

- {@p
S
- }

You can also say position p != {a.b, c.d, ...}  when there are several 
inherited positions you want p to be different from.  p can only be 
compared to inherited positions.

Sometimes an option when there are cases where you don't want to do 
something, you can combine the cases into a disjunction, like:

(
pattern_not_to_transform
|
- x();
+ y();
)

That doesn't work in this case, because a disjunction is evaluated at each 
node in the control-flow graph.  In the case of the nested ifs, the 
pattern you don't want to transform matches starting at a different place 
than the pattern you do want to transform.  So the disjunction would match 
according to the if at the root of the if and then it would also match 
according to the { S } at that root, and that would cause a 
transformation.

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

Reply via email to