(*
-* Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* 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-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.
+ *)
(* detect statements that are between dots in the minus code, because they
let modif_before_mcode mc =
match Ast0.get_mcode_mcodekind mc with
Ast0.MINUS mc -> true (*conservative; don't want to hunt right for + code*)
- | Ast0.PLUS -> failwith "not possible"
+ | Ast0.PLUS _ -> failwith "not possible"
| Ast0.CONTEXT mc ->
(match !mc with
(Ast.BEFORE _,_,_) -> true
let modif_after_mcodekind = function
Ast0.MINUS mc -> true (*conservative; don't want to hunt right for + code*)
- | Ast0.PLUS -> failwith "not possible"
+ | Ast0.PLUS _ -> failwith "not possible"
| Ast0.CONTEXT mc ->
(match !mc with
(Ast.AFTER _,_,_) -> true
let modif_before x =
match Ast0.get_mcodekind x with
- Ast0.PLUS -> failwith "not possible"
+ Ast0.PLUS _ -> failwith "not possible"
| Ast0.MINUS mc ->
(match !mc with
(* do better for the common case of replacing a stmt by another one *)
- ([[Ast.StatementTag(s)]],_) ->
+ ([[Ast.StatementTag(s)]],ti) ->
(match Ast.unwrap s with
Ast.IfThen(_,_,_) -> true (* potentially dangerous *)
- | _ -> false)
+ | _ -> mc := ([[Ast.StatementTag(s)]],ti); false)
| (_,_) -> true)
| Ast0.CONTEXT mc | Ast0.MIXED mc ->
(match !mc with
let modif_after x =
match Ast0.get_mcodekind x with
- Ast0.PLUS -> failwith "not possible"
+ Ast0.PLUS _ -> failwith "not possible"
| Ast0.MINUS mc ->
(match !mc with
(* do better for the common case of replacing a stmt by another one *)
- ([[Ast.StatementTag(s)]],_) ->
+ ([[Ast.StatementTag(s)]],ti) ->
(match Ast.unwrap s with
Ast.IfThen(_,_,_) -> true (* potentially dangerous *)
- | _ -> false)
- | (l,_) -> any_statements l)
+ | _ -> mc := ([[Ast.StatementTag(s)]],ti); false)
+ | (l,_) when any_statements l -> true
+ | (l,ti) -> mc := (l,ti); false)
| Ast0.CONTEXT mc | Ast0.MIXED mc ->
(match !mc with
(Ast.AFTER _,_,_) -> true
| Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,(info,aft)) ->
modif_before_mcode fr
| Ast0.Iterator(nm,lp,args,rp,body,(info,aft)) -> left_ident nm
- | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> modif_before_mcode switch
+ | Ast0.Switch(switch,lp,exp,rp,lb,decls,cases,rb) ->
+ modif_before_mcode switch
| Ast0.Break(br,sem) -> modif_before_mcode br
| Ast0.Continue(cont,sem) -> modif_before_mcode cont
| Ast0.Label(l,dd) -> left_ident l
modif_after_mcodekind aft
| Ast0.Iterator(nm,lp,args,rp,body,(info,aft)) ->
modif_after_mcodekind aft
- | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> modif_after_mcode rb
+ | Ast0.Switch(switch,lp,exp,rp,lb,decls,cases,rb) -> modif_after_mcode rb
| Ast0.Break(br,sem) -> modif_after_mcode sem
| Ast0.Continue(cont,sem) -> modif_after_mcode sem
| Ast0.Label(l,dd) -> modif_after_mcode dd
Ast0.MINUS(mc) ->
(match !mc with
(* do better for the common case of replacing a stmt by another one *)
- ([[Ast.StatementTag(s)]],_) ->
+ ([[Ast.StatementTag(s)]],ti) ->
(match Ast.unwrap s with
Ast.IfThen(_,_,_) -> true (* potentially dangerous *)
- | _ -> false)
+ | _ -> mc := ([[Ast.StatementTag(s)]],ti); false)
| (_,_) -> true)
| Ast0.CONTEXT(mc) ->
let (text,tinfo1,tinfo2) = !mc in
| _ -> false)
| Ast0.CONTEXT(mc) -> false
| _ -> false in
- let mcode (_,_,_,mc,_) = mcodekind mc in
+ let mcode (_,_,_,mc,_,_) = mcodekind mc in
let donothing r k e = mcodekind (Ast0.get_mcodekind e) && k e in
List.for_all r.VT0.combiner_rec_statement_dots statement_dots_list
| _ -> k e in
+ let case_line r k e =
+ mcodekind (Ast0.get_mcodekind e) &&
+ match Ast0.unwrap e with
+ Ast0.DisjCase(starter,case_list,mids,ender) ->
+ List.for_all r.VT0.combiner_rec_case_line case_list
+ | _ -> k e in
+
V0.flat_combiner bind option_default
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
dots dots dots dots dots dots
donothing expression typeC donothing donothing declaration
- statement donothing donothing
+ statement case_line donothing
(* needs a special case when there is a Disj or an empty DOTS *)
| Ast0.CONTEXT(mc) ->
let (text,tinfo1,tinfo2) = !mc in
let new_text =
+ (* this is going to be a mess if we allow it to be iterable...
+ there would be one level of braces for every added things.
+ need to come up with something better, or just add {} in the
+ source code. *)
match text with
- Ast.BEFORE(bef) ->
- Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,[[Ast.mkToken "}"]])
- | Ast.AFTER(aft) ->
- Ast.BEFOREAFTER([[Ast.mkToken "{"]],aft@[[Ast.mkToken "}"]])
- | Ast.BEFOREAFTER(bef,aft) ->
- Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,aft@[[Ast.mkToken "}"]])
+ Ast.BEFORE(bef,_) ->
+ Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,[[Ast.mkToken "}"]],
+ Ast.ONE)
+ | Ast.AFTER(aft,_) ->
+ Ast.BEFOREAFTER([[Ast.mkToken "{"]],aft@[[Ast.mkToken "}"]],
+ Ast.ONE)
+ | Ast.BEFOREAFTER(bef,aft,_) ->
+ Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,aft@[[Ast.mkToken "}"]],
+ Ast.ONE)
| Ast.NOTHING ->
- Ast.BEFOREAFTER([[Ast.mkToken "{"]],[[Ast.mkToken "}"]]) in
+ Ast.BEFOREAFTER([[Ast.mkToken "{"]],[[Ast.mkToken "}"]],
+ Ast.ONE) in
Ast0.CONTEXT(ref(new_text,tinfo1,tinfo2))
| Ast0.MIXED(mc) ->
let (text,tinfo1,tinfo2) = !mc in
let new_text =
match text with
- Ast.BEFORE(bef) ->
- Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,[[Ast.mkToken "}"]])
- | Ast.AFTER(aft) ->
- Ast.BEFOREAFTER([[Ast.mkToken "{"]],aft@[[Ast.mkToken "}"]])
- | Ast.BEFOREAFTER(bef,aft) ->
- Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,aft@[[Ast.mkToken "}"]])
+ Ast.BEFORE(bef,_) ->
+ Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,[[Ast.mkToken "}"]],
+ Ast.ONE)
+ | Ast.AFTER(aft,_) ->
+ Ast.BEFOREAFTER([[Ast.mkToken "{"]],aft@[[Ast.mkToken "}"]],
+ Ast.ONE)
+ | Ast.BEFOREAFTER(bef,aft,_) ->
+ Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,aft@[[Ast.mkToken "}"]],
+ Ast.ONE)
| Ast.NOTHING ->
- Ast.BEFOREAFTER([[Ast.mkToken "{"]],[[Ast.mkToken "}"]]) in
+ Ast.BEFOREAFTER([[Ast.mkToken "{"]],[[Ast.mkToken "}"]],
+ Ast.ONE) in
Ast0.MIXED(ref(new_text,tinfo1,tinfo2))
| _ -> failwith "unexpected plus code" in
Ast0.set_mcodekind s new_mcodekind;
- Compute_lines.statement s
+ Compute_lines.compute_statement_lines true s
(* ---------------------------------------------------------------------- *)
do_one
(Ast0.rewrap s
(Ast0.Iterator(nm,lp,args,rp,statement false false body,x)))
- | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+ | Ast0.Switch(switch,lp,exp,rp,lb,decls,cases,rb) ->
do_one
(Ast0.rewrap s
- (Ast0.Switch(switch,lp,exp,rp,lb,
+ (Ast0.Switch(switch,lp,exp,rp,lb,decls,
Ast0.rewrap cases
- (Ast0.DOTS(List.map case_line (Ast0.undots cases))),
+ (Ast0.DOTS
+ (List.map case_line (Ast0.undots cases))),
rb)))
| Ast0.Break(br,sem) -> do_one s
| Ast0.Continue(cont,sem) -> do_one s
Ast0.Default(def,colon,statement_dots false false code)
| Ast0.Case(case,exp,colon,code) ->
Ast0.Case(case,exp,colon,statement_dots false false code)
+ | Ast0.DisjCase(starter,case_lines,mids,ender) ->
+ Ast0.DisjCase(starter,List.map case_line case_lines,mids,ender)
| Ast0.OptCase(case) -> Ast0.OptCase(case_line c))
and do_statement_dots dots_before dots_after = function