Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
298 lines (258 sloc) 4.33 KB
//
// Use list_for_each_entry instead of list_for_each
//
// Target: Linux
// Copyright: 2012 - LIP6/INRIA
// License: Licensed under ISC. See LICENSE or http://www.isc.org/software/license
// Author: Julia Lawall <Julia.Lawall@lip6.fr>
// URL: http://coccinelle.lip6.fr/
// URL: http://coccinellery.org/
// prepare for transformation
@@
idexpression struct list_head *I;
@@
- I
+ _Y(I)
@@
identifier I;
expression E;
iterator list_for_each_rcu;
statement S;
@@
list_for_each_rcu(
- _Y(I)
+ _X(I)
,E)
S
@@
identifier I;
expression E;
iterator list_for_each;
statement S;
@@
list_for_each(
- _Y(I)
+ _X(I)
,E)
S
@@
identifier I;
expression E;
iterator list_for_each_prev;
statement S;
@@
list_for_each_prev(
- _Y(I)
+ _X(I)
,E)
S
@@
type T;
identifier I;
expression E;
@@
list_entry(
- _Y(I)
+ _X(I)
,T,E)
// the case where the list element is just stored in a variable
@r@
type T,T1;
identifier I, x;
expression E, E1, E2;
iterator list_for_each_entry_rcu;
@@
<... when != _Y(I)
- list_for_each_rcu(_X(I),E1)
+ list_for_each_entry_rcu(x,E1,E2)
{
... when != \(_Y(I)\|_X(I)\|x=E\)
when != T1 x;
- x = list_entry(_X(I),T,E2);
... when != \(_Y(I)\|_X(I)\|x=E\)
}
...>
@ra@
type T,T1;
identifier I, x;
expression E, E1, E2;
iterator list_for_each_entry;
@@
<... when != _Y(I)
- list_for_each(_X(I),E1)
+ list_for_each_entry(x,E1,E2)
{
... when != \(_Y(I)\|_X(I)\|x=E\)
when != T1 x;
- x = list_entry(_X(I),T,E2);
... when != \(_Y(I)\|_X(I)\|x=E\)
}
...>
@rb@
type T,T1;
identifier I, x;
expression E, E1, E2;
iterator list_for_each_entry_reverse;
@@
<... when != _Y(I)
- list_for_each_prev(_X(I),E1)
+ list_for_each_entry_reverse(x,E1,E2)
{
... when != \(_Y(I)\|_X(I)\|x=E\)
when != T1 x;
- x = list_entry(_X(I),T,E2);
... when != \(_Y(I)\|_X(I)\|x=E\)
}
...>
// instances of the above that we can't treat because of the local variable
// problem. seems better to do nothing.
@r1@
type T,T1;
identifier I, x;
expression E1, E2;
@@
list_for_each_rcu(
- _X(I)
+ _Y(I)
,E1)
{
...
(
T1 x;
...
x =
- list_entry(_X(I),T,E2);
+ _LOCAL_DECL(list_entry(_X(I),T,E2));
|
T1 x =
- list_entry(_X(I),T,E2);
+ _LOCAL_DECL(list_entry(_X(I),T,E2));
)
...
}
@r1a@
type T,T1;
identifier I, x;
expression E1, E2;
@@
list_for_each(
- _X(I)
+ _Y(I)
,E1)
{
...
(
T1 x;
...
x =
- list_entry(_X(I),T,E2);
+ _LOCAL_DECL(list_entry(_X(I),T,E2));
|
T1 x =
- list_entry(_X(I),T,E2);
+ _LOCAL_DECL(list_entry(_X(I),T,E2));
)
...
}
@r1b@
type T,T1;
identifier I, x;
expression E1, E2;
@@
list_for_each_prev(
- _X(I)
+ _Y(I)
,E1)
{
...
(
T1 x;
...
x =
- list_entry(_X(I),T,E2);
+ _LOCAL_DECL(list_entry(_X(I),T,E2));
|
T1 x =
- list_entry(_X(I),T,E2);
+ _LOCAL_DECL(list_entry(_X(I),T,E2));
)
...
}
// the case where the list element is used for something else (often a return)
@@
type T;
identifier I;
expression E1, E2;
@@
- struct list_head *I;
+ T *I;
<+... when != _Y(I)
- list_for_each_rcu(_X(I),E1)
+ list_for_each_entry_rcu(I,E1,E2)
{
<+... when != _Y(I)
- list_entry(_X(I),T,E2)
+ I
...+>
}
...+>
@@
type T;
identifier I;
expression E1, E2;
@@
- struct list_head *I;
+ T *I;
<+... when != _Y(I)
- list_for_each(_X(I),E1)
+ list_for_each_entry(I,E1,E2)
{
<+... when != _Y(I)
- list_entry(_X(I),T,E2)
+ I
...+>
}
...+>
@@
type T;
identifier I;
expression E1, E2;
@@
- struct list_head *I;
+ T *I;
<+... when != _Y(I)
- list_for_each_prev(_X(I),E1)
+ list_for_each_entry_reverse(I,E1,E2)
{
<+... when != _Y(I)
- list_entry(_X(I),T,E2)
+ I
...+>
}
...+>
// clean up
@@
struct list_head *I;
@@
(
- _X(I)
+ I
|
- _Y(I)
+ I
)
@@
expression I;
@@
(
- _X(I)
+ _INCONSISTENT_MODIF(I)
|
- _Y(I)
+ _INCONSISTENT_MODIF(I)
)
@ depends on r || ra @
identifier I;
@@
- struct list_head *I;
... when != I