Coccinelle release 1.0.0-rc3
[bpt/coccinelle.git] / parsing_cocci / context_neg.ml
index 096002d..11e310d 100644 (file)
@@ -1,5 +1,7 @@
 (*
- * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
+ * 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.
  *
@@ -328,6 +330,13 @@ let classify is_minus all_marked table code =
 
   (* no whencode in plus tree so have to drop it *)
   (* need special cases for dots, nests, and disjs *)
+  let ident r k e =
+    compute_result Ast0.ident e
+      (match Ast0.unwrap e with
+       Ast0.DisjId(starter,id_list,_,ender) ->
+         disj_cases e starter id_list r.VT0.combiner_rec_ident ender
+      |        _ -> k e) in
+
   let expression r k e =
     compute_result Ast0.expr e
       (match Ast0.unwrap e with
@@ -438,7 +447,7 @@ let classify is_minus all_marked table code =
       (do_nothing Ast0.dotsExpr) (do_nothing Ast0.dotsInit)
       (do_nothing Ast0.dotsParam) (do_nothing Ast0.dotsStmt)
       (do_nothing Ast0.dotsDecl) (do_nothing Ast0.dotsCase)
-      (do_nothing Ast0.ident) expression typeC initialiser param declaration
+      ident expression typeC initialiser param declaration
       statement case_line (do_top Ast0.top) in
   combiner.VT0.combiner_rec_top_level code
 
@@ -467,12 +476,17 @@ let dots fn d1 d2 =
 let rec equal_ident i1 i2 =
   match (Ast0.unwrap i1,Ast0.unwrap i2) with
     (Ast0.Id(name1),Ast0.Id(name2)) -> equal_mcode name1 name2
-  | (Ast0.MetaId(name1,_,_),Ast0.MetaId(name2,_,_)) ->
+  | (Ast0.MetaId(name1,_,_,_),Ast0.MetaId(name2,_,_,_)) ->
       equal_mcode name1 name2
   | (Ast0.MetaFunc(name1,_,_),Ast0.MetaFunc(name2,_,_)) ->
       equal_mcode name1 name2
   | (Ast0.MetaLocalFunc(name1,_,_),Ast0.MetaLocalFunc(name2,_,_)) ->
       equal_mcode name1 name2
+  | (Ast0.DisjId(starter1,_,mids1,ender1),
+     Ast0.DisjId(starter2,_,mids2,ender2)) ->
+      equal_mcode starter1 starter2 &&
+      List.for_all2 equal_mcode mids1 mids2 &&
+      equal_mcode ender1 ender2
   | (Ast0.OptIdent(_),Ast0.OptIdent(_)) -> true
   | (Ast0.UniqueIdent(_),Ast0.UniqueIdent(_)) -> true
   | _ -> false
@@ -539,6 +553,8 @@ let rec equal_typeC t1 t2 =
       equal_mcode lb1 lb2 && equal_mcode rb1 rb2
   | (Ast0.EnumName(kind1,_),Ast0.EnumName(kind2,_)) ->
       equal_mcode kind1 kind2
+  | (Ast0.EnumDef(_,lb1,_,rb1),Ast0.EnumDef(_,lb2,_,rb2)) ->
+       equal_mcode lb1 lb2 && equal_mcode rb1 rb2
   | (Ast0.StructUnionName(kind1,_),Ast0.StructUnionName(kind2,_)) ->
       equal_mcode kind1 kind2
   | (Ast0.FunctionType(ty1,lp1,p1,rp1),Ast0.FunctionType(ty2,lp2,p2,rp2)) ->
@@ -560,7 +576,11 @@ let rec equal_typeC t1 t2 =
 
 let equal_declaration d1 d2 =
   match (Ast0.unwrap d1,Ast0.unwrap d2) with
-    (Ast0.Init(stg1,_,_,eq1,_,sem1),Ast0.Init(stg2,_,_,eq2,_,sem2)) ->
+    (Ast0.MetaDecl(name1,_),Ast0.MetaDecl(name2,_))
+  | (Ast0.MetaField(name1,_),Ast0.MetaField(name2,_))
+  | (Ast0.MetaFieldList(name1,_,_),Ast0.MetaFieldList(name2,_,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.Init(stg1,_,_,eq1,_,sem1),Ast0.Init(stg2,_,_,eq2,_,sem2)) ->
       equal_option stg1 stg2 && equal_mcode eq1 eq2 && equal_mcode sem1 sem2
   | (Ast0.UnInit(stg1,_,_,sem1),Ast0.UnInit(stg2,_,_,sem2)) ->
       equal_option stg1 stg2 && equal_mcode sem1 sem2
@@ -590,8 +610,12 @@ let equal_initialiser i1 i2 =
   match (Ast0.unwrap i1,Ast0.unwrap i2) with
     (Ast0.MetaInit(name1,_),Ast0.MetaInit(name2,_)) ->
       equal_mcode name1 name2
+  | (Ast0.MetaInitList(name1,_,_),Ast0.MetaInitList(name2,_,_)) ->
+      equal_mcode name1 name2
   | (Ast0.InitExpr(_),Ast0.InitExpr(_)) -> true
-  | (Ast0.InitList(lb1,_,rb1),Ast0.InitList(lb2,_,rb2)) ->
+  | (Ast0.InitList(lb1,_,rb1,o1),Ast0.InitList(lb2,_,rb2,o2)) ->
+      (* can't compare orderedness, because this can differ between -
+        and + code *)
       (equal_mcode lb1 lb2) && (equal_mcode rb1 rb2)
   | (Ast0.InitGccExt(designators1,eq1,_),
      Ast0.InitGccExt(designators2,eq2,_)) ->
@@ -685,6 +709,8 @@ let rec equal_statement s1 s2 =
   | (Ast0.Stars(d1,_),Ast0.Stars(d2,_)) -> equal_mcode d1 d2
   | (Ast0.Include(inc1,name1),Ast0.Include(inc2,name2)) ->
       equal_mcode inc1 inc2 && equal_mcode name1 name2
+  | (Ast0.Undef(def1,_),Ast0.Undef(def2,_)) ->
+      equal_mcode def1 def2
   | (Ast0.Define(def1,_,_,_),Ast0.Define(def2,_,_,_)) ->
       equal_mcode def1 def2
   | (Ast0.OptStm(_),Ast0.OptStm(_)) -> true
@@ -715,7 +741,7 @@ let equal_case_line c1 c2 =
 
 let rec equal_top_level t1 t2 =
   match (Ast0.unwrap t1,Ast0.unwrap t2) with
-    (Ast0.DECL(_),Ast0.DECL(_)) -> true
+    (Ast0.NONDECL(_),Ast0.NONDECL(_)) -> true
   | (Ast0.FILEINFO(old_file1,new_file1),Ast0.FILEINFO(old_file2,new_file2)) ->
       equal_mcode old_file1 old_file2 && equal_mcode new_file1 new_file2
   | (Ast0.CODE(_),Ast0.CODE(_)) -> true
@@ -835,10 +861,11 @@ let plus_table =
 
 let iscode t =
   match Ast0.unwrap t with
-    Ast0.DECL(_) -> true
+    Ast0.NONDECL(_) -> true
   | Ast0.FILEINFO(_) -> true
   | Ast0.ERRORWORDS(_) -> false
   | Ast0.CODE(_) -> true
+  | Ast0.TOPCODE(_)
   | Ast0.OTHER(_) -> failwith "unexpected top level code"
 
 (* ------------------------------------------------------------------- *)
@@ -852,7 +879,7 @@ let concat = function
          [] -> []
        | x::rest ->
            (match Ast0.unwrap x with
-             Ast0.DECL(s) -> let stms = loop rest in s::stms
+             Ast0.NONDECL(s) -> let stms = loop rest in s::stms
            | Ast0.CODE(ss) ->
                let stms = loop rest in
                (match Ast0.unwrap ss with
@@ -933,14 +960,17 @@ let rec is_toplevel s =
     Ast0.Decl(_,e) -> true
   | Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true
   | Ast0.Disj(_,stmts,_,_) -> isall is_toplevel stmts
-  | Ast0.ExprStatement(fc,_) ->
+  | Ast0.ExprStatement(Some fc,_) ->
       (match Ast0.unwrap fc with
        Ast0.FunCall(_,_,_,_) -> true
       |        _ -> false)
   | Ast0.Include(_,_) -> true
+  | Ast0.Undef(_,_) -> true
   | Ast0.Define(_,_,_,_) -> true
   | _ -> false
 
+(* consider code and topcode to be the same; difference handled
+in top_level.ml *)
 let check_compatible m p =
   let fail _ =
     failwith
@@ -948,17 +978,21 @@ let check_compatible m p =
         "incompatible minus and plus code starting on lines %d and %d"
         (Ast0.get_line m) (Ast0.get_line p)) in
   match (Ast0.unwrap m, Ast0.unwrap p) with
-    (Ast0.DECL(decl1),Ast0.DECL(decl2)) ->
+    (Ast0.NONDECL(decl1),Ast0.NONDECL(decl2)) ->
       if not (is_decl decl1 && is_decl decl2)
       then fail()
-  | (Ast0.DECL(decl1),Ast0.CODE(code2)) ->
+  | (Ast0.NONDECL(decl1),Ast0.CODE(code2)) ->
+      (* This is probably the only important case.  We don't want to
+        replace top-level declarations by arbitrary code. *)
       let v1 = is_decl decl1 in
       let v2 = List.for_all is_toplevel (Ast0.undots code2) in
-      if !Flag.make_hrule = None && v1 && not v2 then fail()
-  | (Ast0.CODE(code1),Ast0.DECL(decl2)) ->
+      if !Flag.make_hrule = None && v1 && not v2
+      then fail()
+  | (Ast0.CODE(code1),Ast0.NONDECL(decl2)) ->
       let v1 = List.for_all is_toplevel (Ast0.undots code1) in
       let v2 = is_decl decl2 in
-      if v1 && not v2 then fail()
+      if v1 && not v2
+      then fail()
   | (Ast0.CODE(code1),Ast0.CODE(code2)) ->
       let v1 = isonly is_init code1 in
       let v2a = isonly is_init code2 in
@@ -976,7 +1010,8 @@ let check_compatible m p =
          testers;
        let v1 = isonly is_fndecl code1 in
        let v2 = List.for_all is_toplevel (Ast0.undots code2) in
-       if !Flag.make_hrule = None && v1 && not v2 then fail()
+       if !Flag.make_hrule = None && v1 && not v2
+       then fail()
   | (Ast0.FILEINFO(_,_),Ast0.FILEINFO(_,_)) -> ()
   | (Ast0.OTHER(_),Ast0.OTHER(_)) -> ()
   | _ -> fail()
@@ -999,7 +1034,8 @@ let context_neg minus plus =
          List.map
            (function m ->
              classify true
-               (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+               (function _ ->
+                 Ast0.MINUS(ref(Ast.NOREPLACEMENT,Ast0.default_token_info)))
                minus_table m)
            minus in
        []
@@ -1025,7 +1061,8 @@ let context_neg minus plus =
            collect_plus_lines p;
            let _ =
              classify true
-               (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+               (function _ ->
+                 Ast0.MINUS(ref(Ast.NOREPLACEMENT,Ast0.default_token_info)))
                minus_table m in
            let _ = classify false (function c -> Ast0.PLUS c) plus_table p in
            traverse minus_table plus_table;
@@ -1041,7 +1078,9 @@ let context_neg minus plus =
                plus_lines := [];
                let _ =
                  classify true
-                   (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+                   (function _ ->
+                     Ast0.MINUS(ref(Ast.NOREPLACEMENT,
+                                    Ast0.default_token_info)))
                    minus_table m in
                loop(minus,pall)
              end