On Sun, 2015-02-15 at 10:38AM +0100, Julia Lawall wrote:
> On Sat, 14 Feb 2015, Sören Brinkmann wrote:
> 
> > Hi Julia,
> > 
> > On Sat, 2015-02-14 at 07:56PM +0100, Julia Lawall wrote:
> > > On Sat, 14 Feb 2015, Sören Brinkmann wrote:
> > > 
> > > > Hi,
> > > >
> > > > I'm just getting my feet wet with coccinelle, so I'm probably missing
> > > > something really obvious in my problem.
> > > >
> > > > I have a codebase that uses plenty of
> > > >   typedef struct foo {
> > > >         ...
> > > >   } bar;
> > > >
> > > > I want to remove all these typedefs and simply use struct foo instead. I
> > > > came up with this patch:
> > > >
> > > >   /// Convert typdefed structs to structs
> > > >
> > > >   @ rule1 @
> > > >   identifier i;
> > > >   type t;
> > > >   @@
> > > >   -typedef struct i {
> > > >   +struct i {
> > > >         ...
> > > >   - }t;
> > > >   + };
> > > >
> > > >   @@
> > > >   identifier rule1.i;
> > > >   type rule1.t;
> > > >   @@
> > > >   -t
> > > >   +struct i
> > > >   // end of patch
> > > >
> > > > This seems to work for most occurrences, but there are a couple of
> > > > variables defined like this:
> > > >
> > > >   static const t *const baz[MAX] = {
> > > >         ...
> > > >   };
> > > >
> > > > And also function declarations like:
> > > >   u32 fn(const t* const baz);
> > > >
> > > > In such cases, t isn't replaces as I would expect, but those lines
> > > > aren't changed at all.
> > > >
> > > > Other variables and non-const function parameters seem to be replaced as
> > > > expected.
> > > > Does anybody have an idea what I'm missing?
> 
> OK, the issue is that const is considered to be part of the type, so when 
> you have a metavariable that contains type foo, it doesn't match an 
> occurrence of const foo.  I'm not sure if it is correct to consider const 
> to be part of the type, but I'm also not eager to change it.  Could you 
> live with the solution of just making one more rule:
> 
> @@
> identifier rule1.i;
> type rule1.t;
> @@
>  const
> -t
> +struct i

Yes, that works for me. Thanks!

But I just ran into the next controversy:
I extended my patch to also catch typedef forward declarations:

  @ rule4 @
  identifier i;
  type t;
  @@
  -typedef struct i t;
  +struct i;
  
  /* Replace type with struct (forward declarations */
  @ rule5 @
  identifier rule4.i;
  type rule4.t;
  @@
  -t
  +struct i
  
  /* Replace type with struct (forward declarations */
  @ rule6 @
  identifier rule4.i;
  type rule4.t;
  @@
  const
  -t
  +struct i

This works mostly fine, but fails (under certain circumstances) on a
line like this:
  typedef u32 (*const fnptr2)(a_struct_t *strptr);

I did a little bit of testing:
 - the parser chokes on that line unless
   - the u32 typedef is in the same file before the failing line (not
     sure why it's not enough to pull it in through an include)
   - a similar line without the 'const' precedes the failing line e.g.
        typedef u32 (*fnptr)(a_struct_t *strptr);

I attach a patch and c file to reproduce this. Running
'spatch --parse-c --spfile test.cocci testcase2.c' reveals some
parsing issues.  If the annotated line int he c file is commented
in, parsing goes through fine.

        Thanks,
        Soren
@ rule4 @
identifier i;
type t;
@@
-typedef struct i t;
+struct i;

/* Replace type with struct (forward declarations */
@ rule5 @
identifier rule4.i;
type rule4.t;
@@
-t
+struct i

/* Replace type with struct (forward declarations */
@ rule6 @
identifier rule4.i;
type rule4.t;
@@
const
-t
+struct i
#include "types.h"

typedef struct a_struct a_struct_t;

static a_struct_t struct_instance;

/* commenting this in makes coccinelle parse succeed */
//typedef u32 (*fnptr)(a_struct_t *strptr);
typedef u32 (*const fnptr2)(a_struct_t *strptr);
typedef u32 (*fnptr3)(a_struct_t *strptr);
_______________________________________________
Cocci mailing list
[email protected]
https://systeme.lip6.fr/mailman/listinfo/cocci

Reply via email to