2 * Copyright 2005-2008, 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.
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 let check_return_value v
=
32 if v
= (pynull
()) then
34 raise Pycocciexception
)
36 let check_int_return_value v
=
39 raise Pycocciexception
)
42 let initialised = ref false
44 let coccinelle_module = ref (pynone
())
45 let cocci_file_name = ref ""
47 (* dealing with python modules loaded *)
48 let module_map = ref (StringMap.add
"__main__" (pynone
()) StringMap.empty
)
50 let get_module module_name
=
51 StringMap.find module_name
(!module_map)
53 let is_module_loaded module_name
=
55 let _ = get_module module_name
in
57 with Not_found
-> false
59 let load_module module_name
=
60 if not
(is_module_loaded module_name
) then
61 let m = pyimport_importmodule module_name
in
63 (module_map := (StringMap.add module_name
m (!module_map));
65 else get_module module_name
66 (* end python module handling part *)
68 (* initialisation routines *)
71 if not
!initialised then (
73 Unix.putenv
"PYTHONPATH"
74 (Printf.sprintf
"%s/coccinelle" (Unix.getenv
"HOME"));
75 let _ = if not
(py_isinitialized
() != 0) then
76 (if !Flag.show_misc
then Common.pr2
"Initializing python\n%!";
80 let argv0 = Printf.sprintf
"%s%sspatch" (Sys.getcwd
()) (match Sys.os_type
with "Win32" -> "\\" | _ -> "/") in
81 let _ = pycaml_setargs
argv0 in
83 coccinelle_module := (pymodule_new
"coccinelle");
84 module_map := StringMap.add
"coccinelle" !coccinelle_module !module_map;
85 let _ = load_module "coccilib.elems" in
86 let _ = load_module "coccilib.output" in
91 (*let _ = pycocci_init ()*)
92 (* end initialisation routines *)
94 (* python interaction *)
96 let last_period = String.rindex fqn '
.'
in
97 let module_name = String.sub fqn
0 last_period in
98 let class_name = String.sub fqn
(last_period + 1) (String.length fqn
- last_period - 1) in
99 (module_name, class_name)
101 let pycocci_get_class_type fqn
=
102 let (module_name, class_name) = split_fqn fqn
in
103 let m = get_module module_name in
104 let attr = pyobject_getattrstring
(m, class_name) in
105 check_return_value attr;
108 let pycocci_instantiate_class fqn args
=
109 let class_type = pycocci_get_class_type fqn
in
110 let obj = pyobject_callobject
(class_type, args
) in
111 check_return_value obj;
114 (* end python interaction *)
116 let inc_match = ref true
118 let include_match v
=
119 let truth = pyobject_istrue
(pytuple_getitem
(v
, 1)) in
120 check_int_return_value truth;
121 inc_match := truth != 0;
124 let build_method (mname
, camlfunc
, args
) pymodule classx classdict
=
125 let cmx = pymethod_new
(pywrap_closure camlfunc
, args
, classx
) in
126 let v = pydict_setitemstring
(classdict
, mname
, cmx) in
127 check_int_return_value v;
130 let build_class cname parent methods pymodule
=
131 let cd = pydict_new
() in
132 check_return_value cd;
133 let cx = pyclass_new
(pytuple_fromsingle
(pycocci_get_class_type parent
), cd, pystring_fromstring cname
) in
134 check_return_value cx;
135 List.iter
(function meth
-> build_method meth pymodule
cx cd) methods
;
136 let v = pydict_setitemstring
(pymodule_getdict pymodule
, cname
, cx) in
137 check_int_return_value v;
140 let has_environment_binding env name
=
141 let a = pytuple_toarray name
in
142 let (rule
, name
) = (Array.get
a 1, Array.get
a 2) in
143 let orule = pystring_asstring rule
in
144 let oname = pystring_asstring name
in
145 let e = List.exists
(function (x
,y
) -> orule = x
&& oname = y
) env
in
146 if e then pytrue
() else pyfalse
()
148 let pyoutputinstance = ref (pynone
())
149 let pyoutputdict = ref (pynone
())
151 let get_cocci_file args
=
152 pystring_fromstring
(!cocci_file_name)
154 let build_classes env
=
155 let _ = pycocci_init () in
156 let module_dictionary = pyimport_getmoduledict
() in
157 coccinelle_module := pymodule_new
"coccinelle";
158 let mx = !coccinelle_module in
160 let (cd, cx) = build_class "Cocci" (!Flag.pyoutput
)
161 [("include_match", include_match, (pynull
()));
162 ("has_env_binding", has_environment_binding env
, (pynull
()))] mx in
163 pyoutputinstance := cx;
165 let v1 = pydict_setitemstring
(module_dictionary, "coccinelle", mx) in
166 check_int_return_value v1;
167 let mypystring = pystring_fromstring
!cocci_file_name in
168 let v2 = pydict_setitemstring
(cd, "cocci_file", mypystring) in
169 check_int_return_value v2;
172 let build_variable name
value =
173 let mx = !coccinelle_module in
174 check_int_return_value (pydict_setitemstring
(pymodule_getdict
mx, name
, value))
176 let contains_binding e (_,(r
,m)) =
178 let _ = List.find
(function ((re
, rm
), _) -> r
= re
&& m = rm
) e in true
179 with Not_found
-> false
181 let construct_variables mv
e =
182 let find_binding (r
,m) =
184 let elem = List.find
(function ((re
,rm
),_) -> r
= re
&& m = rm
) e in
186 with Not_found
-> None
189 let instantiate_Expression(x
) =
190 let str = pystring_fromstring
(Pycocci_aux.exprrep x
) in
191 pycocci_instantiate_class "coccilib.elems.Expression" (pytuple_fromsingle
(str))
194 let instantiate_Identifier(x
) =
195 let str = pystring_fromstring x
in
196 pycocci_instantiate_class "coccilib.elems.Identifier" (pytuple_fromsingle
(str))
199 List.iter
(function (py
,(r
,m)) ->
200 match find_binding (r
,m) with
202 | Some
(_, Ast_c.MetaExprVal
((expr
, _), info_list
)) ->
203 let expr_repr = instantiate_Expression(expr
) in
204 let _ = build_variable py
expr_repr in
206 | Some
(_, Ast_c.MetaIdVal id
) ->
207 let id_repr = instantiate_Identifier(id
) in
208 let _ = build_variable py
id_repr in
210 | Some
(_, Ast_c.MetaPosValList l
) ->
213 (function (fname
,current_element
,(line
,col
),(line_end
,col_end
)) ->
214 pycocci_instantiate_class "coccilib.elems.Location" (pytuple6
215 (pystring_fromstring fname
,pystring_fromstring current_element
,
216 pystring_fromstring
(Printf.sprintf
"%d" line
),
217 pystring_fromstring
(Printf.sprintf
"%d" col
),
218 pystring_fromstring
(Printf.sprintf
"%d" line_end
),
219 pystring_fromstring
(Printf.sprintf
"%d" col_end
)))) l
in
220 let pylocs = pytuple_fromarray
(Array.of_list
locs) in
221 let _ = build_variable py
pylocs in
223 | Some
(_,binding
) ->
224 let _ = build_variable py
(pystring_fromstring
(Pycocci_aux.stringrep binding
))
230 let set_coccifile cocci_file
=
231 cocci_file_name := cocci_file
;
235 let pyrun_simplestring s
=
236 Pycaml.pyrun_simplestring s
238 let py_isinitialized () =
239 Pycaml.py_isinitialized ()
243 Pycaml.py_finalize ()