Coccinelle release 0.2.5-rc9
[bpt/coccinelle.git] / parsing_cocci / parse_cocci.ml
index 53f6807..7a635c1 100644 (file)
@@ -1,27 +1,3 @@
-(*
- * Copyright 2010, INRIA, University of Copenhagen
- * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
- * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
- * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
- * This file is part of Coccinelle.
- *
- * Coccinelle is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, according to version 2 of the License.
- *
- * Coccinelle is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
- *
- * The authors reserve the right to distribute this or future versions of
- * Coccinelle under other licenses.
- *)
-
-
 (* splits the entire file into minus and plus fragments, and parses each
 separately (thus duplicating work for the parsing of the context elements) *)
 
@@ -56,7 +32,8 @@ let line_type2c tok =
 
 let token2c (tok,_) =
  match tok with
-    PC.TIdentifier -> "identifier"
+    PC.TMetavariable -> "metavariable"
+  | PC.TIdentifier -> "identifier"
   | PC.TType -> "type"
   | PC.TParameter -> "parameter"
   | PC.TConstant -> "constant"
@@ -104,6 +81,9 @@ let token2c (tok,_) =
   | PC.Tfloat(clt) -> "float"^(line_type2c clt)
   | PC.Tlong(clt) -> "long"^(line_type2c clt)
   | PC.Tvoid(clt) -> "void"^(line_type2c clt)
+  | PC.Tsize_t(clt) -> "size_t"^(line_type2c clt)
+  | PC.Tssize_t(clt) -> "ssize_t"^(line_type2c clt)
+  | PC.Tptrdiff_t(clt) -> "ptrdiff_t"^(line_type2c clt)
   | PC.Tstruct(clt) -> "struct"^(line_type2c clt)
   | PC.Tunion(clt) -> "union"^(line_type2c clt)
   | PC.Tenum(clt) -> "enum"^(line_type2c clt)
@@ -121,8 +101,10 @@ let token2c (tok,_) =
 
   | PC.TPragma(Ast.Noindent s,_) -> s
   | PC.TPragma(Ast.Indent s,_)   -> s
+  | PC.TPragma(Ast.Space s,_)   -> s
   | PC.TIncludeL(s,clt) -> (pr "#include \"%s\"" s)^(line_type2c clt)
   | PC.TIncludeNL(s,clt) -> (pr "#include <%s>" s)^(line_type2c clt)
+  | PC.TUndef(clt,_) -> "#undef"^(line_type2c clt)
   | PC.TDefine(clt,_) -> "#define"^(line_type2c clt)
   | PC.TDefineParam(clt,_,_,_) -> "#define_param"^(line_type2c clt)
   | PC.TMinusFile(s,clt) -> (pr "--- %s" s)^(line_type2c clt)
@@ -188,6 +170,7 @@ let token2c (tok,_) =
       ^(line_type2c clt)
   | PC.TTilde (clt) -> "~"^(line_type2c clt)
 
+  | PC.TMeta(_,_,clt) -> "meta"^(line_type2c clt)
   | PC.TMetaParam(_,_,clt) -> "parammeta"^(line_type2c clt)
   | PC.TMetaParamList(_,_,_,clt) -> "paramlistmeta"^(line_type2c clt)
   | PC.TMetaConst(_,_,_,_,clt) -> "constmeta"^(line_type2c clt)
@@ -196,11 +179,12 @@ let token2c (tok,_) =
   | PC.TMetaIdExp(_,_,_,_,clt) -> "idexpmeta"^(line_type2c clt)
   | PC.TMetaLocalIdExp(_,_,_,_,clt) -> "localidexpmeta"^(line_type2c clt)
   | PC.TMetaExpList(_,_,_,clt) -> "explistmeta"^(line_type2c clt)
-  | PC.TMetaId(_,_,_,clt)    -> "idmeta"^(line_type2c clt)
+  | PC.TMetaId(nm,_,_,clt)    -> "idmeta-"^(Dumper.dump nm)^(line_type2c clt)
   | PC.TMetaType(_,_,clt)    -> "typemeta"^(line_type2c clt)
   | PC.TMetaInit(_,_,clt)    -> "initmeta"^(line_type2c clt)
   | PC.TMetaDecl(_,_,clt)    -> "declmeta"^(line_type2c clt)
   | PC.TMetaField(_,_,clt)   -> "fieldmeta"^(line_type2c clt)
+  | PC.TMetaFieldList(_,_,_,clt)   -> "fieldlistmeta"^(line_type2c clt)
   | PC.TMetaStm(_,_,clt)     -> "stmmeta"^(line_type2c clt)
   | PC.TMetaStmList(_,_,clt) -> "stmlistmeta"^(line_type2c clt)
   | PC.TMetaFunc(_,_,_,clt)  -> "funcmeta"^(line_type2c clt)
@@ -291,14 +275,17 @@ type plus = PLUS | NOTPLUS | SKIP
 let plus_attachable only_plus (tok,_) =
   match tok with
     PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
-  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
+  | PC.Tfloat(clt) | PC.Tlong(clt)
+  | PC.Tsize_t(clt) | PC.Tssize_t(clt) | PC.Tptrdiff_t(clt)
+  | PC.Tstruct(clt)
   | PC.Tunion(clt) | PC.Tenum(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt)
   | PC.Tstatic(clt)
   | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt)
   | PC.Tauto(clt) | PC.Tregister(clt)
   | PC.Textern(clt) | PC.Tconst(clt) | PC.Tvolatile(clt)
 
-  | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TDefine(clt,_)
+  | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TUndef(clt,_)
+  | PC.TDefine(clt,_)
   | PC.TDefineParam(clt,_,_,_) | PC.TMinusFile(_,clt) | PC.TPlusFile(_,clt)
 
   | PC.TInc(clt) | PC.TDec(clt)
@@ -319,14 +306,16 @@ let plus_attachable only_plus (tok,_) =
   | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
   | PC.TDmOp(_,clt) | PC.TTilde (clt)
 
-  | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
+  | PC.TMeta(_,_,clt) | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
   | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaErr(_,_,_,clt)
   | PC.TMetaExp(_,_,_,_,clt) | PC.TMetaIdExp(_,_,_,_,clt)
   | PC.TMetaLocalIdExp(_,_,_,_,clt)
   | PC.TMetaExpList(_,_,_,clt)
   | PC.TMetaId(_,_,_,clt)
   | PC.TMetaType(_,_,clt) | PC.TMetaInit(_,_,clt) | PC.TMetaStm(_,_,clt)
-  | PC.TMetaStmList(_,_,clt) | PC.TMetaDecl(_,_,clt) | PC.TMetaField(_,_,clt)
+  | PC.TMetaStmList(_,_,clt)
+  | PC.TMetaDecl(_,_,clt) | PC.TMetaField(_,_,clt)
+  | PC.TMetaFieldList(_,_,_,clt)
   | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt)
 
   | PC.TWhen(clt) |  PC.TWhenTrue(clt) |  PC.TWhenFalse(clt)
@@ -360,13 +349,16 @@ let plus_attachable only_plus (tok,_) =
 let get_clt (tok,_) =
   match tok with
     PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
-  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
+  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt)
+  | PC.Tsize_t(clt) | PC.Tssize_t(clt) | PC.Tptrdiff_t(clt)
+  | PC.Tstruct(clt)
   | PC.Tunion(clt) | PC.Tenum(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt)
   | PC.Tstatic(clt)
   | PC.Tinline(clt) | PC.Tattr(_,clt) | PC.Tauto(clt) | PC.Tregister(clt)
   | PC.Textern(clt) | PC.Tconst(clt) | PC.Tvolatile(clt)
 
-  | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TDefine(clt,_)
+  | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TUndef(clt,_)
+  | PC.TDefine(clt,_)
   | PC.TDefineParam(clt,_,_,_) | PC.TMinusFile(_,clt) | PC.TPlusFile(_,clt)
 
   | PC.TInc(clt) | PC.TDec(clt)
@@ -387,14 +379,16 @@ let get_clt (tok,_) =
   | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
   | PC.TDmOp(_,clt) | PC.TTilde (clt)
 
-  | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
+  | PC.TMeta(_,_,clt) | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
   | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaErr(_,_,_,clt)
   | PC.TMetaExp(_,_,_,_,clt) | PC.TMetaIdExp(_,_,_,_,clt)
   | PC.TMetaLocalIdExp(_,_,_,_,clt)
   | PC.TMetaExpList(_,_,_,clt)
   | PC.TMetaId(_,_,_,clt)
   | PC.TMetaType(_,_,clt) | PC.TMetaInit(_,_,clt) | PC.TMetaStm(_,_,clt)
-  | PC.TMetaStmList(_,_,clt) | PC.TMetaDecl(_,_,clt) | PC.TMetaField(_,_,clt)
+  | PC.TMetaStmList(_,_,clt)
+  | PC.TMetaDecl(_,_,clt) | PC.TMetaField(_,_,clt)
+  | PC.TMetaFieldList(_,_,_,clt)
   | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt)
   | PC.TMetaPos(_,_,_,clt)
 
@@ -429,6 +423,9 @@ let update_clt (tok,x) clt =
   | PC.Tfloat(_) -> (PC.Tfloat(clt),x)
   | PC.Tlong(_) -> (PC.Tlong(clt),x)
   | PC.Tvoid(_) -> (PC.Tvoid(clt),x)
+  | PC.Tsize_t(_) -> (PC.Tsize_t(clt),x)
+  | PC.Tssize_t(_) -> (PC.Tssize_t(clt),x)
+  | PC.Tptrdiff_t(_) -> (PC.Tptrdiff_t(clt),x)
   | PC.Tstruct(_) -> (PC.Tstruct(clt),x)
   | PC.Tunion(_) -> (PC.Tunion(clt),x)
   | PC.Tenum(_) -> (PC.Tenum(clt),x)
@@ -446,6 +443,7 @@ let update_clt (tok,x) clt =
 
   | PC.TIncludeL(s,_) -> (PC.TIncludeL(s,clt),x)
   | PC.TIncludeNL(s,_) -> (PC.TIncludeNL(s,clt),x)
+  | PC.TUndef(_,a) -> (PC.TUndef(clt,a),x)
   | PC.TDefine(_,a) -> (PC.TDefine(clt,a),x)
   | PC.TDefineParam(_,a,b,c) -> (PC.TDefineParam(clt,a,b,c),x)
   | PC.TMinusFile(s,_) -> (PC.TMinusFile(s,clt),x)
@@ -496,6 +494,7 @@ let update_clt (tok,x) clt =
   | PC.TDmOp(op,_) -> (PC.TDmOp(op,clt),x)
   | PC.TTilde (_) -> (PC.TTilde (clt),x)
 
+  | PC.TMeta(a,b,_)      -> (PC.TMeta(a,b,clt),x)
   | PC.TMetaParam(a,b,_) -> (PC.TMetaParam(a,b,clt),x)
   | PC.TMetaParamList(a,b,c,_) -> (PC.TMetaParamList(a,b,c,clt),x)
   | PC.TMetaConst(a,b,c,d,_) -> (PC.TMetaConst(a,b,c,d,clt),x)
@@ -509,6 +508,7 @@ let update_clt (tok,x) clt =
   | PC.TMetaInit(a,b,_)    -> (PC.TMetaInit(a,b,clt),x)
   | PC.TMetaDecl(a,b,_)    -> (PC.TMetaDecl(a,b,clt),x)
   | PC.TMetaField(a,b,_)   -> (PC.TMetaField(a,b,clt),x)
+  | PC.TMetaFieldList(a,b,c,_)   -> (PC.TMetaFieldList(a,b,c,clt),x)
   | PC.TMetaStm(a,b,_)     -> (PC.TMetaStm(a,b,clt),x)
   | PC.TMetaStmList(a,b,_) -> (PC.TMetaStmList(a,b,clt),x)
   | PC.TMetaFunc(a,b,c,_)  -> (PC.TMetaFunc(a,b,c,clt),x)
@@ -617,7 +617,8 @@ let split t clt =
 
 let split_token ((tok,_) as t) =
   match tok with
-    PC.TIdentifier | PC.TConstant | PC.TExpression | PC.TIdExpression
+    PC.TMetavariable | PC.TIdentifier
+  | PC.TConstant | PC.TExpression | PC.TIdExpression
   | PC.TDeclaration | PC.TField
   | PC.TStatement | PC.TPosition | PC.TPosAny | PC.TInitialiser
   | PC.TFunction | PC.TTypedef | PC.TDeclarer | PC.TIterator | PC.TName
@@ -629,7 +630,9 @@ let split_token ((tok,_) as t) =
   | PC.TError | PC.TWords | PC.TGenerated | PC.TNothing -> ([t],[t])
 
   | PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
-  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
+  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt)
+  | PC.Tsize_t(clt) | PC.Tssize_t(clt) | PC.Tptrdiff_t(clt)
+  | PC.Tstruct(clt)
   | PC.Tunion(clt) | PC.Tenum(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt)
   | PC.Tstatic(clt) | PC.Tauto(clt) | PC.Tregister(clt) | PC.Textern(clt)
   | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt)
@@ -639,7 +642,8 @@ let split_token ((tok,_) as t) =
   | PC.TPlusFile(s,clt) | PC.TMinusFile(s,clt)
   | PC.TIncludeL(s,clt) | PC.TIncludeNL(s,clt) ->
       split t clt
-  | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_,_) -> split t clt
+  | PC.TUndef(clt,_) | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_,_) ->
+      split t clt
 
   | PC.TIf(clt) | PC.TElse(clt)  | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt)
   | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt)
@@ -647,12 +651,13 @@ let split_token ((tok,_) as t) =
   | PC.TReturn(clt) | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt)
   | PC.TIdent(_,clt)
   | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt)
-  | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt)
+  | PC.TMeta(_,_,clt) | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt)
   | PC.TMetaIdExp(_,_,_,_,clt) | PC.TMetaLocalIdExp(_,_,_,_,clt)
   | PC.TMetaExpList(_,_,_,clt)
   | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
   | PC.TMetaId(_,_,_,clt) | PC.TMetaType(_,_,clt) | PC.TMetaInit(_,_,clt)
   | PC.TMetaDecl(_,_,clt) | PC.TMetaField(_,_,clt)
+  | PC.TMetaFieldList(_,_,_,clt)
   | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaErr(_,_,_,clt)
   | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt)
   | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt) -> split t clt
@@ -724,35 +729,77 @@ distinguish a function declaration from a function call even if the latter
 has no return type.  Undoubtedly, this is not very nice, but it doesn't
 seem very convenient to refactor the grammar to get around the problem. *)
 
-let rec find_function_names = function
-    [] -> []
-  | ((PC.TIdent(_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest
-  | ((PC.TMetaId(_,_,_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest
-  | ((PC.TMetaFunc(_,_,_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest
-  | ((PC.TMetaLocalFunc(_,_,_,clt),info) as t1)::((PC.TOPar(_),_) as t2)::rest
-    ->
-      let rec skip level = function
-         [] -> ([],false,[])
-       | ((PC.TCPar(_),_) as t)::rest ->
-           let level = level - 1 in
-           if level = 0
-           then ([t],true,rest)
-           else let (pre,found,post) = skip level rest in (t::pre,found,post)
-       | ((PC.TOPar(_),_) as t)::rest ->
-           let level = level + 1 in
-           let (pre,found,post) = skip level rest in (t::pre,found,post)
-       | ((PC.TArobArob,_) as t)::rest
-       | ((PC.TArob,_) as t)::rest
-       | ((PC.EOF,_) as t)::rest -> ([t],false,rest)
-       | t::rest ->
-           let (pre,found,post) = skip level rest in (t::pre,found,post) in
-      let (pre,found,post) = skip 1 rest in
-      (match (found,post) with
-       (true,((PC.TOBrace(_),_) as t3)::rest) ->
-         (PC.TFunDecl(clt),info) :: t1 :: t2 :: pre @
-         t3 :: (find_function_names rest)
-      |        _ -> t1 :: t2 :: pre @ find_function_names post)
-  | t :: rest -> t :: find_function_names rest
+exception Irrelevant
+
+let rec find_function_names l =
+  let is_ident = function
+      (PC.TIdent(_,clt),info)
+    | (PC.TMeta(_,_,clt),info)
+    | (PC.TMetaId(_,_,_,clt),info)
+    | (PC.TMetaFunc(_,_,_,clt),info)
+    | (PC.TMetaLocalFunc(_,_,_,clt),info) -> true
+    | _ -> false in
+  let is_mid = function
+      (PC.TMid0(_),info) -> true
+    | _ -> false in
+  let is_par = function
+      (PC.TOPar0(_),info) -> true
+    | _ -> false in
+  let rec split acc = function
+      [] | [_] -> raise Irrelevant
+    | ((PC.TCPar(_),_) as t1) :: ((PC.TOBrace(_),_) as t2) :: rest ->
+       (List.rev (t1::acc),(t2::rest))
+    | x::xs -> split (x::acc) xs in
+  let rec balanced_name level = function
+      [] -> raise Irrelevant
+    | (PC.TCPar0(_),_)::rest ->
+       let level = level - 1 in
+       if level = 0
+       then rest
+       else balanced_name level rest
+    | (PC.TOPar0(_),_)::rest ->
+       let level = level + 1 in
+       balanced_name level rest
+    | (PC.TArobArob,_)::_ | (PC.TArob,_)::_ | (PC.EOF,_)::_ ->
+       raise Irrelevant
+    | t::rest when is_ident t && level = 0 -> rest
+    | t::rest when is_ident t or is_mid t -> balanced_name level rest
+    | _ -> raise Irrelevant in
+  let rec balanced_args level = function
+      [] -> raise Irrelevant
+    | (PC.TCPar(_),_)::rest ->
+       let level = level - 1 in
+       if level = 0
+       then rest
+       else balanced_args level rest
+    | (PC.TOPar(_),_)::rest ->
+       let level = level + 1 in
+       balanced_args level rest
+    | (PC.TArobArob,_)::_ | (PC.TArob,_)::_ | (PC.EOF,_)::_ ->
+       raise Irrelevant
+    | t::rest -> balanced_args level rest in
+  let rec loop = function
+      [] -> []
+    | t :: rest ->
+       if is_par t or is_mid t or is_ident t
+       then
+         let (t,rest) =
+           try
+             let (bef,aft) = split [] (t::rest) in
+             let rest = balanced_name 0 bef in
+             (match rest with
+               (PC.TOPar(_),_)::_ ->
+                 (match balanced_args 0 rest with
+                   [] ->
+                     let (_,info) as h = List.hd bef in
+                     let clt = get_clt h in
+                     (((PC.TFunDecl(clt),info) :: bef), aft)
+                 | _ -> raise Irrelevant)
+             | _ -> raise Irrelevant)
+           with Irrelevant -> ([t],rest) in
+         t @ (loop rest)
+       else t :: (loop rest) in
+  loop l
 
 (* ----------------------------------------------------------------------- *)
 (* an attribute is an identifier that preceeds another identifier and
@@ -810,6 +857,7 @@ let detect_types in_meta_decls l =
     | (PC.TMetaInit(_,_,_),_)
     | (PC.TMetaDecl(_,_,_),_)
     | (PC.TMetaField(_,_,_),_)
+    | (PC.TMetaFieldList(_,_,_,_),_)
     | (PC.TMetaStm(_,_,_),_)
     | (PC.TMetaStmList(_,_,_),_)
     | (PC.TMetaPos(_,_,_,_),_) -> in_meta_decls
@@ -871,7 +919,9 @@ let detect_types in_meta_decls l =
 let token2line (tok,_) =
   match tok with
     PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
-  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
+  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt)
+  | PC.Tsize_t(clt) | PC.Tssize_t(clt) | PC.Tptrdiff_t(clt)
+  | PC.Tstruct(clt)
   | PC.Tunion(clt) | PC.Tenum(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt)
   | PC.Tstatic(clt) | PC.Tauto(clt) | PC.Tregister(clt) | PC.Textern(clt)
   | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt) | PC.Tconst(clt)
@@ -894,12 +944,13 @@ let token2line (tok,_) =
   | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
   | PC.TDmOp(_,clt) | PC.TTilde (clt)
 
-  | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
+  | PC.TMeta(_,_,clt) | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
   | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt)
   | PC.TMetaIdExp(_,_,_,_,clt) | PC.TMetaLocalIdExp(_,_,_,_,clt)
   | PC.TMetaExpList(_,_,_,clt)
   | PC.TMetaId(_,_,_,clt) | PC.TMetaType(_,_,clt) | PC.TMetaInit(_,_,clt)
   | PC.TMetaDecl(_,_,clt) | PC.TMetaField(_,_,clt)
+  | PC.TMetaFieldList(_,_,_,clt)
   | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt)
   | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt)
 
@@ -921,7 +972,7 @@ let token2line (tok,_) =
 
   | PC.TPtrOp(clt)
 
-  | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_,_)
+  | PC.TUndef(clt,_) | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_,_)
   | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt)
 
   | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt)
@@ -934,6 +985,7 @@ let rec insert_line_end = function
     [] -> []
   | (((PC.TWhen(clt),q) as x)::xs) ->
       x::(find_line_end true (token2line x) clt q xs)
+  | (((PC.TUndef(clt,_),q) as x)::xs)
   | (((PC.TDefine(clt,_),q) as x)::xs)
   | (((PC.TDefineParam(clt,_,_,_),q) as x)::xs) ->
       x::(find_line_end false (token2line x) clt q xs)
@@ -1075,6 +1127,8 @@ are not allowed. *)
 
 let rec collect_all_pragmas collected = function
     (PC.TPragma(s,(_,line,logical_line,offset,col,_,_,pos)),_)::rest ->
+      Printf.printf "Pragma on line %d and logical line %d\n" line
+       logical_line;
       let i =
        { Ast0.line_start = line; Ast0.line_end = line;
          Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
@@ -1919,15 +1973,17 @@ let process file isofile verbose =
               | Some mv_fp -> [(extra_meta @ metavars, minus_ast); mv_fp])
 (*          Ast0.CocciRule ((minus, metavarsm, (iso, dropiso, dependencies, rule_name, exists)), (plus, metavars))*)
       rules in
+
   let parsed = List.concat parsed in
+  let parsed = Safe_for_multi_decls.safe_for_multi_decls parsed in
   let disjd = Disjdistr.disj parsed in
 
   let (metavars,code,fvs,neg_pos,ua,pos) = Free_vars.free_vars disjd in
   if !Flag_parsing_cocci.show_SP
   then List.iter Pretty_print_cocci.unparse code;
 
-  let (grep_tokens,glimpse_tokens) =
+  let search_tokens =
     Common.profile_code "get_glimpse_constants" (* for glimpse *)
       (fun () -> Get_constants2.get_constants code neg_pos) in
 
-  (metavars,code,fvs,neg_pos,ua,pos, grep_tokens,glimpse_tokens)
+  (metavars,code,fvs,neg_pos,ua,pos,search_tokens)