summaryrefslogtreecommitdiffstats
path: root/pcilib
diff options
context:
space:
mode:
authorVasilii Chernov <vchernov@inr.ru>2016-03-01 10:42:40 +0100
committerVasilii Chernov <vchernov@inr.ru>2016-03-01 10:42:40 +0100
commit5d775d64bdec554b9842823bd1c46263210425fd (patch)
treecb1da12066687273f7dccace7aba4ee1ff2ba25c /pcilib
parent0e584d07a0776454fd5487b7d23407c0624b56c2 (diff)
downloadpcitool-5d775d64bdec554b9842823bd1c46263210425fd.tar.gz
pcitool-5d775d64bdec554b9842823bd1c46263210425fd.tar.bz2
pcitool-5d775d64bdec554b9842823bd1c46263210425fd.tar.xz
pcitool-5d775d64bdec554b9842823bd1c46263210425fd.zip
1. multithreading:
- Enable multiprocessing for api_server - Enable mutrithreading for html_server 2. py: - extract pcilib->py bases from pcilib->py functions - add api for interact directly with pcilib->py without pcilib context. 3. pcipywrap - Add scripts handling.
Diffstat (limited to 'pcilib')
-rw-r--r--pcilib/locking.c207
-rw-r--r--pcilib/property.c4
-rw-r--r--pcilib/py.c309
-rw-r--r--pcilib/py.h26
4 files changed, 355 insertions, 191 deletions
diff --git a/pcilib/locking.c b/pcilib/locking.c
index 71f204e..28aa4c4 100644
--- a/pcilib/locking.c
+++ b/pcilib/locking.c
@@ -102,118 +102,117 @@ pcilib_lock_t *pcilib_get_lock_by_id(pcilib_t *ctx, pcilib_lock_id_t id) {
}
pcilib_lock_t *pcilib_get_lock(pcilib_t *ctx, pcilib_lock_flags_t flags, const char *lock_id, ...) {
- pcilib_lock_id_t i;
- int err, ret;
-
- pcilib_lock_t *lock;
- char buffer[PCILIB_LOCK_SIZE];
-
- /* we construct the complete lock_id given the parameters of the function*/
- va_list pa;
- va_start(pa, lock_id);
- ret = vsnprintf(buffer, PCILIB_LOCK_SIZE, lock_id, pa);
- va_end(pa);
-
- if (ret < 0) {
- pcilib_error("Failed to construct the lock id, probably arguments does not match the format string (%s)...", lock_id);
- return NULL;
- }
-
-
- /* we iterate through locks to see if there is one already with the same name*/
- // Would be nice to have hash here
- for (i = 0; i < PCILIB_MAX_LOCKS; i++) {
- lock = pcilib_get_lock_by_id(ctx, i);
-
- const char *name = pcilib_lock_get_name(lock);
- if (!name) break;
-
- if (!strcmp(buffer, name)) {
- if ((pcilib_lock_get_flags(lock)&PCILIB_LOCK_FLAG_PERSISTENT) != (flags&PCILIB_LOCK_FLAG_PERSISTENT)) {
- if (flags&PCILIB_LOCK_FLAG_PERSISTENT)
- pcilib_error("Requesting persistent lock (%s), but requested lock is already existing and is robust", name);
- else
- pcilib_error("Requesting robust lock (%s), but requested lock is already existing and is persistent", name);
- return NULL;
- }
-
-#ifndef HAVE_STDATOMIC_H
- if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0) {
- err = pcilib_lock(ctx->locks.locking);
- if (err) {
- pcilib_error("Error (%i) obtaining global lock", err);
- return NULL;
- }
- }
-#endif /* ! HAVE_STDATOMIC_H */
- /* if yes, we increment its ref variable*/
- pcilib_lock_ref(lock);
-#ifndef HAVE_STDATOMIC_H
- if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
- pcilib_unlock(ctx->locks.locking);
-#endif /* ! HAVE_STDATOMIC_H */
-
- return lock;
- }
- }
+ pcilib_lock_id_t i;
+ int err, ret;
- if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0) {
- err = pcilib_lock(ctx->locks.locking);
- if (err) {
- pcilib_error("Error (%i) obtaining global lock", err);
- return NULL;
- }
- }
+ pcilib_lock_t *lock;
+ char buffer[PCILIB_LOCK_SIZE];
- // Make sure it was not allocated meanwhile
- for (; i < PCILIB_MAX_LOCKS; i++) {
- lock = pcilib_get_lock_by_id(ctx, i);
-
- const char *name = pcilib_lock_get_name(lock);
- if (!name) break;
+ /* we construct the complete lock_id given the parameters of the function*/
+ va_list pa;
+ va_start(pa, lock_id);
+ ret = vsnprintf(buffer, PCILIB_LOCK_SIZE, lock_id, pa);
+ va_end(pa);
- if (!strcmp(buffer, name)) {
- if ((pcilib_lock_get_flags(lock)&PCILIB_LOCK_FLAG_PERSISTENT) != (flags&PCILIB_LOCK_FLAG_PERSISTENT)) {
- if (flags&PCILIB_LOCK_FLAG_PERSISTENT)
- pcilib_error("Requesting persistent lock (%s), but requested lock is already existing and is robust", name);
- else
- pcilib_error("Requesting robust lock (%s), but requested lock is already existing and is persistent", name);
-
- if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
- pcilib_unlock(ctx->locks.locking);
- return NULL;
- }
+ if (ret < 0) {
+ pcilib_error("Failed to construct the lock id, probably arguments does not match the format string (%s)...", lock_id);
+ return NULL;
+ }
- pcilib_lock_ref(lock);
- if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
- pcilib_unlock(ctx->locks.locking);
- return lock;
- }
- }
- if (i == PCILIB_MAX_LOCKS) {
- if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
- pcilib_unlock(ctx->locks.locking);
- pcilib_error("Failed to create lock (%s), only %u locks is supported", buffer, PCILIB_MAX_LOCKS);
- return NULL;
- }
+ /* we iterate through locks to see if there is one already with the same name*/
+ // Would be nice to have hash here
+ for (i = 0; i < PCILIB_MAX_LOCKS; i++) {
+ lock = pcilib_get_lock_by_id(ctx, i);
- /* if the lock did not exist before, then we create it*/
- err = pcilib_init_lock(lock, flags, buffer);
-
- if (err) {
- pcilib_error("Lock initialization failed with error %i", err);
+ const char *name = pcilib_lock_get_name(lock);
+ if (!name) break;
- if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
- pcilib_unlock(ctx->locks.locking);
-
- return NULL;
- }
-
- if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
- pcilib_unlock(ctx->locks.locking);
+ if (!strcmp(buffer, name)) {
+ if ((pcilib_lock_get_flags(lock)&PCILIB_LOCK_FLAG_PERSISTENT) != (flags&PCILIB_LOCK_FLAG_PERSISTENT)) {
+ if (flags&PCILIB_LOCK_FLAG_PERSISTENT)
+ pcilib_error("Requesting persistent lock (%s), but requested lock is already existing and is robust", name);
+ else
+ pcilib_error("Requesting robust lock (%s), but requested lock is already existing and is persistent", name);
+ return NULL;
+ }
- return lock;
+#ifndef HAVE_STDATOMIC_H
+ if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0) {
+ err = pcilib_lock(ctx->locks.locking);
+ if (err) {
+ pcilib_error("Error (%i) obtaining global lock", err);
+ return NULL;
+ }
+ }
+#endif /* ! HAVE_STDATOMIC_H */
+ /* if yes, we increment its ref variable*/
+ pcilib_lock_ref(lock);
+ #ifndef HAVE_STDATOMIC_H
+ if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+ pcilib_unlock(ctx->locks.locking);
+ #endif /* ! HAVE_STDATOMIC_H */
+ return lock;
+ }
+ }
+
+ if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0) {
+ err = pcilib_lock(ctx->locks.locking);
+ if (err) {
+ pcilib_error("Error (%i) obtaining global lock", err);
+ return NULL;
+ }
+ }
+
+ // Make sure it was not allocated meanwhile
+ for (; i < PCILIB_MAX_LOCKS; i++) {
+ lock = pcilib_get_lock_by_id(ctx, i);
+
+ const char *name = pcilib_lock_get_name(lock);
+ if (!name) break;
+
+ if (!strcmp(buffer, name)) {
+ if ((pcilib_lock_get_flags(lock)&PCILIB_LOCK_FLAG_PERSISTENT) != (flags&PCILIB_LOCK_FLAG_PERSISTENT)) {
+ if (flags&PCILIB_LOCK_FLAG_PERSISTENT)
+ pcilib_error("Requesting persistent lock (%s), but requested lock is already existing and is robust", name);
+ else
+ pcilib_error("Requesting robust lock (%s), but requested lock is already existing and is persistent", name);
+
+ if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+ pcilib_unlock(ctx->locks.locking);
+ return NULL;
+ }
+
+ pcilib_lock_ref(lock);
+ if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+ pcilib_unlock(ctx->locks.locking);
+ return lock;
+ }
+ }
+
+ if (i == PCILIB_MAX_LOCKS) {
+ if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+ pcilib_unlock(ctx->locks.locking);
+ pcilib_error("Failed to create lock (%s), only %u locks is supported", buffer, PCILIB_MAX_LOCKS);
+ return NULL;
+ }
+
+ /* if the lock did not exist before, then we create it*/
+ err = pcilib_init_lock(lock, flags, buffer);
+
+ if (err) {
+ pcilib_error("Lock initialization failed with error %i", err);
+
+ if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+ pcilib_unlock(ctx->locks.locking);
+
+ return NULL;
+ }
+
+ if ((flags&PCILIB_LOCK_FLAG_UNLOCKED)==0)
+ pcilib_unlock(ctx->locks.locking);
+
+ return lock;
}
void pcilib_return_lock(pcilib_t *ctx, pcilib_lock_flags_t flags, pcilib_lock_t *lock) {
diff --git a/pcilib/property.c b/pcilib/property.c
index dfab9a6..1dba1be 100644
--- a/pcilib/property.c
+++ b/pcilib/property.c
@@ -226,8 +226,8 @@ pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *bran
}
HASH_ITER(hh, dir_hash, dir, dir_tmp) {
- HASH_DEL(dir_hash, dir);
- free(dir);
+ HASH_DEL(dir_hash, dir);
+ free(dir);
}
HASH_CLEAR(hh, dir_hash);
diff --git a/pcilib/py.c b/pcilib/py.c
index 6cf9fdc..934c11f 100644
--- a/pcilib/py.c
+++ b/pcilib/py.c
@@ -89,8 +89,6 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag
#endif /* HAVE_PYTHON */
}
-
-
int pcilib_init_py(pcilib_t *ctx) {
#ifdef HAVE_PYTHON
ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
@@ -143,8 +141,6 @@ int pcilib_init_py(pcilib_t *ctx) {
int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
#ifdef HAVE_PYTHON
int err = 0;
- PyObject *pypath, *pynewdir;
- PyObject *pydict, *pystr, *pyret = NULL;
char *script_dir;
const char *model_dir = getenv("PCILIB_MODEL_DIR");
@@ -160,83 +156,59 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
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;
- }
+ err = pcilib_py_ctx_add_script_dir(ctx->py, script_dir);
+ if(err) return err;
+#endif /* HAVE_PYTHON */
- pynewdir = PyString_FromString(script_dir);
- if (!pynewdir) {
- pcilib_python_error("Can't create python string");
- return PCILIB_ERROR_MEMORY;
+ return 0;
+}
+
+void pcilib_py_free_hash(pcilib_py_t *ctx_py) {
+ 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;
}
-
- // 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);
- }
+void pcilib_free_py_ctx(pcilib_py_t *ctx_py) {
+#ifdef HAVE_PYTHON
+ int finalyze = 0;
- pyret = PyRun_String("cur in path", Py_eval_input, ctx->py->global_dict, pydict);
- Py_DECREF(pydict);
- }
+ if (ctx_py) {
+ if (ctx_py->finalyze) finalyze = 1;
- if ((pyret == Py_False)&&(PyList_Append(pypath, pynewdir) == -1))
- err = PCILIB_ERROR_FAILED;
+ pcilib_py_free_hash(ctx_py);
- if (pyret) Py_DECREF(pyret);
- Py_DECREF(pynewdir);
+ if (ctx_py->pcilib_pywrap)
+ Py_DECREF(ctx_py->pcilib_pywrap);
- if (err) {
- pcilib_python_error("Can't add directory (%s) to python path", script_dir);
- return err;
- }
-#endif /* HAVE_PYTHON */
+ free(ctx_py);
+ }
- return 0;
+ if (finalyze)
+ Py_Finalize();
+#endif /* HAVE_PYTHON */
}
+
void pcilib_free_py(pcilib_t *ctx) {
#ifdef HAVE_PYTHON
- 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);
-
- free(ctx->py);
- ctx->py = NULL;
- }
-
- if (finalyze)
- Py_Finalize();
+ pcilib_free_py_ctx(ctx->py);
+ ctx->py = NULL;
#endif /* HAVE_PYTHON */
}
int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
+ return pcilib_py_ctx_load_script(ctx->py, script_name);
+}
+
+int pcilib_py_ctx_load_script(pcilib_py_t *ctx_py, const char *script_name) {
#ifdef HAVE_PYTHON
PyObject* pymodule;
pcilib_script_t *module = NULL;
@@ -252,7 +224,7 @@ int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
}
*py = 0;
- HASH_FIND_STR(ctx->py->script_hash, script_name, module);
+ HASH_FIND_STR(ctx_py->script_hash, script_name, module);
if (module) return 0;
pymodule = PyImport_ImportModule(module_name);
@@ -266,7 +238,7 @@ int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
module->module = pymodule;
module->name = script_name;
- HASH_ADD_KEYPTR(hh, ctx->py->script_hash, module->name, strlen(module->name), module);
+ HASH_ADD_STR(ctx_py->script_hash, name, module);
#endif /* HAVE_PYTHON */
return 0;
}
@@ -527,51 +499,218 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va
int pcilib_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func_name, pcilib_value_t *val) {
#ifdef HAVE_PYTHON
int err = 0;
+ PyObject *pyval = NULL;
+
+ if (val) {
+ pyval = pcilib_get_value_as_pyobject(ctx, val, &err);
+ if (err) return err;
+ }
+
+ PyObject* pyret = pcilib_py_ctx_eval_func(ctx->py, script_name,
+ func_name, pyval, &err);
+ if (err) return err;
+
+ if ((val)&&(pyret != Py_None))
+ err = pcilib_set_value_from_pyobject(ctx, val, pyret);
+
+ Py_DECREF(pyret);
+
+ return err;
+#else /* HAVE_PYTHON */
+ pcilib_error("Python is not supported");
+ return PCILIB_ERROR_NOTSUPPORTED;
+#endif /* HAVE_PYTHON */
+}
+
+pcilib_py_object* pcilib_py_ctx_eval_func(pcilib_py_t *ctx_py,
+ const char *script_name,
+ const char *func_name,
+ pcilib_py_object *pyval,
+ int *err) {
+#ifdef HAVE_PYTHON
PyObject *pyfunc;
- PyObject *pyval = NULL, *pyret;
+ PyObject *pyret;
pcilib_script_t *module = NULL;
- HASH_FIND_STR(ctx->py->script_hash, script_name, module);
+ 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;
- }
-
- if (val) {
- pyval = pcilib_get_value_as_pyobject(ctx, val, &err);
- if (err) return err;
+ if(err) *err = PCILIB_ERROR_NOTFOUND;
+ return NULL;
}
-
+
PyGILState_STATE gstate = PyGILState_Ensure();
pyfunc = PyUnicode_FromString(func_name);
if (!pyfunc) {
if (pyval) Py_DECREF(pyval);
PyGILState_Release(gstate);
- return PCILIB_ERROR_MEMORY;
+ if(err) *err = PCILIB_ERROR_MEMORY;
+ return NULL;
}
- pyret = PyObject_CallMethodObjArgs(module->module, pyfunc, ctx->py->pcilib_pywrap, pyval, NULL);
+ pyret = PyObject_CallMethodObjArgs(module->module,
+ pyfunc,
+ ctx_py->pcilib_pywrap,
+ pyval,
+ NULL);
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);
+ pcilib_python_error("Error executing function (%s) of python "
+ "script (%s)", func_name, script_name);
+ if(err) *err = PCILIB_ERROR_FAILED;
+ return NULL;
+ }
+ PyGILState_Release(gstate);
+
+ return pyret;
+
+#else /* HAVE_PYTHON */
+ pcilib_error("Python is not supported");
+ if(err) *err = PCILIB_ERROR_NOTSUPPORTED;
+ return NULL;
+#endif /* HAVE_PYTHON */
+}
+
+int pcilib_py_ctx_add_script_dir(pcilib_py_t *ctx_py, const char *dir) {
+#ifdef HAVE_PYTHON
+ int err = 0;
+ PyObject *pypath, *pynewdir;
+ PyObject *pydict, *pystr, *pyret = NULL;
+
+ //const char *model_dir = getenv("PCILIB_MODEL_DIR");
+ //if (!model_dir) model_dir = PCILIB_MODEL_DIR;
+
+ pypath = PySys_GetObject("path");
+ if (!pypath) {
+ pcilib_python_error("Can't get python path");
return PCILIB_ERROR_FAILED;
}
- if ((val)&&(pyret != Py_None))
- err = pcilib_set_value_from_pyobject(ctx, val, pyret);
+ pynewdir = PyString_FromString(dir);
+ if (!pynewdir) {
+ pcilib_python_error("Can't create python string");
+ return PCILIB_ERROR_MEMORY;
+ }
- Py_DECREF(pyret);
- PyGILState_Release(gstate);
+ // 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);
+ } else {
+ pcilib_python_error("Can't create python string");
+ return PCILIB_ERROR_MEMORY;
+ }
- return err;
+ pystr = PyString_FromString("path");
+ if (pystr) {
+ PyDict_SetItem(pydict, pystr, pypath);
+ Py_DECREF(pystr);
+ } else {
+ pcilib_python_error("Can't create python string");
+ return PCILIB_ERROR_MEMORY;
+ }
+
+ pyret = PyRun_String("cur in path", Py_eval_input, ctx_py->global_dict, pydict);
+ Py_DECREF(pydict);
+
+ } else {
+ pcilib_python_error("Can't create python dict");
+ return PCILIB_ERROR_MEMORY;
+ }
+
+ 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", dir);
+ return err;
+ }
+ return 0;
#else /* HAVE_PYTHON */
pcilib_error("Python is not supported");
return PCILIB_ERROR_NOTSUPPORTED;
#endif /* HAVE_PYTHON */
}
+
+pcilib_py_t* pcilib_init_py_ctx(pcilib_py_t* in, int *err) {
+ pcilib_py_t* out = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
+ if (!out) {
+ if(err) *err = PCILIB_ERROR_MEMORY;
+ return NULL;
+ }
+
+ out->finalyze = 0;
+ out->main_module = in->main_module;
+ out->global_dict = in->global_dict;
+ out->pcilib_pywrap = in->pcilib_pywrap;
+ out->script_hash = NULL;
+
+ if(err) *err = 0;
+ return out;
+}
+
+/*!
+ * \brief Wrap for PyDict_SetItem, with decrease reference counting after set.
+ */
+void pcilib_pydict_set_item(pcilib_py_object* dict, pcilib_py_object* name, pcilib_py_object* value)
+{
+ PyDict_SetItem(dict,
+ name,
+ value);
+ Py_XDECREF(name);
+ Py_XDECREF(value);
+}
+
+/*!
+ * \brief Wrap for PyList_Append, with decrease reference counting after append.
+ */
+void pcilib_pylist_append(pcilib_py_object* list, pcilib_py_object* value)
+{
+ PyList_Append(list, value);
+ Py_XDECREF(value);
+}
+
+pcilib_py_object *pcilib_py_ctx_get_scripts_info(pcilib_py_t *ctx_py) {
+
+ PyObject* pyList = PyList_New(0);
+
+ if (ctx_py->script_hash) {
+ pcilib_script_t *script, *script_tmp;
+
+ HASH_ITER(hh, ctx_py->script_hash, script, script_tmp) {
+
+ PyObject* pylistItem = PyDict_New();
+ pcilib_pydict_set_item(pylistItem,
+ PyString_FromString("name"),
+ PyString_FromString(script->name));
+
+ PyObject* dict = PyModule_GetDict(script->module);
+ if (dict) {
+ PyObject* pystr = PyString_FromString("description");
+ if (pystr) {
+ if (PyDict_Contains(dict, pystr)) {
+ PyDict_SetItem(pylistItem,
+ pystr,
+ PyDict_GetItem(dict, pystr));
+ }
+ Py_DECREF(pystr);
+ }
+ }
+ pcilib_pylist_append(pyList, pylistItem);
+
+ }
+ }
+ return pyList;
+}
diff --git a/pcilib/py.h b/pcilib/py.h
index c372a09..549eddf 100644
--- a/pcilib/py.h
+++ b/pcilib/py.h
@@ -118,6 +118,32 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va
*/
int pcilib_py_eval_func(pcilib_t *ctx, const char *script, const char *func, pcilib_value_t *val);
+
+/** Clone pcilib_py_t content without scripts hash
+ * @param[in] in - pcilib_py_t content to clone
+ * @param[out] err - error
+ * @return - NULL or cloned pcilib_py_t content pointer on success
+ */
+pcilib_py_t* pcilib_init_py_ctx(pcilib_py_t* in, int *err);
+pcilib_py_object* pcilib_py_ctx_eval_func(pcilib_py_t *ctx_py,
+ const char *script_name,
+ const char *func_name,
+ pcilib_py_object *pyval,
+ int *err);
+int pcilib_py_ctx_add_script_dir(pcilib_py_t *ctx_py, const char *dir);
+void pcilib_free_py_ctx(pcilib_py_t *ctx_py);
+int pcilib_py_ctx_load_script(pcilib_py_t *ctx_py, const char *script_name);
+pcilib_py_object *pcilib_py_ctx_get_scripts_info(pcilib_py_t *ctx_py);
+
+/*!
+ * \brief Wrap for PyDict_SetItem, with decrease reference counting after set.
+ */
+void pcilib_pydict_set_item(pcilib_py_object* dict, pcilib_py_object* name, pcilib_py_object* value);
+
+/*!
+ * \brief Wrap for PyList_Append, with decrease reference counting after append.
+ */
+void pcilib_pylist_append(pcilib_py_object* list, pcilib_py_object* value);
#ifdef __cplusplus
}
#endif