diff options
Diffstat (limited to 'pcilib/py.c')
-rw-r--r-- | pcilib/py.c | 389 |
1 files changed, 199 insertions, 190 deletions
diff --git a/pcilib/py.c b/pcilib/py.c index 271a3fd..3e1f38d 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -5,6 +5,7 @@ #endif /* HAVE_PYTHON */ #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <strings.h> #include <alloca.h> @@ -47,9 +48,9 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag gstate = PyGILState_Ensure(); if (PyErr_Occurred()) { - PyErr_Fetch(&pytype, &pyval, &pytraceback); - type = PyString_AsString(pytype); - val = PyString_AsString(pyval); + PyErr_Fetch(&pytype, &pyval, &pytraceback); + type = PyString_AsString(pytype); + val = PyString_AsString(pyval); } PyGILState_Release(gstate); #endif /* HAVE_PYTHON */ @@ -82,9 +83,9 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag va_end(va); #ifdef HAVE_PYTHON - if (pytype) Py_XDECREF(pytype); - if (pyval) Py_XDECREF(pyval); - if (pytraceback) Py_XDECREF(pytraceback); + if (pytype) Py_DECREF(pytype); + if (pyval) Py_DECREF(pyval); + if (pytraceback) Py_DECREF(pytraceback); #endif /* HAVE_PYTHON */ } @@ -97,101 +98,109 @@ int pcilib_init_py(pcilib_t *ctx) { memset(ctx->py, 0, sizeof(pcilib_py_t)); - if(Py_IsInitialized()) - ctx->py->finalyze = 0; - else { + if(!Py_IsInitialized()) { Py_Initialize(); - // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads + // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads PyEval_InitThreads(); PyEval_ReleaseLock(); + ctx->py->finalyze = 1; } ctx->py->main_module = PyImport_AddModule("__parser__"); if (!ctx->py->main_module) { - pcilib_python_error("Error importing python parser"); - return PCILIB_ERROR_FAILED; + pcilib_python_error("Error importing python parser"); + return PCILIB_ERROR_FAILED; } ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) { - pcilib_python_error("Error locating global python dictionary"); - return PCILIB_ERROR_FAILED; + pcilib_python_error("Error locating global python dictionary"); + return PCILIB_ERROR_FAILED; } PyObject *pywrap = PyImport_ImportModule("pcipywrap"); if (!pywrap) { - pcilib_python_error("Error importing pcilib python wrapper"); - return PCILIB_ERROR_FAILED; + pcilib_python_error("Error importing pcilib python wrapper"); + return PCILIB_ERROR_FAILED; } PyObject *mod_name = PyString_FromString("Pcipywrap"); - PyObject *ctx_py_ptr = PyCObject_FromVoidPtr(ctx, NULL); - ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(pywrap, mod_name, ctx_py_ptr, NULL); - Py_DECREF(ctx_py_ptr); - Py_DECREF(mod_name); + PyObject *pyctx = PyCObject_FromVoidPtr(ctx, NULL); + ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(pywrap, mod_name, pyctx, NULL); + Py_XDECREF(pyctx); + Py_XDECREF(mod_name); if (!ctx->py->pcilib_pywrap) { - pcilib_python_error("Error initializing python wrapper"); - return PCILIB_ERROR_FAILED; + pcilib_python_error("Error initializing python wrapper"); + return PCILIB_ERROR_FAILED; } #endif /* HAVE_PYTHON */ + return 0; } int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { #ifdef HAVE_PYTHON - PyObject* pypath; - char *script_dir; - - const char *model_dir = getenv("PCILIB_MODEL_DIR"); - if (!model_dir) model_dir = PCILIB_MODEL_DIR; - - if (!dir) dir = ctx->model; - - if (*dir == '/') { - script_dir = (char*)dir; - } else { - script_dir = alloca(strlen(model_dir) + strlen(dir) + 2); - if (!script_dir) return PCILIB_ERROR_MEMORY; - sprintf(script_dir, "%s/%s", model_dir, dir); - } - - pypath = PySys_GetObject("path"); - if (!pypath) { - pcilib_python_error("Can't get python path"); - return PCILIB_ERROR_FAILED; - } - - PyObject* new_path = PyString_FromString(script_dir); - - //Check if sys.path already contains our path - PyObject* dict = PyDict_New(); - PyObject* cur_py = PyString_FromString("cur"); - PyObject* path_py = PyString_FromString("path"); - PyDict_SetItem(dict, cur_py, new_path); - PyDict_SetItem(dict, path_py, pypath); - Py_DECREF(cur_py); - Py_DECREF(path_py); - - PyObject* pyret = PyRun_String("cur in path", Py_eval_input, - ctx->py->global_dict, - dict); - Py_DECREF(dict); - - if(pyret == Py_False) { - if(PyList_Append(pypath, new_path) == -1) { - pcilib_python_error("Can't add directory (%s) to python path", script_dir); - return PCILIB_ERROR_FAILED; - } - } - else if(pyret == Py_True) - { - printf("1\n"); - Py_DECREF(new_path); - return 0; - } - + int err = 0; + PyObject *pypath, *pynewdir; + PyObject *pydict, *pystr, *pyret = NULL; + char *script_dir; + + const char *model_dir = getenv("PCILIB_MODEL_DIR"); + if (!model_dir) model_dir = PCILIB_MODEL_DIR; + + if (!dir) dir = ctx->model; + + if (*dir == '/') { + script_dir = (char*)dir; + } else { + script_dir = alloca(strlen(model_dir) + strlen(dir) + 2); + if (!script_dir) return PCILIB_ERROR_MEMORY; + sprintf(script_dir, "%s/%s", model_dir, dir); + } + + pypath = PySys_GetObject("path"); + if (!pypath) { + pcilib_python_error("Can't get python path"); + return PCILIB_ERROR_FAILED; + } + + pynewdir = PyString_FromString(script_dir); + if (!pynewdir) { + pcilib_python_error("Can't create python string"); + return PCILIB_ERROR_MEMORY; + } + + // Checking if the directory already in the path? + pydict = PyDict_New(); + if (pydict) { + pystr = PyString_FromString("cur"); + if (pystr) { + PyDict_SetItem(pydict, pystr, pynewdir); + Py_DECREF(pystr); + } + + pystr = PyString_FromString("path"); + if (pystr) { + PyDict_SetItem(pydict, pystr, pypath); + Py_DECREF(pystr); + } + + pyret = PyRun_String("cur in path", Py_eval_input, ctx->py->global_dict, pydict); + Py_DECREF(pydict); + } + + if ((pyret == Py_False)&&(PyList_Append(pypath, pynewdir) == -1)) + err = PCILIB_ERROR_FAILED; + + if (pyret) Py_DECREF(pyret); + Py_DECREF(pynewdir); + + if (err) { + pcilib_python_error("Can't add directory (%s) to python path", script_dir); + return err; + } #endif /* HAVE_PYTHON */ return 0; @@ -199,65 +208,65 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { void pcilib_free_py(pcilib_t *ctx) { #ifdef HAVE_PYTHON - int finalyze = 0; + int finalyze = 0; + + if (ctx->py) { + if (ctx->py->finalyze) finalyze = 1; + + if (ctx->py->script_hash) { + pcilib_script_t *script, *script_tmp; + + HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) { + Py_DECREF(script->module); + HASH_DEL(ctx->py->script_hash, script); + free(script); + } + ctx->py->script_hash = NULL; + } + + if (ctx->py->pcilib_pywrap) + Py_DECREF(ctx->py->pcilib_pywrap); - if (ctx->py) { - - if(ctx->py->finalyze) finalyze = 1; - if (ctx->py->script_hash) { - pcilib_script_t *script, *script_tmp; - - HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) { - Py_DECREF(script->module); - - HASH_DEL(ctx->py->script_hash, script); - free(script); - } - ctx->py->script_hash = NULL; - } - - Py_DECREF(ctx->py->pcilib_pywrap); - - free(ctx->py); - ctx->py = NULL; - } + free(ctx->py); + ctx->py = NULL; + } if (finalyze) - Py_Finalize(); + Py_Finalize(); #endif /* HAVE_PYTHON */ } int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) { #ifdef HAVE_PYTHON - PyObject* pymodule; - pcilib_script_t *module = NULL; + PyObject* pymodule; + pcilib_script_t *module = NULL; - char *module_name = strdupa(script_name); - if (!module_name) return PCILIB_ERROR_MEMORY; + char *module_name = strdupa(script_name); + if (!module_name) return PCILIB_ERROR_MEMORY; - char *py = strrchr(module_name, '.'); - if ((!py)||(strcasecmp(py, ".py"))) { - pcilib_error("Invalid script name (%s) is specified", script_name); - return PCILIB_ERROR_INVALID_ARGUMENT; - } - *py = 0; + char *py = strrchr(module_name, '.'); + if ((!py)||(strcasecmp(py, ".py"))) { + pcilib_error("Invalid script name (%s) is specified", script_name); + return PCILIB_ERROR_INVALID_ARGUMENT; + } + *py = 0; - HASH_FIND_STR(ctx->py->script_hash, script_name, module); - if (module) return 0; + HASH_FIND_STR(ctx->py->script_hash, script_name, module); + if (module) return 0; - pymodule = PyImport_ImportModule(module_name); - if (!pymodule) { - pcilib_python_error("Error importing script (%s)", script_name); - return PCILIB_ERROR_FAILED; - } + pymodule = PyImport_ImportModule(module_name); + if (!pymodule) { + pcilib_python_error("Error importing script (%s)", script_name); + return PCILIB_ERROR_FAILED; + } - module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); - if (!module) return PCILIB_ERROR_MEMORY; + module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); + if (!module) return PCILIB_ERROR_MEMORY; - module->module = pymodule; - module->name = script_name; - HASH_ADD_KEYPTR(hh, ctx->py->script_hash, module->name, strlen(module->name), module); + module->module = pymodule; + module->name = script_name; + HASH_ADD_KEYPTR(hh, ctx->py->script_hash, module->name, strlen(module->name), module); #endif /* HAVE_PYTHON */ return 0; } @@ -266,34 +275,34 @@ int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_ pcilib_access_mode_t mode = 0; #ifdef HAVE_PYTHON - PyObject *dict; - PyObject *pystr; - pcilib_script_t *module; - - HASH_FIND_STR(ctx->py->script_hash, script_name, module); - - if(!module) { - pcilib_error("Script (%s) is not loaded yet", script_name); - return PCILIB_ERROR_NOTFOUND; - } - - dict = PyModule_GetDict(module->module); - if (!dict) { - pcilib_python_error("Error getting dictionary for script (%s)", script_name); - return PCILIB_ERROR_FAILED; - } - - pystr = PyString_FromString("read_from_register"); - if (pystr) { - if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_R; - Py_XDECREF(pystr); - } - - pystr = PyString_FromString("write_to_register"); - if (pystr) { - if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W; - Py_XDECREF(pystr); - } + PyObject *dict; + PyObject *pystr; + pcilib_script_t *module; + + HASH_FIND_STR(ctx->py->script_hash, script_name, module); + + if(!module) { + pcilib_error("Script (%s) is not loaded yet", script_name); + return PCILIB_ERROR_NOTFOUND; + } + + dict = PyModule_GetDict(module->module); + if (!dict) { + pcilib_python_error("Error getting dictionary for script (%s)", script_name); + return PCILIB_ERROR_FAILED; + } + + pystr = PyString_FromString("read_from_register"); + if (pystr) { + if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_R; + Py_DECREF(pystr); + } + + pystr = PyString_FromString("write_to_register"); + if (pystr) { + if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W; + Py_DECREF(pystr); + } #endif /* HAVE_PYTHON */ if (mode_ret) *mode_ret = mode; @@ -309,31 +318,31 @@ pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *va long ival; double fval; - gstate = PyGILState_Ensure(); - switch(val->type) { - case PCILIB_TYPE_LONG: - ival = pcilib_get_value_as_int(ctx, val, &err); - if (!err) res = (PyObject*)PyInt_FromLong(ival); - break; - case PCILIB_TYPE_DOUBLE: - fval = pcilib_get_value_as_float(ctx, val, &err); - if (!err) res = (PyObject*)PyFloat_FromDouble(fval); - break; - default: - PyGILState_Release(gstate); - pcilib_error("Can't convert pcilib value of type (%lu) to PyObject", val->type); - if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; - return NULL; - } - PyGILState_Release(gstate); - - if (err) { - if (ret) *ret = err; - return NULL; - } else if (!res) { - if (ret) *ret = PCILIB_ERROR_MEMORY; - return res; - } + gstate = PyGILState_Ensure(); + switch(val->type) { + case PCILIB_TYPE_LONG: + ival = pcilib_get_value_as_int(ctx, val, &err); + if (!err) res = (PyObject*)PyInt_FromLong(ival); + break; + case PCILIB_TYPE_DOUBLE: + fval = pcilib_get_value_as_float(ctx, val, &err); + if (!err) res = (PyObject*)PyFloat_FromDouble(fval); + break; + default: + PyGILState_Release(gstate); + pcilib_error("Can't convert pcilib value of type (%lu) to PyObject", val->type); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; + return NULL; + } + PyGILState_Release(gstate); + + if (err) { + if (ret) *ret = err; + return NULL; + } else if (!res) { + if (ret) *ret = PCILIB_ERROR_MEMORY; + return res; + } if (ret) *ret = 0; return res; @@ -481,36 +490,36 @@ static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_v int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { #ifdef HAVE_PYTHON int err; - + PyGILState_STATE gstate; char *code; PyObject* obj; - code = pcilib_py_parse_string(ctx, codestr, value); if (!code) { pcilib_error("Failed to parse registers in the code: %s", codestr); return PCILIB_ERROR_FAILED; } - + gstate = PyGILState_Ensure(); obj = PyRun_String(code, Py_eval_input, ctx->py->global_dict, ctx->py->global_dict); PyGILState_Release(gstate); - - free(code); if (!obj) { pcilib_error("Failed to run the Python code: %s", code); + free(code); return PCILIB_ERROR_FAILED; } pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code); err = pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); + Py_DECREF(obj); + free(code); return err; #else /* HAVE_PYTHON */ - pcilib_error("Current build not support python."); + pcilib_error("Current build not support python."); return PCILIB_ERROR_NOTAVAILABLE; #endif /* HAVE_PYTHON */ } @@ -525,39 +534,39 @@ int pcilib_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func HASH_FIND_STR(ctx->py->script_hash, script_name, module); if (!module) { - pcilib_error("Script (%s) is not loaded", script_name); - return PCILIB_ERROR_NOTFOUND; + pcilib_error("Script (%s) is not loaded", script_name); + return PCILIB_ERROR_NOTFOUND; } if (val) { - pyval = pcilib_get_value_as_pyobject(ctx, val, &err); - if (err) return err; + pyval = pcilib_get_value_as_pyobject(ctx, val, &err); + if (err) return err; } PyGILState_STATE gstate = PyGILState_Ensure(); pyfunc = PyUnicode_FromString(func_name); if (!pyfunc) { - if (pyval) Py_XDECREF(pyval); - PyGILState_Release(gstate); - return PCILIB_ERROR_MEMORY; + if (pyval) Py_DECREF(pyval); + PyGILState_Release(gstate); + return PCILIB_ERROR_MEMORY; } pyret = PyObject_CallMethodObjArgs(module->module, pyfunc, ctx->py->pcilib_pywrap, pyval, NULL); - Py_XDECREF(pyfunc); - Py_XDECREF(pyval); + Py_DECREF(pyfunc); + Py_DECREF(pyval); if (!pyret) { - PyGILState_Release(gstate); - pcilib_python_error("Error executing function (%s) of python script (%s)", func_name, script_name); - return PCILIB_ERROR_FAILED; + PyGILState_Release(gstate); + pcilib_python_error("Error executing function (%s) of python script (%s)", func_name, script_name); + return PCILIB_ERROR_FAILED; } if ((val)&&(pyret != Py_None)) - err = pcilib_set_value_from_pyobject(ctx, val, pyret); + err = pcilib_set_value_from_pyobject(ctx, val, pyret); - Py_XDECREF(pyret); + Py_DECREF(pyret); PyGILState_Release(gstate); return err; |