Coccinelle release 0.2.5-rc3
[bpt/coccinelle.git] / engine / cocci_vs_c.ml
index 9457777..1e9249e 100644 (file)
  *)
 
 
-(* Yoann Padioleau, Julia Lawall
- *
- * Copyright (C) 2006, 2007, 2008 Ecole des Mines de Nantes
- * Copyright (C) 2009, 2010 DIKU, INRIA, LIP6
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License (GPL)
- * version 2 as published by the Free Software Foundation.
- *
- * This program 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
- * file license.txt for more details.
- *
- * This file was part of Coccinelle.
- *)
-
 open Common
 
 module A = Ast_cocci
@@ -432,6 +415,11 @@ let split_signb_baseb_ii (baseb, ii) =
          failwith ("strange type1, maybe because of weird order: "^
                    (String.concat " " (List.map fst iis))) in
       (signed,base_res)
+
+  | B.SizeType, ["size_t",i1] -> None, [i1]
+  | B.SSizeType, ["ssize_t",i1] -> None, [i1]
+  | B.PtrDiffType, ["ptrdiff_t",i1] -> None, [i1]
+
   | _ -> failwith ("strange type2, maybe because of weird order: "^
                   (String.concat " " (List.map fst iis)))
 
@@ -683,7 +671,6 @@ module type PARAM =
     val optional_qualifier_flag : (bool -> tin -> 'x tout) -> (tin -> 'x tout)
     val value_format_flag: (bool -> tin -> 'x tout) -> (tin -> 'x tout)
 
-
   end
 
 (*****************************************************************************)
@@ -1732,20 +1719,32 @@ and (declaration: (A.mcodekind * bool * A.declaration,B.declaration) matcher) =
           )))
 
   | _, (B.DeclList (xs, iiptvirgb::iifakestart::iisto)) ->
-      if X.mode =*= PatternMode
+      let indexify l =
+       let rec loop n = function
+           [] -> []
+         | x::xs -> (n,x)::(loop (n+1) xs) in
+       loop 0 l in
+      let rec repln n vl cur = function
+         [] -> []
+       | x::xs ->
+           if n = cur then vl :: xs else x :: (repln n vl (cur+1) xs) in
+      if X.mode =*= PatternMode || A.get_safe_decl decla
       then
-        xs +> List.fold_left (fun acc var ->
-          acc >||> (
+        (indexify xs) +> List.fold_left (fun acc (n,var) ->
+         (* consider all possible matches *)
+          acc >||> (function tin -> (
             X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart ->
               onedecl allminus decla (var, iiptvirgb, iisto) >>=
                 (fun decla (var, iiptvirgb, iisto) ->
                   return (
                     (mckstart, allminus, decla),
-                    (B.DeclList ([var], iiptvirgb::iifakestart::iisto))
-                  )))))
+                   (* adjust the variable that was chosen *)
+                    (B.DeclList (repln n var 0 xs,
+                                iiptvirgb::iifakestart::iisto))
+                  )))) tin))
           fail
       else
-        failwith "More that one variable in decl. Have to split to transform."
+        failwith "More that one variable in decl. Have to split to transform.  Check that there is no transformation on the type or the ;"
 
   | A.MacroDecl (sa,lpa,eas,rpa,enda), B.MacroDecl ((sb,ebs),ii) ->
       let (iisb, lpb, rpb, iiendb, iifakestart, iistob) =
@@ -1918,7 +1917,6 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
        B.v_attr = attrs;
        B.v_type_bis = typbbis;
      }, iivirg) ->
-
        tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
        fullType typa typb >>= (fun typa typb ->
        ident_cpp DontKnow ida nameidb >>= (fun ida nameidb ->
@@ -2605,9 +2603,12 @@ and simulate_signed ta basea stringsa signaopt tb baseb ii rebuilda =
       (* handle some iso on type ? (cf complex C rule for possible implicit
         casting) *)
       match basea, baseb with
-      | A.VoidType,  B.Void
-      | A.FloatType, B.FloatType (B.CFloat)
-      | A.DoubleType, B.FloatType (B.CDouble) ->
+      | A.VoidType,   B.Void
+      | A.FloatType,  B.FloatType (B.CFloat)
+      | A.DoubleType, B.FloatType (B.CDouble)
+      |        A.SizeType,   B.SizeType
+      |        A.SSizeType,  B.SSizeType
+      |        A.PtrDiffType,B.PtrDiffType ->
            assert (signaopt =*= None);
           let stringa = tuple_of_list1 stringsa in
            let (ibaseb) = tuple_of_list1 ii in
@@ -2693,7 +2694,8 @@ and simulate_signed ta basea stringsa signaopt tb baseb ii rebuilda =
             "warning: long double not handled by ast_cocci";
           fail
 
-      | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+      | _, (B.Void|B.FloatType _|B.IntType _
+           |B.SizeType|B.SSizeType|B.PtrDiffType) -> fail
 
 and simulate_signed_meta ta basea signaopt tb baseb ii rebuilda =
       (* In ii there is a list, sometimes of length 1 or 2 or 3.
@@ -2732,7 +2734,8 @@ and simulate_signed_meta ta basea signaopt tb baseb ii rebuilda =
 
           )
 
-      | (B.Void|B.FloatType _|B.IntType _) -> fail
+      | (B.Void|B.FloatType _|B.IntType _
+         |B.SizeType|B.SSizeType|B.PtrDiffType) -> fail
 
 and (typeC: (A.typeC, Ast_c.typeC) matcher) =
   fun ta tb ->
@@ -3214,7 +3217,10 @@ and compatible_base_type a signa b =
   let ok  = return ((),()) in
 
   match a, b with
-  | Type_cocci.VoidType, B.Void ->
+  | Type_cocci.VoidType,    B.Void
+  | Type_cocci.SizeType,    B.SizeType
+  | Type_cocci.SSizeType,   B.SSizeType
+  | Type_cocci.PtrDiffType, B.PtrDiffType ->
       assert (signa =*= None);
       ok
   | Type_cocci.CharType, B.IntType B.CChar when signa =*= None ->
@@ -3241,7 +3247,8 @@ and compatible_base_type a signa b =
       fail
   | Type_cocci.BoolType, _ -> failwith "no booltype in C"
 
-  | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+  | _, (B.Void|B.FloatType _|B.IntType _
+        |B.SizeType|B.SSizeType|B.PtrDiffType) -> fail
 
 and compatible_base_type_meta a signa qua b ii local =
   match a, b with
@@ -3259,7 +3266,8 @@ and compatible_base_type_meta a signa qua b ii local =
       pr2_once "no longdouble in cocci";
       fail
 
-  | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+  | _, (B.Void|B.FloatType _|B.IntType _
+        |B.SizeType|B.SSizeType|B.PtrDiffType) -> fail
 
 
 and compatible_type a (b,local) =
@@ -3550,8 +3558,7 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
   | _, F.EndStatement _ | _, F.CaseNode _
   | _, F.TrueNode | _, F.FalseNode | _, F.AfterNode
   | _, F.FallThroughNode | _, F.LoopFallThroughNode
-  | _, F.InLoopNode
-    -> fail2()
+  | _, F.InLoopNode -> fail2()
 
   (* really ? diff between pattern.ml and transformation.ml *)
   | _, F.Fake -> fail2()
@@ -3967,6 +3974,15 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
           )))
       else fail
 
+  | A.Undef(undefa,ida), F.DefineHeader ((idb, ii), B.Undef) ->
+      let (defineb, iidb, ieol) = tuple_of_list3 ii in
+      ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
+      tokenf undefa defineb >>= (fun undefa defineb ->
+        return (
+         A.Undef(undefa,ida),
+          F.DefineHeader ((idb,[defineb;iidb;ieol]),B.Undef)
+        ))
+      )
 
 
   | A.DefineHeader(definea,ida,params), F.DefineHeader ((idb, ii), defkind) ->
@@ -4066,7 +4082,8 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
     (F.Label (_, _, _)|F.Break (_, _)|F.Continue (_, _)|F.Default (_, _)|
     F.Case (_, _)|F.Include _|F.Goto _|F.ExprStatement _|
     F.DefineType _|F.DefineExpr _|F.DefineTodo|
-    F.DefineHeader (_, _)|F.ReturnExpr (_, _)|F.Return (_, _)|F.MacroIterHeader (_, _)|
+    F.DefineHeader (_, _)|F.ReturnExpr (_, _)|F.Return (_, _)|
+    F.MacroIterHeader (_, _)|
     F.SwitchHeader (_, _)|F.ForHeader (_, _)|F.DoWhileTail _|F.DoHeader (_, _)|
     F.WhileHeader (_, _)|F.Else _|F.IfHeader (_, _)|
     F.SeqEnd (_, _)|F.SeqStart (_, _, _)|