On Sun, 2011-02-20 at 08:35 +0100, ext Julia Lawall wrote:
> 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.

Yes, this one seemed to work nicely on my smaller code base (haven't
tested it on my larger code base yet) without causing any immediately
noticeable problems.

> 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();

Right, but I am quite sure that gcc will warn you about an "ambiguous
else statement" if you write code like:

if (x)
        if (y)
                z();
else    /* gcc warns about this: it can't know which if this else goes with */
        a();

If I remember correctly gcc will warn and treat the ambiguous "else"
statement as matching the innermost "if" statement (which is of course
wrong in this case.)

> 
> 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.

Thanks for the info. I will have to read over this further because there
is still a lot about SmPL and spatch I do not yet understand. I think in
my case the first example (and perhaps with the second example for
safety) is adequate.

> 
> julia


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

Reply via email to