Coccinelle release 1.0.0-rc3
[bpt/coccinelle.git] / parsing_cocci / insert_plus.ml
index ff69633..74854aa 100644 (file)
@@ -1,3 +1,27 @@
+(*
+ * 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.
+ *)
+
+
 (* The error message "no available token to attach to" often comes in an
 argument list of unbounded length.  In this case, one should move a comma so
 that there is a comma after the + code. *)
@@ -378,6 +402,7 @@ let verify l =
     l
 
 let process_minus minus =
+  Hashtbl.clear root_token_table;
   create_root_token_table minus;
   List.concat
     (List.map
@@ -504,7 +529,7 @@ let collect_plus_nodes root =
 
   let toplevel r k e =
     match Ast0.unwrap e with
-      Ast0.DECL(s) -> r.VT0.combiner_rec_statement s
+      Ast0.NONDECL(s) -> r.VT0.combiner_rec_statement s
     | Ast0.CODE(sdots) -> r.VT0.combiner_rec_statement_dots sdots
     | _ -> do_nothing mk_code r k e in
 
@@ -675,7 +700,12 @@ let decl = function Decl -> true | Favored | Unfavored | Toplevel -> false
 let favored = function Favored -> true | Unfavored | Toplevel | Decl -> false
 
 let top_code =
-  List.for_all (List.for_all (function Ast.Code _ -> true | _ -> false))
+  List.for_all
+    (List.for_all (function Ast.Code _ | Ast.Pragma _ -> true | _ -> false))
+
+let storage_code =
+  List.for_all
+    (List.for_all (function Ast.StorageTag _ -> true | _ -> false))
 
 (* The following is probably not correct.  The idea is to detect what
 should be placed completely before the declaration.  So type/storage
@@ -751,14 +781,19 @@ let init thing info =
      Ast0.left_offset = info.Ast0.pos_info.Ast0.offset;
      Ast0.right_offset = info.Ast0.pos_info.Ast0.offset})
 
+let it2c = function Ast.ONE -> "one" | Ast.MANY -> "many"
+
 let attachbefore (infop,c,p) = function
     Ast0.MINUS(replacements) ->
       let (repl,ti) = !replacements in
-      let (bef,ti) =
-       match repl with
-         [] -> init p infop
-       | repl -> insert p infop repl ti in
-      replacements := (bef,ti)
+      (match repl with
+       Ast.NOREPLACEMENT ->
+         let (bef,ti) = init p infop in
+         replacements := (Ast.REPLACEMENT(bef,c),ti)
+      | Ast.REPLACEMENT(repl,it) ->
+         let it = Ast.lub_count it c in
+         let (bef,ti) = insert p infop repl ti in
+         replacements := (Ast.REPLACEMENT(bef,it),ti))
   | Ast0.CONTEXT(neighbors) ->
       let (repl,ti1,ti2) = !neighbors in
       (match repl with
@@ -782,11 +817,14 @@ let attachbefore (infop,c,p) = function
 let attachafter (infop,c,p) = function
     Ast0.MINUS(replacements) ->
        let (repl,ti) = !replacements in
-       let (aft,ti) =
-       match repl with
-         [] -> init p infop
-       | repl -> insert p infop repl ti in
-       replacements := (aft,ti)
+       (match repl with
+       Ast.NOREPLACEMENT ->
+         let (aft,ti) = init p infop in
+         replacements := (Ast.REPLACEMENT(aft,c),ti)
+      | Ast.REPLACEMENT(repl,it) ->
+         let it = Ast.lub_count it c in
+         let (aft,ti) = insert p infop repl ti in
+         replacements := (Ast.REPLACEMENT(aft,it),ti))
   | Ast0.CONTEXT(neighbors) ->
       let (repl,ti1,ti2) = !neighbors in
       (match repl with
@@ -825,16 +863,22 @@ let allminus = function
 
 let rec before_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function
     [] -> ()
-  | (((infop,_,_) as p) :: ps) as all ->
+  | (((infop,_,pcode) as p) :: ps) as all ->
       if less_than_start infop infom1 or
        (allminus m1 && less_than_end infop infom1) (* account for trees *)
       then
-       if good_start infom1
-       then (attachbefore p m1; before_m1 x1 x2 rest ps)
+       if toplevel f1
+       then
+         if storage_code pcode
+         then before_m2 x2 rest all (* skip fake token for storage *)
+         else (attachbefore p m1; before_m1 x1 x2 rest ps)
        else
-         failwith
-           (pr "%d: no available token to attach to"
-              infop.Ast0.pos_info.Ast0.line_start)
+         if good_start infom1
+         then (attachbefore p m1; before_m1 x1 x2 rest ps)
+         else
+           failwith
+             (pr "%d: no available token to attach to"
+                infop.Ast0.pos_info.Ast0.line_start)
       else after_m1 x1 x2 rest all
 
 and after_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function
@@ -927,15 +971,18 @@ let merge_one : (minus_join_point * Ast0.info * 'a) list *
   Printf.printf "minus code\n";
   List.iter
     (function (_,info,_) ->
-      Printf.printf "start %d end %d real_start %d real_end %d\n"
+      Printf.printf
+       "start %d end %d real_start %d real_end %d attachable start %b attachable end %b\n"
        info.Ast0.pos_info.Ast0.logical_start
        info.Ast0.pos_info.Ast0.logical_end
        info.Ast0.pos_info.Ast0.line_start
-       info.Ast0.pos_info.Ast0.line_end)
+       info.Ast0.pos_info.Ast0.line_end
+       info.Ast0.attachable_start
+       info.Ast0.attachable_end)
     m;
   Printf.printf "plus code\n";
   List.iter
-    (function (info,p) ->
+    (function (info,_,p) ->
       Printf.printf "start %d end %d real_start %d real_end %d\n"
        info.Ast0.pos_info.Ast0.logical_start
        info.Ast0.pos_info.Ast0.logical_end