11
10
#include "pcilib.h"
17
#endif /* HAVE_PYTHON */
20
typedef struct pcilib_script_s pcilib_script_t;
22
struct pcilib_script_s {
23
const char *name; /**< Script name */
24
PyObject *module; /**< PyModule object, contains script enviroment */
25
UT_hash_handle hh; /**< hash */
15
28
struct pcilib_py_s {
16
PyObject *main_module;
17
PyObject *global_dict;
29
int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */
30
PyObject *main_module; /**< Main interpreter */
31
PyObject *global_dict; /**< Dictionary of main interpreter */
32
PyObject *pcilib_pywrap; /**< pcilib wrapper module */
33
pcilib_script_t *script_hash; /**< Hash with loaded scripts */
35
#endif /* HAVE_PYTHON */
37
void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...) {
39
const char *type = NULL;
40
const char *val = NULL;
43
PyObject *pytype = NULL;
44
PyObject *pyval = NULL;
45
PyObject *pytraceback = NULL;
47
PyErr_Fetch(&pytype, &pyval, &pytraceback);
48
type = PyString_AsString(pytype);
49
val = PyString_AsString(pyval);
50
#endif /* HAVE_PYTHON */
57
if (msg) len += strlen(msg);
58
if (type) len += strlen(type);
59
if (val) len += strlen(val);
61
str = alloca(len * sizeof(char));
64
sprintf(str, "%s <%s: %s>", msg, type, val);
66
sprintf(str, "%s <%s>", msg, type);
68
sprintf(str, "Python error %s: %s", type, val);
70
sprintf(str, "Python error %s", type);
72
pcilib_log_vmessage(file, line, flags, prio, str, va);
75
pcilib_log_vmessage(file, line, flags, prio, msg, va);
82
Py_XDECREF(pytraceback);
83
#endif /* HAVE_PYTHON */
20
88
int pcilib_init_py(pcilib_t *ctx) {
21
90
ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
22
91
if (!ctx->py) return PCILIB_ERROR_MEMORY;
93
memset(ctx->py, 0, sizeof(pcilib_py_t));
95
if(Py_IsInitialized())
96
ctx->py->finalyze = 1;
100
// Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads
101
PyEval_InitThreads();
102
PyEval_ReleaseLock();
26
105
ctx->py->main_module = PyImport_AddModule("__parser__");
27
if (!ctx->py->main_module)
106
if (!ctx->py->main_module) {
107
pcilib_python_error("Error importing python parser");
28
108
return PCILIB_ERROR_FAILED;
30
111
ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module);
31
if (!ctx->py->global_dict)
32
return PCILIB_ERROR_FAILED;
112
if (!ctx->py->global_dict) {
113
pcilib_python_error("Error locating global python dictionary");
114
return PCILIB_ERROR_FAILED;
117
PyObject *pywrap = PyImport_ImportModule("pcipywrap");
119
pcilib_python_error("Error importing pcilib python wrapper");
120
return PCILIB_ERROR_FAILED;
123
PyObject *mod_name = PyString_FromString("Pcipywrap");
124
ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(pywrap, mod_name, PyCObject_FromVoidPtr(ctx, NULL), NULL);
125
Py_XDECREF(mod_name);
127
if (!ctx->py->pcilib_pywrap) {
128
pcilib_python_error("Error initializing python wrapper");
129
return PCILIB_ERROR_FAILED;
131
#endif /* HAVE_PYTHON */
136
int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
141
const char *model_dir = getenv("PCILIB_MODEL_DIR");
142
if (!model_dir) model_dir = PCILIB_MODEL_DIR;
144
if (!dir) dir = ctx->model;
147
script_dir = (char*)dir;
149
script_dir = alloca(strlen(model_dir) + strlen(dir) + 2);
150
if (!script_dir) return PCILIB_ERROR_MEMORY;
151
sprintf(script_dir, "%s/%s", model_dir, dir);
154
pypath = PySys_GetObject("path");
156
pcilib_python_error("Can't get python path");
157
return PCILIB_ERROR_FAILED;
160
// Shall we check if the directory already in the path?
161
if(PyList_Append(pypath, PyString_FromString(script_dir)) == -1) {
162
pcilib_python_error("Can't add directory (%s) to python path", script_dir);
163
return PCILIB_ERROR_FAILED;
165
#endif /* HAVE_PYTHON */
37
170
void pcilib_free_py(pcilib_t *ctx) {
39
// Dict and module references are borrowed
175
if(ctx->py->finalyze) finalyze = 1;
177
if (ctx->py->script_hash) {
178
pcilib_script_t *script, *script_tmp;
180
HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) {
181
HASH_DEL(ctx->py->script_hash, script);
184
ctx->py->script_hash = NULL;
48
static int pcilib_py_realloc_string(pcilib_t *ctx, size_t required, size_t *size, char **str) {
52
if ((required + 1) > cur) {
53
while (cur < required) cur *= 2;
54
ptr = (char*)realloc(*str, cur);
55
if (!ptr) return PCILIB_ERROR_MEMORY;
193
#endif /* HAVE_PYTHON */
196
int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
199
pcilib_script_t *module = NULL;
202
char *module_name = strdupa(script_name);
203
if (!module_name) return PCILIB_ERROR_MEMORY;
205
char *py = strrchr(module_name, '.');
206
if ((!py)||(strcasecmp(py, ".py"))) {
207
pcilib_error("Invalid script name (%s) is specified", script_name);
208
return PCILIB_ERROR_INVALID_ARGUMENT;
212
HASH_FIND_STR(ctx->py->script_hash, script_name, module);
213
if (module) return 0;
215
pymodule = PyImport_ImportModule(module_name);
217
pcilib_python_error("Error importing script (%s)", script_name);
218
return PCILIB_ERROR_FAILED;
221
module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t));
222
if (!module) return PCILIB_ERROR_MEMORY;
224
module->module = pymodule;
225
module->name = script_name;
226
HASH_ADD_KEYPTR(hh, ctx->py->script_hash, module->name, strlen(module->name), module);
227
#endif /* HAVE_PYTHON */
231
int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_name, pcilib_access_mode_t *mode_ret) {
232
pcilib_access_mode_t mode = 0;
237
pcilib_script_t *module;
239
HASH_FIND_STR(ctx->py->script_hash, script_name, module);
242
pcilib_error("Script (%s) is not loaded yet", script_name);
243
return PCILIB_ERROR_NOTFOUND;
246
dict = PyModule_GetDict(module->module);
248
pcilib_python_error("Error getting dictionary for script (%s)", script_name);
249
return PCILIB_ERROR_FAILED;
252
pystr = PyString_FromString("read_from_register");
254
if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_R;
258
pystr = PyString_FromString("write_to_register");
260
if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W;
263
#endif /* HAVE_PYTHON */
265
if (mode_ret) *mode_ret = mode;
269
pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) {
272
PyObject *res = NULL;
278
case PCILIB_TYPE_LONG:
279
ival = pcilib_get_value_as_int(ctx, val, &err);
280
if (!err) res = (PyObject*)PyInt_FromLong(ival);
282
case PCILIB_TYPE_DOUBLE:
283
fval = pcilib_get_value_as_float(ctx, val, &err);
284
if (!err) res = (PyObject*)PyFloat_FromDouble(fval);
287
err = PCILIB_ERROR_NOTSUPPORTED;
288
pcilib_error("Can't convert pcilib value of type (%lu) to PyObject", val->type);
295
if (ret) *ret = PCILIB_ERROR_MEMORY;
301
#else /* HAVE_PYTHON */
302
pcilib_error("Python is not supported");
304
#endif /* HAVE_PYTHON */
307
int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object *pval) {
310
PyObject *pyval = (PyObject*)pval;
312
if (PyInt_Check(pyval)) {
313
err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyval));
314
} else if (PyFloat_Check(pyval)) {
315
err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyval));
316
} else if (PyString_Check(pyval)) {
317
err = pcilib_set_value_from_string(ctx, val, PyString_AsString(pyval));
319
pcilib_error("Can't convert PyObject to polymorphic pcilib value");
320
err = PCILIB_ERROR_NOTSUPPORTED;
324
#else /* HAVE_PYTHON */
325
pcilib_error("Python is not supported");
326
return PCILIB_ERROR_NOTSUPPORTED;
327
#endif /* HAVE_PYTHON */
64
331
static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) {
190
459
pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code);
191
460
return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
461
#else /* HAVE_PYTHON */
462
pcilib_error("Current build not support python.");
463
return PCILIB_ERROR_NOTAVAILABLE;
464
#endif /* HAVE_PYTHON */
467
int pcilib_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func_name, pcilib_value_t *val) {
471
PyObject *pyval = NULL, *pyret;
472
pcilib_script_t *module = NULL;
474
HASH_FIND_STR(ctx->py->script_hash, script_name, module);
477
pcilib_error("Script (%s) is not loaded", script_name);
478
return PCILIB_ERROR_NOTFOUND;
482
pyval = pcilib_get_value_as_pyobject(ctx, val, &err);
486
pyfunc = PyUnicode_FromString(func_name);
488
if (pyval) Py_XDECREF(pyval);
489
return PCILIB_ERROR_MEMORY;
492
PyGILState_STATE gstate = PyGILState_Ensure();
493
pyret = PyObject_CallMethodObjArgs(module->module, pyfunc, ctx->py->pcilib_pywrap, pyval, NULL);
494
PyGILState_Release(gstate);
500
pcilib_python_error("Error executing function (%s) of python script (%s)", func_name, script_name);
501
return PCILIB_ERROR_FAILED;
504
if ((val)&&(pyret != Py_None))
505
err = pcilib_set_value_from_pyobject(ctx, val, pyret);
510
#else /* HAVE_PYTHON */
511
pcilib_error("Python is not supported");
512
return PCILIB_ERROR_NOTSUPPORTED;
513
#endif /* HAVE_PYTHON */