Release coccinelle-0.2.0rc1
[bpt/coccinelle.git] / python / yes_pycocci.ml
CommitLineData
34e49164
C
1open Ast_c
2open Common
3open Pycaml
4open Pycocci_aux
5module StringMap = Map.Make (String)
6
7exception Pycocciexception
8
7f004419
C
9let python_support = true
10
fc1ad971
C
11(* ------------------------------------------------------------------- *)
12(* The following definitions are from
13http://patches.ubuntu.com/by-release/extracted/debian/c/coccinelle/0.1.5dbs-2/01-system-pycaml
14as well as _pycocci_setargs *)
15
16let _pycocci_none () =
17 let builtins = pyeval_getbuiltins () in
18 pyobject_getitem (builtins, pystring_fromstring "None")
19
20let _pycocci_true () =
21 let builtins = pyeval_getbuiltins () in
22 pyobject_getitem (builtins, pystring_fromstring "True")
23
24let _pycocci_false () =
25 let builtins = pyeval_getbuiltins () in
26 pyobject_getitem (builtins, pystring_fromstring "False")
27
28let _pycocci_tuple6 (a,b,c,d,e,f) =
29 pytuple_fromarray ([|a; b; c; d; e; f|])
30
31(* ------------------------------------------------------------------- *)
32
34e49164 33let check_return_value v =
b1b2de81 34 if v =*= (pynull ()) then
34e49164
C
35 (pyerr_print ();
36 raise Pycocciexception)
37 else ()
38let check_int_return_value v =
b1b2de81 39 if v =|= -1 then
34e49164
C
40 (pyerr_print ();
41 raise Pycocciexception)
42 else ()
43
44let initialised = ref false
45
fc1ad971 46let coccinelle_module = ref (_pycocci_none ())
34e49164
C
47let cocci_file_name = ref ""
48
49(* dealing with python modules loaded *)
fc1ad971 50let module_map = ref (StringMap.add "__main__" (_pycocci_none ()) StringMap.empty)
34e49164
C
51
52let get_module module_name =
53 StringMap.find module_name (!module_map)
54
55let is_module_loaded module_name =
56 try
57 let _ = get_module module_name in
58 true
59 with Not_found -> false
60
61let load_module module_name =
62 if not (is_module_loaded module_name) then
63 let m = pyimport_importmodule module_name in
64 check_return_value m;
65 (module_map := (StringMap.add module_name m (!module_map));
66 m)
67 else get_module module_name
68(* end python module handling part *)
69
34e49164
C
70(* python interaction *)
71let split_fqn fqn =
72 let last_period = String.rindex fqn '.' in
73 let module_name = String.sub fqn 0 last_period in
74 let class_name = String.sub fqn (last_period + 1) (String.length fqn - last_period - 1) in
75 (module_name, class_name)
76
77let pycocci_get_class_type fqn =
78 let (module_name, class_name) = split_fqn fqn in
79 let m = get_module module_name in
80 let attr = pyobject_getattrstring(m, class_name) in
81 check_return_value attr;
82 attr
83
84let pycocci_instantiate_class fqn args =
85 let class_type = pycocci_get_class_type fqn in
86 let obj = pyobject_callobject(class_type, args) in
87 check_return_value obj;
88 obj
89
90(* end python interaction *)
91
92let inc_match = ref true
93
94let include_match v =
95 let truth = pyobject_istrue (pytuple_getitem (v, 1)) in
96 check_int_return_value truth;
97 inc_match := truth != 0;
fc1ad971 98 _pycocci_none ()
34e49164
C
99
100let build_method (mname, camlfunc, args) pymodule classx classdict =
101 let cmx = pymethod_new(pywrap_closure camlfunc, args, classx) in
102 let v = pydict_setitemstring(classdict, mname, cmx) in
103 check_int_return_value v;
104 ()
105
106let build_class cname parent methods pymodule =
107 let cd = pydict_new() in
108 check_return_value cd;
fc1ad971
C
109 let cx = pyclass_new(pytuple_fromsingle (pycocci_get_class_type parent), cd,
110 pystring_fromstring cname) in
34e49164
C
111 check_return_value cx;
112 List.iter (function meth -> build_method meth pymodule cx cd) methods;
113 let v = pydict_setitemstring(pymodule_getdict pymodule, cname, cx) in
114 check_int_return_value v;
115 (cd, cx)
116
fc1ad971
C
117let the_environment = ref []
118
119let has_environment_binding name =
34e49164
C
120 let a = pytuple_toarray name in
121 let (rule, name) = (Array.get a 1, Array.get a 2) in
122 let orule = pystring_asstring rule in
123 let oname = pystring_asstring name in
fc1ad971
C
124 let e = List.exists (function (x,y) -> orule =$= x && oname =$= y)
125 !the_environment in
126 if e then _pycocci_true () else _pycocci_false ()
34e49164 127
fc1ad971
C
128let pyoutputinstance = ref (_pycocci_none ())
129let pyoutputdict = ref (_pycocci_none ())
34e49164
C
130
131let get_cocci_file args =
fc1ad971
C
132 pystring_fromstring (!cocci_file_name)
133
134(* initialisation routines *)
135let _pycocci_setargs argv0 =
136 let argv =
137 pysequence_list (pytuple_fromsingle (pystring_fromstring argv0)) in
138 let sys_mod = load_module "sys" in
139 pyobject_setattrstring (sys_mod, "argv", argv)
140
141let pycocci_init () =
142 (* initialize *)
143 if not !initialised then (
144 initialised := true;
145 Unix.putenv "PYTHONPATH"
146 (Printf.sprintf "%s/coccinelle" (Unix.getenv "HOME"));
147 let _ = if not (py_isinitialized () != 0) then
148 (if !Flag.show_misc then Common.pr2 "Initializing python\n%!";
149 py_initialize()) in
150
151 (* set argv *)
152 let argv0 = Printf.sprintf "%s%sspatch" (Sys.getcwd ()) (match Sys.os_type with "Win32" -> "\\" | _ -> "/") in
153 let _ = _pycocci_setargs argv0 in
154
155 coccinelle_module := (pymodule_new "coccinelle");
156 module_map := StringMap.add "coccinelle" !coccinelle_module !module_map;
157 let _ = load_module "coccilib.elems" in
158 let _ = load_module "coccilib.output" in
159
160 let module_dictionary = pyimport_getmoduledict() in
161 coccinelle_module := pymodule_new "coccinelle";
162 let mx = !coccinelle_module in
163 let (cd, cx) = build_class "Cocci" (!Flag.pyoutput)
164 [("include_match", include_match, (pynull()));
165 ("has_env_binding", has_environment_binding, (pynull()))] mx in
166 pyoutputinstance := cx;
167 pyoutputdict := cd;
168 let v1 = pydict_setitemstring(module_dictionary, "coccinelle", mx) in
169 check_int_return_value v1;
170 let mypystring = pystring_fromstring !cocci_file_name in
171 let v2 = pydict_setitemstring(cd, "cocci_file", mypystring) in
172 check_int_return_value v2;
173 ()) else
174 ()
175
176(*let _ = pycocci_init ()*)
177(* end initialisation routines *)
178
179let added_variables = ref []
34e49164
C
180
181let build_classes env =
fc1ad971
C
182 let _ = pycocci_init () in
183 inc_match := true;
184 the_environment := env;
185 let mx = !coccinelle_module in
186 let dict = pymodule_getdict mx in
187 List.iter
188 (function
189 "include_match" | "has_env_binding" -> ()
190 | name ->
191 let v = pydict_delitemstring(dict,name) in
192 check_int_return_value v)
193 !added_variables;
194 added_variables := [];
195 ()
34e49164
C
196
197let build_variable name value =
198 let mx = !coccinelle_module in
fc1ad971
C
199 added_variables := name :: !added_variables;
200 check_int_return_value
201 (pydict_setitemstring(pymodule_getdict mx, name, value))
34e49164
C
202
203let contains_binding e (_,(r,m)) =
204 try
fc1ad971
C
205 let _ = List.find (function ((re, rm), _) -> r =$= re && m =$= rm) e in
206 true
34e49164
C
207 with Not_found -> false
208
209let construct_variables mv e =
210 let find_binding (r,m) =
211 try
b1b2de81 212 let elem = List.find (function ((re,rm),_) -> r =$= re && m =$= rm) e in
34e49164
C
213 Some elem
214 with Not_found -> None
215 in
216
217 let instantiate_Expression(x) =
218 let str = pystring_fromstring (Pycocci_aux.exprrep x) in
fc1ad971
C
219 pycocci_instantiate_class "coccilib.elems.Expression"
220 (pytuple_fromsingle (str))
34e49164
C
221 in
222
223 let instantiate_Identifier(x) =
224 let str = pystring_fromstring x in
fc1ad971
C
225 pycocci_instantiate_class "coccilib.elems.Identifier"
226 (pytuple_fromsingle (str))
34e49164
C
227 in
228
229 List.iter (function (py,(r,m)) ->
230 match find_binding (r,m) with
231 None -> ()
0708f913 232 | Some (_, Ast_c.MetaExprVal expr) ->
34e49164
C
233 let expr_repr = instantiate_Expression(expr) in
234 let _ = build_variable py expr_repr in
235 ()
236 | Some (_, Ast_c.MetaIdVal id) ->
237 let id_repr = instantiate_Identifier(id) in
238 let _ = build_variable py id_repr in
239 ()
240 | Some (_, Ast_c.MetaPosValList l) ->
485bce71
C
241 let locs =
242 List.map
243 (function (fname,current_element,(line,col),(line_end,col_end)) ->
fc1ad971
C
244 pycocci_instantiate_class "coccilib.elems.Location"
245 (_pycocci_tuple6
485bce71 246 (pystring_fromstring fname,pystring_fromstring current_element,
34e49164
C
247 pystring_fromstring (Printf.sprintf "%d" line),
248 pystring_fromstring (Printf.sprintf "%d" col),
249 pystring_fromstring (Printf.sprintf "%d" line_end),
250 pystring_fromstring (Printf.sprintf "%d" col_end)))) l in
251 let pylocs = pytuple_fromarray (Array.of_list locs) in
252 let _ = build_variable py pylocs in
253 ()
254 | Some (_,binding) ->
255 let _ = build_variable py (pystring_fromstring (Pycocci_aux.stringrep binding))
256 in ()
257 ) mv;
258
259 ()
260
261let set_coccifile cocci_file =
262 cocci_file_name := cocci_file;
263 ()
264
265
266let pyrun_simplestring s =
267 Pycaml.pyrun_simplestring s
268
269let py_isinitialized () =
270 Pycaml.py_isinitialized ()
271
272
273let py_finalize () =
274 Pycaml.py_finalize ()