Commit | Line | Data |
---|---|---|
0708f913 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 | |
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 | ||
23 | open Common | |
24 | ||
25 | (*****************************************************************************) | |
26 | (* Types *) | |
27 | (*****************************************************************************) | |
28 | ||
29 | type protocol_match = | |
30 | | MatchPos of Ograph_extended.nodei | |
31 | | MatchNeg of Ograph_extended.nodei | |
32 | | NoMatch | |
33 | (* could generate exn instead, but in many cases as for my acomment gui | |
34 | * I still want to print the match for the other elements, so one failure | |
35 | * should not stop everything | |
36 | *) | |
37 | | MatchProblem of string | |
38 | ||
39 | ||
40 | (*****************************************************************************) | |
41 | (* Helpers *) | |
42 | (*****************************************************************************) | |
43 | ||
44 | (*****************************************************************************) | |
45 | (* Specific finder wrappers *) | |
46 | (*****************************************************************************) | |
47 | let (find_nodes_satisfying_pattern: | |
48 | Control_flow_c.cflow -> Ast_cocci.rule_elem -> Ograph_extended.nodei list)= | |
49 | fun flow pattern -> | |
50 | ||
51 | let nodes = flow#nodes in | |
52 | let nodes = nodes#tolist in | |
53 | nodes +> Common.map_filter (fun (nodei, node) -> | |
54 | let res = | |
55 | Pattern_c.match_re_node [] (* dropped isos *) | |
56 | pattern node | |
57 | [] | |
58 | in | |
59 | if List.length res > 0 | |
60 | then Some nodei | |
61 | else None | |
62 | ) | |
63 | ||
64 | ||
65 | let (find_nodes_containing_expr: | |
66 | Control_flow_c.cflow -> Ast_c.expression -> Ograph_extended.nodei list)= | |
67 | fun flow expr -> | |
68 | ||
69 | let expr = Lib_parsing_c.real_al_expr expr in | |
70 | ||
71 | let nodes = flow#nodes in | |
72 | let nodes = nodes#tolist in | |
73 | nodes +> Common.map_filter (fun (nodei, node) -> | |
74 | let node = Lib_parsing_c.real_al_node node in | |
75 | ||
76 | let found = ref false in | |
77 | ||
78 | Visitor_c.vk_node { Visitor_c.default_visitor_c with | |
79 | Visitor_c.kexpr = (fun (k, bigf) e2 -> | |
80 | if e2 =*= expr | |
81 | then found := true | |
82 | else k e2 | |
83 | ); | |
84 | } node; | |
85 | ||
86 | if !found | |
87 | then Some nodei | |
88 | else None | |
89 | ) | |
90 | ||
91 | ||
92 | ||
93 | (*****************************************************************************) | |
94 | (* Main entries *) | |
95 | (*****************************************************************************) | |
96 | ||
97 | (* | |
98 | * | |
99 | * todo: Check for all path upwards ? | |
100 | *) | |
101 | ||
102 | let (find_nodes_upward_satisfying_protocol: | |
103 | Ograph_extended.nodei -> Control_flow_c.cflow -> | |
104 | Ast_cocci.rule_elem * Ast_cocci.rule_elem -> | |
105 | protocol_match | |
106 | ) = | |
107 | fun nodei flow (pattern1, pattern2) -> | |
108 | ||
109 | let already_done = ref [nodei] in | |
110 | let found = ref [] in | |
111 | ||
112 | let rec aux nodei = | |
113 | let pred = | |
114 | List.map fst ((flow#predecessors nodei)#tolist) | |
115 | in | |
116 | pred +> List.iter (fun nodei2 -> | |
117 | if List.mem nodei2 !already_done | |
118 | then () | |
119 | else begin | |
120 | Common.push2 nodei2 already_done; | |
121 | ||
122 | let node2 = flow#nodes#assoc nodei2 in | |
123 | ||
124 | let res1 = | |
125 | Pattern_c.match_re_node [] | |
126 | pattern1 node2 | |
127 | [] | |
128 | in | |
129 | let res2 = | |
130 | Pattern_c.match_re_node [] | |
131 | pattern2 node2 | |
132 | [] | |
133 | in | |
134 | match List.length res1 > 0, List.length res2 > 0 with | |
135 | | true, false -> | |
136 | Common.push2 (MatchPos nodei2) found | |
137 | | false, true -> | |
138 | Common.push2 (MatchNeg nodei2) found | |
139 | | true, true -> | |
140 | failwith "wierd, node match both rule_elem" | |
141 | | false, false -> | |
142 | aux nodei2 | |
143 | end | |
144 | ); | |
145 | in | |
146 | aux nodei; | |
147 | (match !found with | |
148 | | [] -> NoMatch | |
149 | | [x] -> x | |
150 | | x::y::ys -> | |
151 | failwith "multiple found"; | |
152 | ) | |
153 | ||
154 | ||
155 | ||
156 |