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.
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.
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.
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/>.
18 * The authors reserve the right to distribute this or future versions of
19 * Coccinelle under other licenses.
27 module StringMap
= Map.Make
(String
)
29 exception Pycocciexception
31 (* ------------------------------------------------------------------- *)
32 (* The following definitions are from
33 http://patches.ubuntu.com/by-release/extracted/debian/c/coccinelle/0.1.5dbs-2/01-system-pycaml
34 as well as _pycocci_setargs *)
36 let _pycocci_none () =
37 let builtins = pyeval_getbuiltins
() in
38 pyobject_getitem
(builtins, pystring_fromstring
"None")
40 let _pycocci_true () =
41 let builtins = pyeval_getbuiltins
() in
42 pyobject_getitem
(builtins, pystring_fromstring
"True")
44 let _pycocci_false () =
45 let builtins = pyeval_getbuiltins
() in
46 pyobject_getitem
(builtins, pystring_fromstring
"False")
48 let _pycocci_tuple6 (a
,b
,c
,d
,e
,f
) =
49 pytuple_fromarray
([|a
; b
; c
; d
; e
; f
|])
51 (* ------------------------------------------------------------------- *)
53 let check_return_value v
=
54 if v
=*= (pynull
()) then
56 raise Pycocciexception
)
58 let check_int_return_value v
=
61 raise Pycocciexception
)
64 let initialised = ref false
66 let coccinelle_module = ref (_pycocci_none ())
67 let cocci_file_name = ref ""
69 (* dealing with python modules loaded *)
70 let module_map = ref (StringMap.add
"__main__" (_pycocci_none ()) StringMap.empty
)
72 let get_module module_name
=
73 StringMap.find module_name
(!module_map)
75 let is_module_loaded module_name
=
77 let _ = get_module module_name
in
79 with Not_found
-> false
81 let load_module module_name
=
82 if not
(is_module_loaded module_name
) then
83 let m = pyimport_importmodule module_name
in
85 (module_map := (StringMap.add module_name
m (!module_map));
87 else get_module module_name
88 (* end python module handling part *)
90 (* python interaction *)
92 let last_period = String.rindex fqn '
.'
in
93 let module_name = String.sub fqn
0 last_period in
94 let class_name = String.sub fqn
(last_period + 1) (String.length fqn
- last_period - 1) in
95 (module_name, class_name)
97 let pycocci_get_class_type fqn
=
98 let (module_name, class_name) = split_fqn fqn
in
99 let m = get_module module_name in
100 let attr = pyobject_getattrstring
(m, class_name) in
101 check_return_value attr;
104 let pycocci_instantiate_class fqn args
=
105 let class_type = pycocci_get_class_type fqn
in
106 let obj = pyobject_callobject
(class_type, args
) in
107 check_return_value obj;
110 (* end python interaction *)
112 let inc_match = ref true
114 let include_match v
=
115 let truth = pyobject_istrue
(pytuple_getitem
(v
, 1)) in
116 check_int_return_value truth;
117 inc_match := truth != 0;
120 let build_method (mname
, camlfunc
, args
) pymodule classx classdict
=
121 let cmx = pymethod_new
(pywrap_closure camlfunc
, args
, classx
) in
122 let v = pydict_setitemstring
(classdict
, mname
, cmx) in
123 check_int_return_value v;
126 let build_class cname parent methods pymodule
=
127 let cd = pydict_new
() in
128 check_return_value cd;
129 let cx = pyclass_new
(pytuple_fromsingle
(pycocci_get_class_type parent
), cd,
130 pystring_fromstring cname
) in
131 check_return_value cx;
132 List.iter
(function meth
-> build_method meth pymodule
cx cd) methods
;
133 let v = pydict_setitemstring
(pymodule_getdict pymodule
, cname
, cx) in
134 check_int_return_value v;
137 let the_environment = ref []
139 let has_environment_binding name
=
140 let a = pytuple_toarray name
in
141 let (rule
, name
) = (Array.get
a 1, Array.get
a 2) in
142 let orule = pystring_asstring rule
in
143 let oname = pystring_asstring name
in
144 let e = List.exists
(function (x
,y
) -> orule =$
= x
&& oname =$
= y
)
146 if e then _pycocci_true () else _pycocci_false ()
148 let pyoutputinstance = ref (_pycocci_none ())
149 let pyoutputdict = ref (_pycocci_none ())
151 let get_cocci_file args
=
152 pystring_fromstring
(!cocci_file_name)
154 (* initialisation routines *)
155 let _pycocci_setargs argv0
=
157 pysequence_list
(pytuple_fromsingle
(pystring_fromstring argv0
)) in
158 let sys_mod = load_module "sys" in
159 pyobject_setattrstring
(sys_mod, "argv", argv)
161 let pycocci_init () =
163 if not
!initialised then (
165 Unix.putenv
"PYTHONPATH"
166 (Printf.sprintf
"%s/coccinelle" (Unix.getenv
"HOME"));
167 let _ = if not
(py_isinitialized
() != 0) then
168 (if !Flag.show_misc
then Common.pr2
"Initializing python\n%!";
172 let argv0 = Printf.sprintf
"%s%sspatch" (Sys.getcwd
()) (match Sys.os_type
with "Win32" -> "\\" | _ -> "/") in
173 let _ = _pycocci_setargs argv0 in
175 coccinelle_module := (pymodule_new
"coccinelle");
176 module_map := StringMap.add
"coccinelle" !coccinelle_module !module_map;
177 let _ = load_module "coccilib.elems" in
178 let _ = load_module "coccilib.output" in
180 let module_dictionary = pyimport_getmoduledict
() in
181 coccinelle_module := pymodule_new
"coccinelle";
182 let mx = !coccinelle_module in
183 let (cd, cx) = build_class "Cocci" (!Flag.pyoutput
)
184 [("include_match", include_match, (pynull
()));
185 ("has_env_binding", has_environment_binding, (pynull
()))] mx in
186 pyoutputinstance := cx;
188 let v1 = pydict_setitemstring
(module_dictionary, "coccinelle", mx) in
189 check_int_return_value v1;
190 let mypystring = pystring_fromstring
!cocci_file_name in
191 let v2 = pydict_setitemstring
(cd, "cocci_file", mypystring) in
192 check_int_return_value v2;
196 (*let _ = pycocci_init ()*)
197 (* end initialisation routines *)
199 let added_variables = ref []
201 let build_classes env
=
202 let _ = pycocci_init () in
204 the_environment := env
;
205 let mx = !coccinelle_module in
206 let dict = pymodule_getdict
mx in
209 "include_match" | "has_env_binding" -> ()
211 let v = pydict_delitemstring
(dict,name
) in
212 check_int_return_value v)
214 added_variables := [];
217 let build_variable name
value =
218 let mx = !coccinelle_module in
219 added_variables := name
:: !added_variables;
220 check_int_return_value
221 (pydict_setitemstring
(pymodule_getdict
mx, name
, value))
223 let contains_binding e (_,(r
,m)) =
225 let _ = List.find
(function ((re
, rm
), _) -> r
=$
= re
&& m =$
= rm
) e in
227 with Not_found
-> false
229 let construct_variables mv
e =
230 let find_binding (r
,m) =
232 let elem = List.find
(function ((re
,rm
),_) -> r
=$
= re
&& m =$
= rm
) e in
234 with Not_found
-> None
237 let instantiate_Expression(x
) =
238 let str = pystring_fromstring
(Pycocci_aux.exprrep x
) in
239 pycocci_instantiate_class "coccilib.elems.Expression"
240 (pytuple_fromsingle
(str))
243 let instantiate_Identifier(x
) =
244 let str = pystring_fromstring x
in
245 pycocci_instantiate_class "coccilib.elems.Identifier"
246 (pytuple_fromsingle
(str))
249 List.iter
(function (py
,(r
,m)) ->
250 match find_binding (r
,m) with
252 | Some
(_, Ast_c.MetaExprVal expr
) ->
253 let expr_repr = instantiate_Expression(expr
) in
254 let _ = build_variable py
expr_repr in
256 | Some
(_, Ast_c.MetaIdVal id
) ->
257 let id_repr = instantiate_Identifier(id
) in
258 let _ = build_variable py
id_repr in
260 | Some
(_, Ast_c.MetaPosValList l
) ->
263 (function (fname
,current_element
,(line
,col
),(line_end
,col_end
)) ->
264 pycocci_instantiate_class "coccilib.elems.Location"
266 (pystring_fromstring fname
,pystring_fromstring current_element
,
267 pystring_fromstring
(Printf.sprintf
"%d" line
),
268 pystring_fromstring
(Printf.sprintf
"%d" col
),
269 pystring_fromstring
(Printf.sprintf
"%d" line_end
),
270 pystring_fromstring
(Printf.sprintf
"%d" col_end
)))) l
in
271 let pylocs = pytuple_fromarray
(Array.of_list
locs) in
272 let _ = build_variable py
pylocs in
274 | Some
(_,binding
) ->
275 let _ = build_variable py
(pystring_fromstring
(Pycocci_aux.stringrep binding
))
281 let set_coccifile cocci_file
=
282 cocci_file_name := cocci_file
;
286 let pyrun_simplestring s
=
287 Pycaml.pyrun_simplestring s
289 let py_isinitialized () =
290 Pycaml.py_isinitialized ()
294 Pycaml.py_finalize ()