Version 1.0.0-rc17 has been released. Some changes are:
[bpt/coccinelle.git] / parsing_cocci / disjdistr.ml
index b2014ff..80ab024 100644 (file)
@@ -1,27 +1,9 @@
 (*
- * Copyright 2005-2010, 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.
- *)
-
-
-(*
- * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
+ * Copyright 2012, INRIA
+ * Julia Lawall, Gilles Muller
+ * Copyright 2010-2011, 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.
  *
@@ -42,6 +24,7 @@
  *)
 
 
+# 0 "./disjdistr.ml"
 module Ast = Ast_cocci
 module V = Visitor_ast
 
@@ -66,6 +49,11 @@ let rec disjmult f = function
       let rest = disjmult f xs in
       disjmult2 cur rest (function cur -> function rest -> cur :: rest)
 
+let rec disjmult_two fstart frest (start,rest) =
+  let cur = fstart start in
+  let rest = disjmult frest rest in
+  disjmult2 cur rest (function cur -> function rest -> (cur,rest))
+
 let disjoption f = function
     None -> [None]
   | Some x -> List.map (function x -> Some x) (f x)
@@ -81,9 +69,12 @@ let disjdots f d =
 
 let rec disjty ft =
   match Ast.unwrap ft with
-    Ast.Type(cv,ty) ->
+    Ast.Type(allminus,cv,ty) ->
       let ty = disjtypeC ty in
-      List.map (function ty -> Ast.rewrap ft (Ast.Type(cv,ty))) ty
+      List.map (function ty -> Ast.rewrap ft (Ast.Type(allminus,cv,ty))) ty
+  | Ast.AsType(ty,asty) -> (* as ty doesn't contain disj *)
+      let ty = disjty ty in
+      List.map (function ty -> Ast.rewrap ft (Ast.AsType(ty,asty))) ty
   | Ast.DisjType(types) -> List.concat (List.map disjty types)
   | Ast.OptType(ty) ->
       let ty = disjty ty in
@@ -115,15 +106,30 @@ and disjtypeC bty =
        (function ty -> function size ->
          Ast.rewrap bty (Ast.Array(ty,lb,size,rb)))
   | Ast.EnumName(_,_) | Ast.StructUnionName(_,_) -> [bty]
+  | Ast.EnumDef(ty,lb,ids,rb) ->
+      disjmult2 (disjty ty) (disjdots disjexp ids)
+       (function ty -> function ids ->
+         Ast.rewrap bty (Ast.EnumDef(ty,lb,ids,rb)))
   | Ast.StructUnionDef(ty,lb,decls,rb) ->
       disjmult2 (disjty ty) (disjdots disjdecl decls)
        (function ty -> function decls ->
          Ast.rewrap bty (Ast.StructUnionDef(ty,lb,decls,rb)))
   | Ast.TypeName(_) | Ast.MetaType(_,_,_) -> [bty]
 
+and disjident e =
+  match Ast.unwrap e with
+    Ast.DisjId(id_list) -> List.concat (List.map disjident id_list)
+  | Ast.OptIdent(id) ->
+      let id = disjident id in
+      List.map (function id -> Ast.rewrap e (Ast.OptIdent(id))) id
+  | Ast.UniqueIdent(id) ->
+      let id = disjident id in
+      List.map (function id -> Ast.rewrap e (Ast.UniqueIdent(id))) id
+  | _ -> [e]
+
 and disjexp e =
   match Ast.unwrap e with
-    Ast.Ident(_) | Ast.Constant(_) -> [e]
+    Ast.Ident(_) | Ast.Constant(_) -> [e] (* even Ident can't contain disj *)
   | Ast.FunCall(fn,lp,args,rp) ->
       disjmult2 (disjexp fn) (disjdots disjexp args)
        (function fn -> function args ->
@@ -132,6 +138,10 @@ and disjexp e =
       disjmult2 (disjexp left) (disjexp right)
        (function left -> function right ->
          Ast.rewrap e (Ast.Assignment(left,op,right,simple)))
+  | Ast.Sequence(left,op,right) ->
+      disjmult2 (disjexp left) (disjexp right)
+       (function left -> function right ->
+         Ast.rewrap e (Ast.Sequence(left,op,right)))
   | Ast.CondExpr(exp1,why,Some exp2,colon,exp3) ->
       let res = disjmult disjexp [exp1;exp2;exp3] in
       List.map
@@ -189,10 +199,16 @@ and disjexp e =
   | Ast.TypeExp(ty) ->
       let ty = disjty ty in
       List.map (function ty -> Ast.rewrap e (Ast.TypeExp(ty))) ty
+  | Ast.Constructor(lp,ty,rp,init) ->
+      disjmult2 (disjty ty) (disjini init)
+       (function ty ->
+         function exp -> Ast.rewrap e (Ast.Constructor(lp,ty,rp,init)))
   | Ast.MetaErr(_,_,_,_) | Ast.MetaExpr(_,_,_,_,_,_)
   | Ast.MetaExprList(_,_,_,_) | Ast.EComma(_) -> [e]
-  | Ast.DisjExpr(exp_list) ->
-      List.concat (List.map disjexp exp_list)
+  | Ast.AsExpr(exp,asexp) -> (* as exp doesn't contain disj *)
+      let exp = disjexp exp in
+      List.map (function exp -> Ast.rewrap e (Ast.AsExpr(exp,asexp))) exp
+  | Ast.DisjExpr(exp_list) -> List.concat (List.map disjexp exp_list)
   | Ast.NestExpr(starter,expr_dots,ender,whencode,multi) ->
       (* not sure what to do here, so ambiguities still possible *)
       [e]
@@ -210,6 +226,9 @@ and disjparam p =
   | Ast.Param(ty,id) ->
       let ty = disjty ty in
       List.map (function ty -> Ast.rewrap p (Ast.Param(ty,id))) ty
+  | Ast.AsParam(pm,asexp) -> (* as exp doesn't contain disj *)
+      let pm = disjparam pm in
+      List.map (function pm -> Ast.rewrap p (Ast.AsParam(pm,asexp))) pm
   | Ast.MetaParam(_,_,_) | Ast.MetaParamList(_,_,_,_) | Ast.PComma(_) -> [p]
   | Ast.Pdots(dots) | Ast.Pcircles(dots) -> [p]
   | Ast.OptParam(param) ->
@@ -221,14 +240,22 @@ and disjparam p =
 
 and disjini i =
   match Ast.unwrap i with
-    Ast.MetaInit(_,_,_) -> [i]
+    Ast.MetaInit(_,_,_) | Ast.MetaInitList(_,_,_,_) -> [i]
+  | Ast.AsInit(ini,asini) ->
+      let ini = disjini ini in
+      List.map (function ini -> Ast.rewrap i (Ast.AsInit(ini,asini))) ini
   | Ast.InitExpr(exp) ->
       let exp = disjexp exp in
       List.map (function exp -> Ast.rewrap i (Ast.InitExpr(exp))) exp
-  | Ast.InitList(lb,initlist,rb,whencode) ->
+  | Ast.ArInitList(lb,initlist,rb) ->
+      List.map
+       (function initlist ->
+         Ast.rewrap i (Ast.ArInitList(lb,initlist,rb)))
+       (disjdots disjini initlist)
+  | Ast.StrInitList(allminus,lb,initlist,rb,whencode) ->
       List.map
        (function initlist ->
-         Ast.rewrap i (Ast.InitList(lb,initlist,rb,whencode)))
+         Ast.rewrap i (Ast.StrInitList(allminus,lb,initlist,rb,whencode)))
        (disjmult disjini initlist)
   | Ast.InitGccExt(designators,eq,ini) ->
       let designators = disjmult designator designators in
@@ -242,6 +269,7 @@ and disjini i =
        (function ini -> Ast.rewrap i (Ast.InitGccName(name,eq,ini)))
        ini
   | Ast.IComma(comma) -> [i]
+  | Ast.Idots(dots,_) -> [i]
   | Ast.OptIni(ini) ->
       let ini = disjini ini in
       List.map (function ini -> Ast.rewrap i (Ast.OptIni(ini))) ini
@@ -261,7 +289,12 @@ and designator = function
 
 and disjdecl d =
   match Ast.unwrap d with
-    Ast.Init(stg,ty,id,eq,ini,sem) ->
+    Ast.MetaDecl(_,_,_) | Ast.MetaField(_,_,_)
+  | Ast.MetaFieldList(_,_,_,_) -> [d]
+  | Ast.AsDecl(decl,asdecl) ->
+      let decl = disjdecl decl in
+      List.map (function decl -> Ast.rewrap d (Ast.AsDecl(decl,asdecl))) decl
+  | Ast.Init(stg,ty,id,eq,ini,sem) ->
       disjmult2 (disjty ty) (disjini ini)
        (function ty -> function ini ->
          Ast.rewrap d (Ast.Init(stg,ty,id,eq,ini,sem)))
@@ -272,6 +305,10 @@ and disjdecl d =
       List.map
        (function args -> Ast.rewrap d (Ast.MacroDecl(name,lp,args,rp,sem)))
        (disjdots disjexp args)
+  | Ast.MacroDeclInit(name,lp,args,rp,eq,ini,sem) ->
+      disjmult2 (disjdots disjexp args) (disjini ini)
+       (function args -> function ini ->
+         Ast.rewrap d (Ast.MacroDeclInit(name,lp,args,rp,eq,ini,sem)))
   | Ast.TyDecl(ty,sem) ->
       let ty = disjty ty in
       List.map (function ty -> Ast.rewrap d (Ast.TyDecl(ty,sem))) ty
@@ -279,7 +316,7 @@ and disjdecl d =
       let ty = disjty ty in (* disj not allowed in id *)
       List.map (function ty -> Ast.rewrap d (Ast.Typedef(stg,ty,id,sem))) ty
   | Ast.DisjDecl(decls) -> List.concat (List.map disjdecl decls)
-  | Ast.Ddots(_,_) | Ast.MetaDecl(_,_,_) -> [d]
+  | Ast.Ddots(_,_) -> [d]
   | Ast.OptDecl(decl) ->
       let decl = disjdecl decl in
       List.map (function decl -> Ast.rewrap d (Ast.OptDecl(decl))) decl
@@ -312,9 +349,10 @@ let rec disj_rule_elem r k re =
        (function decl -> Ast.rewrap re (Ast.Decl(bef,allminus,decl)))
   | Ast.SeqStart(brace) -> re
   | Ast.SeqEnd(brace) -> re
-  | Ast.ExprStatement(exp,sem) ->
+  | Ast.ExprStatement(Some exp,sem) ->
       orify_rule_elem re exp
-       (function exp -> Ast.rewrap re (Ast.ExprStatement(exp,sem)))
+       (function exp -> Ast.rewrap re (Ast.ExprStatement(Some exp,sem)))
+  | Ast.ExprStatement(None,sem) -> re
   | Ast.IfHeader(iff,lp,exp,rp) ->
       orify_rule_elem re exp
        (function exp -> Ast.rewrap re (Ast.IfHeader(iff,lp,exp,rp)))
@@ -326,12 +364,20 @@ let rec disj_rule_elem r k re =
   | Ast.WhileTail(whl,lp,exp,rp,sem) ->
       orify_rule_elem re exp
        (function exp -> Ast.rewrap re (Ast.WhileTail(whl,lp,exp,rp,sem)))
-  | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) ->
-      generic_orify_rule_elem (disjmult (disjoption disjexp)) re [e1;e2;e3]
-       (function
-           [exp1;exp2;exp3] ->
-             Ast.rewrap re (Ast.ForHeader(fr,lp,exp1,sem1,exp2,sem2,exp3,rp))
-         | _ -> failwith "not possible")
+  | Ast.ForHeader(fr,lp,first,e2,sem2,e3,rp) ->
+      let disjfirst = function
+         Ast.ForExp(e1,sem1) ->
+           List.map (function e1 -> Ast.ForExp(e1,sem1))
+             (disjoption disjexp e1)
+       | Ast.ForDecl (bef,allminus,decl) ->
+           List.map (function decl -> Ast.ForDecl (bef,allminus,decl))
+             (disjdecl decl) in
+      generic_orify_rule_elem
+       (disjmult_two disjfirst (disjoption disjexp)) re (first,[e2;e3])
+        (function
+            (first,[exp2;exp3]) ->
+              Ast.rewrap re (Ast.ForHeader(fr,lp,first,exp2,sem2,exp3,rp))
+          |  _ -> failwith "not possible")
   | Ast.IteratorHeader(whl,lp,args,rp) ->
       generic_orify_rule_elem (disjdots disjexp) re args
        (function args -> Ast.rewrap re (Ast.IteratorHeader(whl,lp,args,rp)))
@@ -355,6 +401,7 @@ let rec disj_rule_elem r k re =
       orify_rule_elem_ini re init
        (function init -> Ast.rewrap init (Ast.TopInit(init)))
   | Ast.Include(inc,s) -> re
+  | Ast.Undef(def,id) -> re
   | Ast.DefineHeader(def,id,params) -> re
   | Ast.Default(def,colon) -> re
   | Ast.Case(case,exp,colon) ->
@@ -369,7 +416,7 @@ let disj_all =
   let donothing r k e = k e in
   V.rebuilder
     mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
-    donothing donothing donothing donothing
+    donothing donothing donothing donothing donothing
     donothing donothing donothing donothing donothing donothing donothing
     disj_rule_elem donothing donothing donothing donothing
 
@@ -386,7 +433,7 @@ let collect_all_isos =
     mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
     donothing donothing donothing donothing donothing donothing donothing
     donothing donothing donothing donothing donothing donothing donothing
-    donothing doanything
+    donothing donothing doanything
 
 let collect_iso_info =
   let mcode x = x in
@@ -400,6 +447,7 @@ let collect_iso_info =
   V.rebuilder
     mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
     donothing donothing donothing donothing donothing donothing donothing
+     donothing
     donothing donothing donothing donothing rule_elem donothing donothing
     donothing donothing