[Cocci] Putting a specific #include first
Julia Lawall
julia at diku.dk
Sat Nov 14 11:48:46 CET 2009
> @r@
> @@
> #include <...>
> -#include <std.h>
> @s depends on r@
> @@
> +#include <std.h>
> #include <...>
The problem with this is that #include is a top-level thing, and a rule
cannot contain two top-level things. I'm not sure why the parsing of the
SmPL code didn't give an error about it.
The rather clunky solution is to put positions on occurrences of #include
<...> twice and then use python to see if any of these pairs of positions
are different from each other. If any are, a flag is set. Note that if
there are a lot of includes, this will be quite expensive, because it
considers all possible pairs. Afterwards if the flag is not set, then
python is used again to discard all of the matches, using
cocci.include_match. And then the rules written the original way can be
used, because it is known that the file contains at least two #include
<...>s. The complete semantic patch is attached in incl2.cocci.
This rule should be used with the option -no_includes, because you don't
want #includes in header files to be taken into account.
There was a bug in the process of attaching positions to #includes. A
patch is attached to fix this. This patch has an impact on
parser_cocci_menhir.mly, and thus if you apply the patch, you will need to
have menhir installed to be able to compile the result.
Note that a position variable can only be attached to the end of an
include directive, and not to the #include itself, due to the way the
lexing of #include is done.
julia
-------------- next part --------------
--- a/parsing_cocci/parse_aux.ml 2009-10-21 18:04:45.000000000 +0200
+++ b/parsing_cocci/parse_aux.ml 2009-11-14 11:36:21.000000000 +0100
@@ -59,6 +59,9 @@ let drop_bef (arity,line,lline,offset,co
let drop_aft (arity,line,lline,offset,col,strbef,straft,pos) =
(arity,line,lline,offset,col,strbef,[],pos)
+let drop_pos (arity,line,lline,offset,col,strbef,straft,pos) =
+ (arity,line,lline,offset,col,strbef,straft,Ast0.NoMetaPos)
+
let clt2mcode str = function
(Data.MINUS,line,lline,offset,col,strbef,straft,pos) ->
(str,Ast0.NONE,make_info line lline offset col strbef straft,
--- a/parsing_cocci/parser_cocci_menhir.mly 2009-10-21 18:04:44.000000000 +0200
+++ b/parsing_cocci/parser_cocci_menhir.mly 2009-11-14 11:36:59.000000000 +0100
@@ -634,7 +634,8 @@ filespec:
includes:
TIncludeL
{ Ast0.wrap
- (Ast0.Include(P.clt2mcode "#include" (P.drop_aft (P.id2clt $1)),
+ (Ast0.Include(P.clt2mcode "#include"
+ (P.drop_pos (P.drop_aft (P.id2clt $1))),
let (arity,ln,lln,offset,col,strbef,straft,pos) =
P.id2clt $1 in
let clt =
@@ -644,7 +645,8 @@ includes:
(P.drop_bef clt))) }
| TIncludeNL
{ Ast0.wrap
- (Ast0.Include(P.clt2mcode "#include" (P.drop_aft (P.id2clt $1)),
+ (Ast0.Include(P.clt2mcode "#include"
+ (P.drop_pos (P.drop_aft (P.id2clt $1))),
let (arity,ln,lln,offset,col,strbef,straft,pos) =
P.id2clt $1 in
let clt =
-------------- next part --------------
@script:python@
@@
multi = 0
@r1@
position p1;
@@
#include <...>@p1
@r2@
position p2;
@@
#include <...>@p2
@script:python@
p1 << r1.p1;
p2 << r2.p2;
@@
if int(p1[0].line) != int(p2[0].line) or int(p1[0].column) != int(p2[0].column):
multi = 1
@script:python@
@@
if (multi == 0):
cocci.include_match(False)
@r@
@@
-#include <std.h>
@s depends on r@
@@
+#include <std.h>
#include <...>
More information about the Cocci
mailing list