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