2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
26 * Copyright 2010, INRIA, University of Copenhagen
27 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
28 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
29 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
30 * This file is part of Coccinelle.
32 * Coccinelle is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, according to version 2 of the License.
36 * Coccinelle is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
41 * You should have received a copy of the GNU General Public License
42 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
44 * The authors reserve the right to distribute this or future versions of
45 * Coccinelle under other licenses.
50 * Copyright 2010, INRIA, University of Copenhagen
51 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
52 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
53 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
54 * This file is part of Coccinelle.
56 * Coccinelle is free software: you can redistribute it and/or modify
57 * it under the terms of the GNU General Public License as published by
58 * the Free Software Foundation, according to version 2 of the License.
60 * Coccinelle is distributed in the hope that it will be useful,
61 * but WITHOUT ANY WARRANTY; without even the implied warranty of
62 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 * GNU General Public License for more details.
65 * You should have received a copy of the GNU General Public License
66 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
68 * The authors reserve the right to distribute this or future versions of
69 * Coccinelle under other licenses.
77 module StringMap
= Map.Make
(String
)
79 exception Pycocciexception
81 let python_support = true
83 (* ------------------------------------------------------------------- *)
84 (* The following definitions are from
85 http://patches.ubuntu.com/by-release/extracted/debian/c/coccinelle/0.1.5dbs-2/01-system-pycaml
86 as well as _pycocci_setargs *)
88 let _pycocci_none () =
89 let builtins = pyeval_getbuiltins
() in
90 pyobject_getitem
(builtins, pystring_fromstring
"None")
92 let _pycocci_true () =
93 let builtins = pyeval_getbuiltins
() in
94 pyobject_getitem
(builtins, pystring_fromstring
"True")
96 let _pycocci_false () =
97 let builtins = pyeval_getbuiltins
() in
98 pyobject_getitem
(builtins, pystring_fromstring
"False")
100 let _pycocci_tuple6 (a
,b
,c
,d
,e
,f
) =
101 pytuple_fromarray
([|a
; b
; c
; d
; e
; f
|])
103 (* ------------------------------------------------------------------- *)
105 let check_return_value v
=
106 if v
=*= (pynull
()) then
108 raise Pycocciexception
)
110 let check_int_return_value v
=
113 raise Pycocciexception
)
116 let initialised = ref false
118 let coccinelle_module = ref (_pycocci_none ())
119 let cocci_file_name = ref ""
121 (* dealing with python modules loaded *)
122 let module_map = ref (StringMap.add
"__main__" (_pycocci_none ()) StringMap.empty
)
124 let get_module module_name
=
125 StringMap.find module_name
(!module_map)
127 let is_module_loaded module_name
=
129 let _ = get_module module_name
in
131 with Not_found
-> false
133 let load_module module_name
=
134 if not
(is_module_loaded module_name
) then
135 let m = pyimport_importmodule module_name
in
136 check_return_value m;
137 (module_map := (StringMap.add module_name
m (!module_map));
139 else get_module module_name
140 (* end python module handling part *)
142 (* python interaction *)
144 let last_period = String.rindex fqn '
.'
in
145 let module_name = String.sub fqn
0 last_period in
146 let class_name = String.sub fqn
(last_period + 1) (String.length fqn
- last_period - 1) in
147 (module_name, class_name)
149 let pycocci_get_class_type fqn
=
150 let (module_name, class_name) = split_fqn fqn
in
151 let m = get_module module_name in
152 let attr = pyobject_getattrstring
(m, class_name) in
153 check_return_value attr;
156 let pycocci_instantiate_class fqn args
=
157 let class_type = pycocci_get_class_type fqn
in
159 pyeval_callobjectwithkeywords
(class_type, args
, pynull
()) in
160 check_return_value obj;
163 (* end python interaction *)
165 let inc_match = ref true
167 let include_match v
=
168 let truth = pyobject_istrue
(pytuple_getitem
(v
, 1)) in
169 check_int_return_value truth;
170 inc_match := truth != 0;
173 let build_method (mname
, camlfunc
, args
) pymodule classx classdict
=
174 let cmx = pymethod_new
(pywrap_closure camlfunc
, args
, classx
) in
175 let v = pydict_setitemstring
(classdict
, mname
, cmx) in
176 check_int_return_value v;
179 let build_class cname parent methods pymodule
=
180 let cd = pydict_new
() in
181 check_return_value cd;
182 let cx = pyclass_new
(pytuple_fromsingle
(pycocci_get_class_type parent
), cd,
183 pystring_fromstring cname
) in
184 check_return_value cx;
185 List.iter
(function meth
-> build_method meth pymodule
cx cd) methods
;
186 let v = pydict_setitemstring
(pymodule_getdict pymodule
, cname
, cx) in
187 check_int_return_value v;
190 let the_environment = ref []
192 let has_environment_binding name
=
193 let a = pytuple_toarray name
in
194 let (rule
, name
) = (Array.get
a 1, Array.get
a 2) in
195 let orule = pystring_asstring rule
in
196 let oname = pystring_asstring name
in
197 let e = List.exists
(function (x
,y
) -> orule =*= x
&& oname =$
= y
)
199 if e then _pycocci_true () else _pycocci_false ()
201 let pyoutputinstance = ref (_pycocci_none ())
202 let pyoutputdict = ref (_pycocci_none ())
204 let get_cocci_file args
=
205 pystring_fromstring
(!cocci_file_name)
207 (* initialisation routines *)
208 let _pycocci_setargs argv0
=
210 pysequence_list
(pytuple_fromsingle
(pystring_fromstring argv0
)) in
211 let sys_mod = load_module "sys" in
212 pyobject_setattrstring
(sys_mod, "argv", argv)
214 let pycocci_init () =
216 if not
!initialised then (
218 Unix.putenv
"PYTHONPATH"
219 (Printf.sprintf
"%s/coccinelle" (Unix.getenv
"HOME"));
220 let _ = if not
(py_isinitialized
() != 0) then
221 (if !Flag.show_misc
then Common.pr2
"Initializing python\n%!";
225 let argv0 = Printf.sprintf
"%s%sspatch" (Sys.getcwd
()) (match Sys.os_type
with "Win32" -> "\\" | _ -> "/") in
226 let _ = _pycocci_setargs argv0 in
228 coccinelle_module := (pymodule_new
"coccinelle");
229 module_map := StringMap.add
"coccinelle" !coccinelle_module !module_map;
230 let _ = load_module "coccilib.elems" in
231 let _ = load_module "coccilib.output" in
233 let module_dictionary = pyimport_getmoduledict
() in
234 coccinelle_module := pymodule_new
"coccinelle";
235 let mx = !coccinelle_module in
236 let (cd, cx) = build_class "Cocci" (!Flag.pyoutput
)
237 [("include_match", include_match, (pynull
()));
238 ("has_env_binding", has_environment_binding, (pynull
()))] mx in
239 pyoutputinstance := cx;
241 let v1 = pydict_setitemstring
(module_dictionary, "coccinelle", mx) in
242 check_int_return_value v1;
243 let mypystring = pystring_fromstring
!cocci_file_name in
244 let v2 = pydict_setitemstring
(cd, "cocci_file", mypystring) in
245 check_int_return_value v2;
249 (*let _ = pycocci_init ()*)
250 (* end initialisation routines *)
252 let added_variables = ref []
254 let build_classes env
=
255 let _ = pycocci_init () in
257 the_environment := env
;
258 let mx = !coccinelle_module in
259 let dict = pymodule_getdict
mx in
262 "include_match" | "has_env_binding" -> ()
264 let v = pydict_delitemstring
(dict,name
) in
265 check_int_return_value v)
267 added_variables := [];
270 let build_variable name
value =
271 let mx = !coccinelle_module in
272 added_variables := name
:: !added_variables;
273 check_int_return_value
274 (pydict_setitemstring
(pymodule_getdict
mx, name
, value))
276 let get_variable name
=
277 let mx = !coccinelle_module in
279 (pyobject_str
(pydict_getitemstring
(pymodule_getdict
mx, name
)))
281 let contains_binding e (_,(r
,m),_) =
283 let _ = List.find
(function ((re
, rm
), _) -> r
=*= re
&& m =$
= rm
) e in
285 with Not_found
-> false
287 let construct_variables mv
e =
288 let find_binding (r
,m) =
290 let elem = List.find
(function ((re
,rm
),_) -> r
=*= re
&& m =$
= rm
) e in
292 with Not_found
-> None
295 let instantiate_Expression(x
) =
296 let str = pystring_fromstring
(Pycocci_aux.exprrep x
) in
297 pycocci_instantiate_class "coccilib.elems.Expression"
298 (pytuple_fromsingle
(str))
301 let instantiate_Identifier(x
) =
302 let str = pystring_fromstring x
in
303 pycocci_instantiate_class "coccilib.elems.Identifier"
304 (pytuple_fromsingle
(str))
307 List.iter
(function (py
,(r
,m),_) ->
308 match find_binding (r
,m) with
310 | Some
(_, Ast_c.MetaExprVal
(expr
,_)) ->
311 let expr_repr = instantiate_Expression(expr
) in
312 let _ = build_variable py
expr_repr in
314 | Some
(_, Ast_c.MetaIdVal
(id
,_)) ->
315 let id_repr = instantiate_Identifier(id
) in
316 let _ = build_variable py
id_repr in
318 | Some
(_, Ast_c.MetaPosValList l
) ->
321 (function (fname
,current_element
,(line
,col
),(line_end
,col_end
)) ->
322 pycocci_instantiate_class "coccilib.elems.Location"
324 (pystring_fromstring fname
,pystring_fromstring current_element
,
325 pystring_fromstring
(Printf.sprintf
"%d" line
),
326 pystring_fromstring
(Printf.sprintf
"%d" col
),
327 pystring_fromstring
(Printf.sprintf
"%d" line_end
),
328 pystring_fromstring
(Printf.sprintf
"%d" col_end
)))) l
in
329 let pylocs = pytuple_fromarray
(Array.of_list
locs) in
330 let _ = build_variable py
pylocs in
332 | Some
(_,binding
) ->
335 (pystring_fromstring
(Pycocci_aux.stringrep binding
)) in
341 let construct_script_variables mv
=
345 let str = pystring_fromstring
"initial value" in
346 pycocci_instantiate_class "coccilib.elems.Identifier"
347 (pytuple_fromsingle
(str)) in
348 let _ = build_variable py
vl in
352 let retrieve_script_variables mv
=
353 List.map
(function (_,py
) -> get_variable py
) mv
355 let set_coccifile cocci_file
=
356 cocci_file_name := cocci_file
;
359 let pyrun_simplestring s
=
360 let res = Pycaml.pyrun_simplestring s
in
361 check_int_return_value res;
364 let py_isinitialized () =
365 Pycaml.py_isinitialized ()
369 Pycaml.py_finalize ()