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)