5 module StringMap
= Map.Make
(String
)
7 exception Pycocciexception
9 let python_support = true
11 (* ------------------------------------------------------------------- *)
12 (* The following definitions are from
13 http://patches.ubuntu.com/by-release/extracted/debian/c/coccinelle/0.1.5dbs-2/01-system-pycaml
14 as well as _pycocci_setargs *)
16 let _pycocci_none () =
17 let builtins = pyeval_getbuiltins
() in
18 pyobject_getitem
(builtins, pystring_fromstring
"None")
20 let _pycocci_true () =
21 let builtins = pyeval_getbuiltins
() in
22 pyobject_getitem
(builtins, pystring_fromstring
"True")
24 let _pycocci_false () =
25 let builtins = pyeval_getbuiltins
() in
26 pyobject_getitem
(builtins, pystring_fromstring
"False")
28 let _pycocci_tuple6 (a
,b
,c
,d
,e
,f
) =
29 pytuple_fromarray
([|a
; b
; c
; d
; e
; f
|])
31 (* ------------------------------------------------------------------- *)
33 let check_return_value v
=
34 if v
=*= (pynull
()) then
36 raise Pycocciexception
)
38 let check_int_return_value v
=
41 raise Pycocciexception
)
44 let initialised = ref false
46 let coccinelle_module = ref (_pycocci_none ())
47 let cocci_file_name = ref ""
49 (* dealing with python modules loaded *)
50 let module_map = ref (StringMap.add
"__main__" (_pycocci_none ()) StringMap.empty
)
52 let get_module module_name
=
53 StringMap.find module_name
(!module_map)
55 let is_module_loaded module_name
=
57 let _ = get_module module_name
in
59 with Not_found
-> false
61 let load_module module_name
=
62 if not
(is_module_loaded module_name
) then
63 let m = pyimport_importmodule module_name
in
65 (module_map := (StringMap.add module_name
m (!module_map));
67 else get_module module_name
68 (* end python module handling part *)
70 (* python interaction *)
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)
77 let 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;
84 let 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;
90 (* end python interaction *)
92 let inc_match = ref true
95 let truth = pyobject_istrue
(pytuple_getitem
(v
, 1)) in
96 check_int_return_value truth;
97 inc_match := truth != 0;
100 let 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;
106 let build_class cname parent methods pymodule
=
107 let cd = pydict_new
() in
108 check_return_value cd;
109 let cx = pyclass_new
(pytuple_fromsingle
(pycocci_get_class_type parent
), cd,
110 pystring_fromstring cname
) in
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;
117 let the_environment = ref []
119 let has_environment_binding name
=
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
124 let e = List.exists
(function (x
,y
) -> orule =$
= x
&& oname =$
= y
)
126 if e then _pycocci_true () else _pycocci_false ()
128 let pyoutputinstance = ref (_pycocci_none ())
129 let pyoutputdict = ref (_pycocci_none ())
131 let get_cocci_file args
=
132 pystring_fromstring
(!cocci_file_name)
134 (* initialisation routines *)
135 let _pycocci_setargs argv0
=
137 pysequence_list
(pytuple_fromsingle
(pystring_fromstring argv0
)) in
138 let sys_mod = load_module "sys" in
139 pyobject_setattrstring
(sys_mod, "argv", argv)
141 let pycocci_init () =
143 if not
!initialised then (
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%!";
152 let argv0 = Printf.sprintf
"%s%sspatch" (Sys.getcwd
()) (match Sys.os_type
with "Win32" -> "\\" | _ -> "/") in
153 let _ = _pycocci_setargs argv0 in
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
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;
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;
176 (*let _ = pycocci_init ()*)
177 (* end initialisation routines *)
179 let added_variables = ref []
181 let build_classes env
=
182 let _ = pycocci_init () in
184 the_environment := env
;
185 let mx = !coccinelle_module in
186 let dict = pymodule_getdict
mx in
189 "include_match" | "has_env_binding" -> ()
191 let v = pydict_delitemstring
(dict,name
) in
192 check_int_return_value v)
194 added_variables := [];
197 let build_variable name
value =
198 let mx = !coccinelle_module in
199 added_variables := name
:: !added_variables;
200 check_int_return_value
201 (pydict_setitemstring
(pymodule_getdict
mx, name
, value))
203 let contains_binding e (_,(r
,m)) =
205 let _ = List.find
(function ((re
, rm
), _) -> r
=$
= re
&& m =$
= rm
) e in
207 with Not_found
-> false
209 let construct_variables mv
e =
210 let find_binding (r
,m) =
212 let elem = List.find
(function ((re
,rm
),_) -> r
=$
= re
&& m =$
= rm
) e in
214 with Not_found
-> None
217 let instantiate_Expression(x
) =
218 let str = pystring_fromstring
(Pycocci_aux.exprrep x
) in
219 pycocci_instantiate_class "coccilib.elems.Expression"
220 (pytuple_fromsingle
(str))
223 let instantiate_Identifier(x
) =
224 let str = pystring_fromstring x
in
225 pycocci_instantiate_class "coccilib.elems.Identifier"
226 (pytuple_fromsingle
(str))
229 List.iter
(function (py
,(r
,m)) ->
230 match find_binding (r
,m) with
232 | Some
(_, Ast_c.MetaExprVal expr
) ->
233 let expr_repr = instantiate_Expression(expr
) in
234 let _ = build_variable py
expr_repr in
236 | Some
(_, Ast_c.MetaIdVal id
) ->
237 let id_repr = instantiate_Identifier(id
) in
238 let _ = build_variable py
id_repr in
240 | Some
(_, Ast_c.MetaPosValList l
) ->
243 (function (fname
,current_element
,(line
,col
),(line_end
,col_end
)) ->
244 pycocci_instantiate_class "coccilib.elems.Location"
246 (pystring_fromstring fname
,pystring_fromstring current_element
,
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
254 | Some
(_,binding
) ->
255 let _ = build_variable py
(pystring_fromstring
(Pycocci_aux.stringrep binding
))
261 let set_coccifile cocci_file
=
262 cocci_file_name := cocci_file
;
266 let pyrun_simplestring s
=
267 Pycaml.pyrun_simplestring s
269 let py_isinitialized () =
270 Pycaml.py_isinitialized ()
274 Pycaml.py_finalize ()