Coccinelle release 0.2.5-rc9
[bpt/coccinelle.git] / parsing_cocci / parse_cocci.ml
index a6d1056..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) *)
 
@@ -31,6 +7,9 @@ module V0 = Visitor_ast0
 module VT0 = Visitor_ast0_types
 module Ast = Ast_cocci
 module Ast0 = Ast0_cocci
+
+exception Bad_virt of string
+
 let pr = Printf.sprintf
 (*let pr2 s = prerr_string s; prerr_string "\n"; flush stderr*)
 let pr2 s = Printf.printf "%s\n" s
@@ -53,13 +32,16 @@ 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"
   | PC.TExpression -> "expression"
   | PC.TIdExpression -> "idexpression"
   | PC.TInitialiser -> "initialiser"
+  | PC.TDeclaration -> "declaration"
+  | PC.TField -> "field"
   | PC.TStatement -> "statement"
   | PC.TPosition -> "position"
   | PC.TPosAny -> "any"
@@ -99,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)
@@ -116,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)
@@ -170,12 +157,8 @@ let token2c (tok,_) =
       |        Ast.SupEq -> ">="
       |        _ -> failwith "not possible")
       ^(line_type2c clt)
-  | PC.TShOp(op,clt) ->
-      (match op with
-       Ast.DecLeft -> "<<"
-      |        Ast.DecRight -> ">>"
-      |        _ -> failwith "not possible")
-      ^(line_type2c clt)
+  | PC.TShLOp(op,clt) -> "<<"^(line_type2c clt)
+  | PC.TShROp(op,clt) -> ">>"^(line_type2c clt)
   | PC.TPlus(clt) -> "+"^(line_type2c clt)
   | PC.TMinus(clt) -> "-"^(line_type2c clt)
   | PC.TMul(clt) -> "*"^(line_type2c clt)
@@ -187,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)
@@ -195,11 +179,14 @@ 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.TMetaStm(_,_,clt)   -> "stmmeta"^(line_type2c clt)
-  | PC.TMetaStmList(_,_,clt)   -> "stmlistmeta"^(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)
   | PC.TMetaLocalFunc(_,_,_,clt) -> "funcmeta"^(line_type2c clt)
   | PC.TMetaPos(_,_,_,clt)   -> "posmeta"
@@ -274,6 +261,7 @@ let token2c (tok,_) =
   | PC.TIsoStatement -> "Statement"
   | PC.TIsoDeclaration -> "Declaration"
   | PC.TIsoType -> "Type"
+  | PC.TUnderscore -> "_"
   | PC.TScriptData s -> s
 
 let print_tokens s tokens =
@@ -287,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)
@@ -311,18 +302,21 @@ let plus_attachable only_plus (tok,_) =
   | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt)
   | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TTildeEq(clt)
   | PC.TLogOp(_,clt)
-  | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
+  | PC.TShLOp(_,clt) | PC.TShROp(_,clt)
+  | 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.TMetaFunc(_,_,_,clt)
-  | PC.TMetaLocalFunc(_,_,_,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)
   | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
@@ -355,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)
@@ -378,18 +375,22 @@ let get_clt (tok,_) =
   | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt)
   | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TTildeEq(clt)
   | PC.TSub(clt) | PC.TLogOp(_,clt)
-  | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
+  | PC.TShLOp(_,clt) | PC.TShROp(_,clt)
+  | 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.TMetaFunc(_,_,_,clt)
-  | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt)
+  | PC.TMetaStmList(_,_,clt)
+  | PC.TMetaDecl(_,_,clt) | PC.TMetaField(_,_,clt)
+  | PC.TMetaFieldList(_,_,_,clt)
+  | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt)
+  | PC.TMetaPos(_,_,_,clt)
 
   | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) |
     PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
@@ -422,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)
@@ -439,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)
@@ -481,13 +486,15 @@ let update_clt (tok,x) clt =
   | PC.TTildeEq(_) -> (PC.TTildeEq(clt),x)
   | PC.TSub(_) -> (PC.TSub(clt),x)
   | PC.TLogOp(op,_) -> (PC.TLogOp(op,clt),x)
-  | PC.TShOp(op,_) -> (PC.TShOp(op,clt),x)
+  | PC.TShLOp(op,_) -> (PC.TShLOp(op,clt),x)
+  | PC.TShROp(op,_) -> (PC.TShROp(op,clt),x)
   | PC.TPlus(_) -> (PC.TPlus(clt),x)
   | PC.TMinus(_) -> (PC.TMinus(clt),x)
   | PC.TMul(_) -> (PC.TMul(clt),x)
   | 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)
@@ -499,8 +506,11 @@ let update_clt (tok,x) clt =
   | PC.TMetaId(a,b,c,_)    -> (PC.TMetaId(a,b,c,clt),x)
   | PC.TMetaType(a,b,_)    -> (PC.TMetaType(a,b,clt),x)
   | PC.TMetaInit(a,b,_)    -> (PC.TMetaInit(a,b,clt),x)
-  | PC.TMetaStm(a,b,_)   -> (PC.TMetaStm(a,b,clt),x)
-  | PC.TMetaStmList(a,b,_)   -> (PC.TMetaStmList(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)
   | PC.TMetaLocalFunc(a,b,c,_) -> (PC.TMetaLocalFunc(a,b,c,clt),x)
 
@@ -607,7 +617,9 @@ 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
   | PC.TType | PC.TParameter | PC.TLocal | PC.Tlist | PC.TFresh
@@ -618,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)
@@ -628,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)
@@ -636,11 +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
@@ -675,7 +692,8 @@ let split_token ((tok,_) as t) =
   | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt)
   | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TTildeEq(clt)
   | PC.TTildeExclEq(clt) | PC.TSub(clt) | PC.TLogOp(_,clt)
-  | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
+  | PC.TShLOp(_,clt) | PC.TShROp(_,clt)
+  | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
   | PC.TDmOp(_,clt) | PC.TTilde (clt) -> split t clt
 
   | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOInit(clt) -> split t clt
@@ -686,7 +704,7 @@ let split_token ((tok,_) as t) =
   | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt)
   | PC.TPtVirg(clt) -> split t clt
 
-  | PC.EOF | PC.TInvalid -> ([t],[t])
+  | PC.EOF | PC.TInvalid | PC.TUnderscore -> ([t],[t])
 
   | PC.TIso | PC.TRightIso
   | PC.TIsoExpression | PC.TIsoStatement | PC.TIsoDeclaration | PC.TIsoType
@@ -711,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
@@ -795,6 +855,9 @@ let detect_types in_meta_decls l =
     | (PC.TMetaExpList(_,_,_,_),_)
     | (PC.TMetaType(_,_,_),_)
     | (PC.TMetaInit(_,_,_),_)
+    | (PC.TMetaDecl(_,_,_),_)
+    | (PC.TMetaField(_,_,_),_)
+    | (PC.TMetaFieldList(_,_,_,_),_)
     | (PC.TMetaStm(_,_,_),_)
     | (PC.TMetaStmList(_,_,_),_)
     | (PC.TMetaPos(_,_,_,_),_) -> in_meta_decls
@@ -856,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)
@@ -875,14 +940,17 @@ let token2line (tok,_) =
 
   | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt)
   | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt)
-  | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
+  | PC.TShLOp(_,clt) | PC.TShROp(_,clt)
+  | 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)
 
@@ -904,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)
@@ -917,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)
@@ -1058,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;
@@ -1188,6 +1259,8 @@ let rec drop_double_dots l =
       [] -> []
     | x::rest when any_before prev && any_after x ->
        (PC.TNothing,i)::x::(loop x rest)
+    | ((PC.TComma(_),_) as c)::x::rest when any_before prev && any_after x ->
+       c::(PC.TNothing,i)::x::(loop x rest)
     | x::rest -> x :: (loop x rest) in
   match l with
     [] -> []
@@ -1317,9 +1390,7 @@ let eval_virt virt =
   List.iter
     (function x ->
       if not (List.mem x virt)
-      then
-        failwith
-          (Printf.sprintf "unknown virtual rule %s\n" x))
+      then raise (Bad_virt x))
     !Flag.defined_virtual_rules
 
 let drop_last extra l = List.rev(extra@(List.tl(List.rev l)))
@@ -1378,8 +1449,8 @@ let get_rule_name parse_fn starts_with_name get_tokens file prefix =
           Ast.CocciRulename (check_name nm,a,b,c,d,e)
       | Ast.GeneratedRulename (nm,a,b,c,d,e) ->
           Ast.GeneratedRulename (check_name nm,a,b,c,d,e)
-      | Ast.ScriptRulename(_,s,deps) ->
-         Ast.ScriptRulename(check_name None,s,deps)
+      | Ast.ScriptRulename(nm,s,deps) ->
+         Ast.ScriptRulename(check_name nm,s,deps)
       | Ast.InitialScriptRulename(_,s,deps) ->
          Ast.InitialScriptRulename(check_name None,s,deps)
       | Ast.FinalScriptRulename(_,s,deps) ->
@@ -1545,6 +1616,7 @@ let parse file =
 
           let parse_cocci_rule ruletype old_metas
              (rule_name, dependencies, iso, dropiso, exists, is_expression) =
+           let dropiso = !Flag_parsing_cocci.disabled_isos @ dropiso in
             Ast0.rule_name := rule_name;
             Data.inheritable_positions :=
                rule_name :: !Data.inheritable_positions;
@@ -1612,7 +1684,8 @@ let parse file =
            *)
 
            (if not !Flag.sgrep_mode2 &&
-             (any_modif minus_res or any_modif plus_res)
+             (any_modif minus_res or any_modif plus_res) &&
+             not(dependencies = Ast.FailDep)
            then Data.inheritable_positions := []);
 
            Check_meta.check_meta rule_name old_metas inherited_metavars
@@ -1640,6 +1713,25 @@ let parse file =
              Data.call_in_meta
                (function _ ->
                  get_script_metavars PC.script_meta_main table file lexbuf) in
+           let (metavars,script_metavars) =
+             List.fold_left
+               (function (metavars,script_metavars) ->
+                 function
+                     (script_var,Some(parent,var)) ->
+                       ((script_var,parent,var) :: metavars, script_metavars)
+                   | ((Some script_var,None),None) ->
+                       (metavars, (name,script_var) :: script_metavars)
+                   | _ -> failwith "not possible")
+               ([],[]) metavars in
+           let metavars = List.rev metavars in
+           let script_metavars = List.rev script_metavars in
+
+           Hashtbl.add Data.all_metadecls name
+             (List.map (function x -> Ast.MetaIdDecl(Ast.NONE,x))
+                script_metavars);
+           Hashtbl.add Lexer_cocci.rule_names name ();
+           (*TODOHashtbl.add Lexer_cocci.all_metavariables name script_metavars;*)
+
 (*
             let exists_in old_metas (py,(r,m)) =
              r = "virtual" or
@@ -1661,7 +1753,9 @@ let parse file =
               (* script code *)
             let (more, tokens) = get_tokens [PC.TArobArob; PC.TArob] in
             let data = collect_script_tokens tokens in
-            (more,Ast0.ScriptRule(name, language, deps, metavars, data),
+            (more,
+            Ast0.ScriptRule(name, language, deps, metavars,
+                            script_metavars, data),
             [],tokens) in
 
           let parse_if_script_rule k name language _ deps =
@@ -1782,8 +1876,8 @@ let process file isofile verbose =
   let parsed =
     List.map
       (function
-          Ast0.ScriptRule (a,b,c,d,e) ->
-           [([],Ast.ScriptRule (a,b,c,d,e))]
+          Ast0.ScriptRule (a,b,c,d,fv,e) ->
+           [([],Ast.ScriptRule (a,b,c,d,fv,e))]
        | Ast0.InitialScriptRule(a,b,c,d) ->
            [([],Ast.InitialScriptRule (a,b,c,d))]
        | Ast0.FinalScriptRule (a,b,c,d) ->
@@ -1879,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)