[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