permit multiline comments and strings in macros
[bpt/coccinelle.git] / parsing_cocci / safe_for_multi_decls.ml
... / ...
CommitLineData
1(*
2 * Copyright 2012, INRIA
3 * Julia Lawall, Gilles Muller
4 * Copyright 2010-2011, INRIA, University of Copenhagen
5 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
6 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
7 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
8 * This file is part of Coccinelle.
9 *
10 * Coccinelle is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, according to version 2 of the License.
13 *
14 * Coccinelle is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
21 *
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
24 *)
25
26
27# 0 "./safe_for_multi_decls.ml"
28(* This phase sets the safe_for_multi_decls field, which is normally false,
29to true for transformations on declarations where the only change is on the
30declared variable. This is the only kind of change on such a declaration
31that can safely be done without splitting the declaration. *)
32
33module Ast = Ast_cocci
34module V = Visitor_ast
35
36let mcode _ (_,_,kind,_) =
37 match kind with
38 Ast.MINUS(_,_,_,_) -> true
39 | Ast.PLUS _ -> failwith "not possible"
40 | Ast.CONTEXT(_,info) -> not (info = Ast.NOTHING)
41
42let contains_modif =
43 let bind x y = x or y in
44 let option_default = false in
45 let do_nothing r k e = k e in
46 let rule_elem r k re =
47 let res = k re in
48 match Ast.unwrap re with
49 Ast.FunHeader(bef,_,fninfo,name,lp,params,rp) ->
50 bind (mcode r ((),(),bef,[])) res
51 | Ast.Decl(bef,_,decl) -> bind (mcode r ((),(),bef,[])) res
52 | _ -> res in
53 let init r k i =
54 let res = k i in
55 match Ast.unwrap i with
56 Ast.StrInitList(allminus,_,_,_,_) -> allminus or res
57 | _ -> res in
58 let recursor =
59 V.combiner bind option_default
60 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
61 do_nothing do_nothing do_nothing do_nothing do_nothing
62 do_nothing do_nothing do_nothing do_nothing init do_nothing
63 do_nothing rule_elem do_nothing do_nothing do_nothing do_nothing in
64 recursor.V.combiner_fullType
65
66let decl r k e =
67 let e = k e in
68 match Ast.unwrap e with
69 Ast.Init(stg,ty,_,_,_,sem)
70 | Ast.UnInit(stg,ty,_,sem) ->
71 let stg_modif =
72 match stg with
73 Some stg -> mcode () stg
74 | None -> false in
75 let ft_modif = contains_modif ty in
76 let sem_modif = mcode () sem in
77 if not(stg_modif or ft_modif or sem_modif)
78 then {e with Ast.safe_for_multi_decls = true}
79 else e
80 | _ -> e
81let mcode e = e
82let donothing r k e = k e
83
84let process =
85 let fn = V.rebuilder
86 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
87 donothing donothing donothing donothing donothing
88 donothing donothing donothing donothing
89 donothing donothing decl donothing
90 donothing donothing donothing donothing in
91 List.map fn.V.rebuilder_top_level
92
93let safe_for_multi_decls rules =
94 List.map
95 (function (mv,r) ->
96 (mv,
97 match r with
98 Ast.ScriptRule _
99 | Ast.InitialScriptRule _ | Ast.FinalScriptRule _ -> r
100 | Ast.CocciRule (nm, rule_info, r, is_exp,ruletype) ->
101 Ast.CocciRule(nm, rule_info,process r,is_exp,ruletype)))
102 rules