Release coccinelle-0.1.8
[bpt/coccinelle.git] / engine / ctlcocci_integration.ml
CommitLineData
34e49164 1(*
faf9a90c 2* Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
34e49164
C
3* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
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
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
104 [(nodei, (p,[(s --> (Lib_engine.LabelVal labels))]))]
105 | Lib_engine.BCLabel s, _ ->
106 (match F.extract_bclabels node with
107 [] -> [] (* null for all nodes that are not break or continue *)
108 | labels ->
109 [(nodei, (p,[(s --> (Lib_engine.LabelVal labels))]))])
110 | Lib_engine.PrefixLabel s, _ ->
111 let labels = F.extract_labels node in
112 let prefixes = Common.inits labels +> Common.tail in
113 prefixes +> List.map (fun prefixlabels ->
114 (nodei, (p,[(s --> (Lib_engine.LabelVal prefixlabels))]))
115 )
116
117 | Lib_engine.Match (re), _unwrapnode ->
118 let substs =
485bce71 119 Pattern_c.match_re_node dropped_isos re node binding
34e49164
C
120 +> List.map (fun (re', subst) ->
121 Lib_engine.Match (re'), subst
122 )
123 in
124 substs +> List.map (fun (p', subst) ->
125 (nodei,
126 (p',
127 subst +> List.map (fun (s, meta) ->
128 s --> Lib_engine.NormalMetaVal meta
129 ))))
130
131 | Lib_engine.InLoop, F.InLoopNode -> [nodei, (p,[])]
132 | Lib_engine.TrueBranch , F.TrueNode -> [nodei, (p,[])]
133 | Lib_engine.FalseBranch, F.FalseNode -> [nodei, (p,[])]
134 | Lib_engine.After, F.AfterNode -> [nodei, (p,[])]
135 | Lib_engine.FallThrough, F.FallThroughNode -> [nodei,(p,[])]
136 | Lib_engine.FunHeader, F.FunHeader _ -> [nodei, (p,[])]
137 | Lib_engine.Top, F.TopNode -> [nodei, (p,[])]
138 | Lib_engine.Exit, F.Exit -> [nodei, (p,[])]
139 | Lib_engine.ErrorExit, F.ErrorExit -> [nodei, (p,[])]
b1b2de81 140 | Lib_engine.Goto, F.Goto(_,_,_) -> [nodei, (p,[])]
34e49164
C
141
142 | Lib_engine.InLoop , _ -> []
143 | Lib_engine.TrueBranch , _ -> []
144 | Lib_engine.FalseBranch, _ -> []
145 | Lib_engine.After, _ -> []
146 | Lib_engine.FallThrough, _ -> []
147 | Lib_engine.FunHeader, _ -> []
148 | Lib_engine.Top, _ -> []
149 | Lib_engine.Exit, _ -> []
150 | Lib_engine.ErrorExit, _ -> []
151 | Lib_engine.Goto, _ -> []
152
153 | Lib_engine.BindGood s, _ -> [(nodei, (p,[(s --> Lib_engine.GoodVal)]))]
154 | Lib_engine.BindBad s, _ -> [(nodei, (p,[(s --> Lib_engine.BadVal)]))]
155 | Lib_engine.FakeBrace, _ ->
156 if F.extract_is_fake node then [nodei, (p,[])] else []
157
158 | Lib_engine.Return, node ->
159 (match node with
160 (* todo? should match the Exit code ?
161 * todo: one day try also to match the special function
162 * such as panic();
163 *)
164 | F.Return _ -> [nodei, (p,[])]
165 | F.ReturnExpr _ -> [nodei, (p,[])]
166 | _ -> []
167 )
168 )
169 ) +> List.concat
170 in
171
172 show_or_not_nodes nodes';
173 nodes'
174 )
175
176(*****************************************************************************)
177(* Some fix flow, for CTL, for unparse *)
178(*****************************************************************************)
179(* could erase info on nodes, and edge, because they are not used by rene *)
180let (control_flow_for_ctl: F.cflow -> ('a, 'b) ograph_mutable) =
181 fun cflow -> cflow
182
183
184
185(* Just make the final node of the control flow loop over itself.
186 * It seems that one hypothesis of the SAT algorithm is that each node as at
187 * least a successor.
188 *
189 * update: do same for errorexit node.
190 *
191 * update: also erase the fake nodes (and adjust the edges accordingly),
192 * so that AX in CTL can now work.
193