diff options
Diffstat (limited to 'pcilib/py.c')
-rw-r--r-- | pcilib/py.c | 187 |
1 files changed, 183 insertions, 4 deletions
diff --git a/pcilib/py.c b/pcilib/py.c index 13113d7..20b85a1 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -16,11 +16,18 @@ struct pcilib_py_s { PyObject *global_dict; }; +struct pcilib_script_s { + PyObject *py_script_module; /**< PyModule object, contains script enviroment */ + PyObject *dict; + char* script_name; +}; + int pcilib_init_py(pcilib_t *ctx) { ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; - Py_Initialize(); + if(!Py_IsInitialized()) + Py_Initialize(); ctx->py->main_module = PyImport_AddModule("__parser__"); if (!ctx->py->main_module) @@ -35,12 +42,11 @@ int pcilib_init_py(pcilib_t *ctx) { void pcilib_free_py(pcilib_t *ctx) { if (ctx->py) { - // Dict and module references are borrowed + // Dict and module references are borrowed free(ctx->py); ctx->py = NULL; } - - Py_Finalize(); + //Py_Finalize(); } /* @@ -189,3 +195,176 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code); return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } + + +int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode) +{ + int err; + + //Initialize python script, if it has not initialized already. + if(!module_name) + { + pcilib_error("Invalid script name specified in XML property (NULL)"); + return PCILIB_ERROR_INVALID_DATA; + } + + //create path string to scripts + char* model_dir = getenv("PCILIB_MODEL_DIR"); + char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2); + if (!model_path) return PCILIB_ERROR_MEMORY; + sprintf(model_path, "%s/%s", model_dir, ctx->model); + + //set model path to python + PySys_SetPath(model_path); + free(model_path); + model_path = NULL; + + //create path string to pcipywrap library + char* app_dir = getenv("APP_PATH"); + char* pcipywrap_path; + if(app_dir) + { + pcipywrap_path = malloc(strlen(app_dir) + strlen("/pcilib")); + if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; + sprintf(pcipywrap_path, "%s/%s", "/pcilib", ctx->model); + } + else + { + pcipywrap_path = malloc(strlen("./pcilib")); + if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; + sprintf(pcipywrap_path, "%s", "./pcilib"); + + } + + //set pcipywrap library path to python + PyObject* path = PySys_GetObject("path"); + if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1) + { + pcilib_error("Cant set pcipywrap library path to python."); + return PCILIB_ERROR_FAILED; + } + free(pcipywrap_path); + pcipywrap_path = NULL; + + + //extract module name from script name + char* py_module_name = strtok(module_name, "."); + + if(!py_module_name) + { + pcilib_error("Invalid script name specified in XML property (%s)." + " Seems like name doesnt contains extension", module_name); + return PCILIB_ERROR_INVALID_DATA; + } + + //import python script + PyObject* py_script_module = PyImport_ImportModule(py_module_name); + + if(!py_script_module) + { + printf("Error in import python module: "); + PyErr_Print(); + return PCILIB_ERROR_INVALID_DATA; + } + + + //Initializing pcipywrap module if script use it + PyObject* dict = PyModule_GetDict(py_script_module); + if(PyDict_Contains(dict, PyString_FromString("pcipywrap"))) + { + PyObject* pcipywrap_module = PyDict_GetItemString(dict, "pcipywrap"); + if(!pcipywrap_module) + { + pcilib_error("Cant extract pcipywrap module from script dictionary"); + return PCILIB_ERROR_FAILED; + } + + //setting pcilib_t instance + PyObject_CallMethodObjArgs(pcipywrap_module, + PyUnicode_FromString("setPcilib"), + PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)), + NULL); + } + + //Success. Create struct and initialize values + module[0] = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); + module[0]->py_script_module = py_script_module; + module[0]->script_name = module_name; + module[0]->dict = dict; + + //Setting correct mode + mode[0] = 0; + if(PyDict_Contains(dict, PyString_FromString("read_from_register"))) + mode[0] |= PCILIB_ACCESS_R; + if(PyDict_Contains(dict, PyString_FromString("write_to_register"))) + mode[0] |= PCILIB_ACCESS_W; + + return 0; +} + +int pcilib_free_py_script(pcilib_script_t *module) +{ + if(module) + { + if(module->script_name) + { + free(module->script_name); + module->script_name = NULL; + } + + if(module->py_script_module) + { + //PyObject_Free(module->py_script_module); + module->py_script_module = NULL; + } + } +} + +int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +{ + + int err; + + PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()"); + if (!ret) + { + printf("Python script error: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + + err = pcilib_convert_pyobject_to_val(ctx, ret, val); + + if(err) + { + pcilib_error("Failed to convert python script return value to internal type: %i", err); + return err; + } + return 0; +} + +int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +{ + int err; + + PyObject *input = pcilib_convert_val_to_pyobject(ctx, val, printf); + if(!input) + { + printf("Failed to convert input value to Python object"); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + + PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, + PyUnicode_FromString("write_to_register"), + input, + NULL); + if (!ret) + { + printf("Python script error: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + + return 0; +} |