Release coccinelle-0.2.4
[bpt/coccinelle.git] / engine / ctlcocci_integration.ml
CommitLineData
9bc82bae
C
1(*
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
7 *
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
11 *
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 *)
23
24
c491d8ee
C
25(*
26 * Copyright 2010, INRIA, University of Copenhagen
27 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
28 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
29 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
30 * This file is part of Coccinelle.
31 *
32 * Coccinelle is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, according to version 2 of the License.
35 *
36 * Coccinelle is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License
42 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
43 *
44 * The authors reserve the right to distribute this or future versions of
45 * Coccinelle under other licenses.
46 *)
47
48
34e49164
C
49open Common
50
51open Ograph_extended
52
53module F = Control_flow_c
54
55(*****************************************************************************)
56(* Debugging functions *)
57(*****************************************************************************)
ae4735db
C
58let show_or_not_predicate pred =
59 if !Flag_matcher.debug_engine then begin
60 indent_do (fun () ->
61 adjust_pp_with_indent_and_header "labeling: pred = " (fun () ->
34e49164
C
62 Pretty_print_engine.pp_predicate pred;
63 );
64 )
65 end
66
67let show_or_not_nodes nodes =
ae4735db
C
68 if !Flag_matcher.debug_engine then begin
69 indent_do (fun () ->
70 adjust_pp_with_indent_and_header "labeling: result = " (fun () ->
71 Common.pp_do_in_box (fun () ->
34e49164 72 pp "{";
ae4735db 73 Common.print_between
34e49164 74 (fun () -> pp ";"; Format.print_cut())
ae4735db 75 (fun (nodei, (_predTODO, subst)) ->
34e49164 76 Format.print_int nodei;
ae4735db 77 Common.pp_do_in_box (fun () ->
34e49164
C
78 Pretty_print_engine.pp_binding2_ctlsubst subst
79 )
80 ) nodes;
81 pp "}";
82 );
83 )
84 )
85 end
86
87let show_isos rule_elem =
88 match Ast_cocci.get_isos rule_elem with
89 [] -> ()
90 | isos ->
91 let line = Ast_cocci.get_line rule_elem in
92 Printf.printf "rule elem: ";
93 Pretty_print_cocci.rule_elem "" rule_elem;
94 Format.print_newline();
95 List.iter
96 (function (nm,x) ->
97 Printf.printf " iso: %s(%d): " nm line;
98 Pretty_print_cocci.pp_print_anything x;
99 Format.print_newline())
100 isos
101
102(*****************************************************************************)
103(* Labeling function *)
104(*****************************************************************************)
105let (-->) x v = Ast_ctl.Subst (x,v);;
106
107(* Take list of predicate and for each predicate returns where in the
ae4735db 108 * control flow it matches, and the set of subsitutions for this match.
34e49164
C
109 *)
110let (labels_for_ctl: string list (* dropped isos *) ->
ae4735db 111 (nodei * F.node) list -> Lib_engine.metavars_binding ->
34e49164
C
112 Lib_engine.label_ctlcocci) =
113 fun dropped_isos nodes binding ->
114
ae4735db 115 (fun p ->
34e49164
C
116 show_or_not_predicate p;
117
ae4735db 118 let nodes' = nodes +> List.map (fun (nodei, node) ->
34e49164
C
119 (* todo? put part of this code in pattern ? *)
120 (match p, F.unwrap node with
ae4735db 121 | Lib_engine.Paren s, (F.SeqStart (_, bracelevel, _)) ->
34e49164
C
122 let make_var x = ("",i_to_s x) in
123 [(nodei, (p,[(s --> (Lib_engine.ParenVal (make_var bracelevel)))]))]
ae4735db 124 | Lib_engine.Paren s, (F.SeqEnd (bracelevel, _)) ->
34e49164
C
125 let make_var x = ("",i_to_s x) in
126 [(nodei, (p,[(s --> (Lib_engine.ParenVal (make_var bracelevel)))]))]
127 | Lib_engine.Paren _, _ -> []
ae4735db 128 | Lib_engine.Label s, _ ->
34e49164 129 let labels = F.extract_labels node in
7f004419
C
130 [(nodei,
131 (p,[(s --> (Lib_engine.LabelVal (Lib_engine.Absolute labels)))]))]
ae4735db 132 | Lib_engine.BCLabel s, _ ->
34e49164
C
133 (match F.extract_bclabels node with
134 [] -> [] (* null for all nodes that are not break or continue *)
135 | labels ->
7f004419
C
136 [(nodei,
137 (p,[(s -->
138 (Lib_engine.LabelVal (Lib_engine.Absolute labels)))]))])
ae4735db 139 | Lib_engine.PrefixLabel s, _ ->
34e49164 140 let labels = F.extract_labels node in
7f004419
C
141 [(nodei,
142 (p,[(s --> (Lib_engine.LabelVal (Lib_engine.Prefix labels)))]))]
34e49164 143
ae4735db
C
144 | Lib_engine.Match (re), _unwrapnode ->
145 let substs =
485bce71 146 Pattern_c.match_re_node dropped_isos re node binding
ae4735db 147 +> List.map (fun (re', subst) ->
34e49164
C
148 Lib_engine.Match (re'), subst
149 )
150 in
ae4735db
C
151 substs +> List.map (fun (p', subst) ->
152 (nodei,
153 (p',
154 subst +> List.map (fun (s, meta) ->
34e49164
C
155 s --> Lib_engine.NormalMetaVal meta
156 ))))
157
158 | Lib_engine.InLoop, F.InLoopNode -> [nodei, (p,[])]
159 | Lib_engine.TrueBranch , F.TrueNode -> [nodei, (p,[])]
160 | Lib_engine.FalseBranch, F.FalseNode -> [nodei, (p,[])]
161 | Lib_engine.After, F.AfterNode -> [nodei, (p,[])]
162 | Lib_engine.FallThrough, F.FallThroughNode -> [nodei,(p,[])]
951c7801 163 | Lib_engine.LoopFallThrough, F.LoopFallThroughNode -> [nodei,(p,[])]
34e49164
C
164 | Lib_engine.FunHeader, F.FunHeader _ -> [nodei, (p,[])]
165 | Lib_engine.Top, F.TopNode -> [nodei, (p,[])]
166 | Lib_engine.Exit, F.Exit -> [nodei, (p,[])]
167 | Lib_engine.ErrorExit, F.ErrorExit -> [nodei, (p,[])]
b1b2de81 168 | Lib_engine.Goto, F.Goto(_,_,_) -> [nodei, (p,[])]
34e49164
C
169
170 | Lib_engine.InLoop , _ -> []
171 | Lib_engine.TrueBranch , _ -> []
172 | Lib_engine.FalseBranch, _ -> []
173 | Lib_engine.After, _ -> []
174 | Lib_engine.FallThrough, _ -> []
951c7801 175 | Lib_engine.LoopFallThrough, _ -> []
34e49164
C
176 | Lib_engine.FunHeader, _ -> []
177 | Lib_engine.Top, _ -> []
178 | Lib_engine.Exit, _ -> []
179 | Lib_engine.ErrorExit, _ -> []
180 | Lib_engine.Goto, _ -> []
181
182 | Lib_engine.BindGood s, _ -> [(nodei, (p,[(s --> Lib_engine.GoodVal)]))]
183 | Lib_engine.BindBad s, _ -> [(nodei, (p,[(s --> Lib_engine.BadVal)]))]
184 | Lib_engine.FakeBrace, _ ->
185 if F.extract_is_fake node then [nodei, (p,[])] else []
186
ae4735db 187 | Lib_engine.Return, node ->
34e49164 188 (match node with
ae4735db 189 (* todo? should match the Exit code ?
34e49164 190 * todo: one day try also to match the special function
ae4735db 191 * such as panic();
34e49164
C
192 *)
193 | F.Return _ -> [nodei, (p,[])]
194 | F.ReturnExpr _ -> [nodei, (p,[])]
195 | _ -> []
196 )
197 )
198 ) +> List.concat
199 in
200
201 show_or_not_nodes nodes';
202 nodes'
ae4735db 203 )
34e49164
C
204
205(*****************************************************************************)
206(* Some fix flow, for CTL, for unparse *)
207(*****************************************************************************)
208(* could erase info on nodes, and edge, because they are not used by rene *)
ae4735db 209let (control_flow_for_ctl: F.cflow -> ('a, 'b) ograph_mutable) =
34e49164
C
210 fun cflow -> cflow
211
212
213
ae4735db 214(* Just make the final node of the control flow loop over itself.
34e49164
C
215 * It seems that one hypothesis of the SAT algorithm is that each node as at
216 * least a successor.
ae4735db 217 *
34e49164 218 * update: do same for errorexit node.
ae4735db
C
219 *
220 * update: also erase the fake nodes (and adjust the edges accordingly),
34e49164
C
221 * so that AX in CTL can now work.
222