bzr branch
http://suren.me/webbzr/alps/pcitool
354
by Suren A. Chilingaryan
Stabilize merged code |
1 |
#include "config.h" |
2 |
||
3 |
#ifdef HAVE_PYTHON
|
|
4 |
# include <Python.h>
|
|
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
5 |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
6 |
# if PY_MAJOR_VERSION >= 3
|
7 |
# include <pthread.h>
|
|
8 |
# endif /* PY_MAJOR_VERSION >= 3 */ |
|
354
by Suren A. Chilingaryan
Stabilize merged code |
9 |
#endif /* HAVE_PYTHON */ |
10 |
||
309
by Suren A. Chilingaryan
Base functions for views |
11 |
#include <stdio.h> |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
12 |
#include <stdlib.h> |
309
by Suren A. Chilingaryan
Base functions for views |
13 |
#include <string.h> |
14 |
#include <strings.h> |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
15 |
#include <alloca.h> |
309
by Suren A. Chilingaryan
Base functions for views |
16 |
|
17 |
#include "pci.h" |
|
314
by Suren A. Chilingaryan
Support writting register views |
18 |
#include "debug.h" |
309
by Suren A. Chilingaryan
Base functions for views |
19 |
#include "pcilib.h" |
20 |
#include "py.h" |
|
21 |
#include "error.h" |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
22 |
|
23 |
#ifdef HAVE_PYTHON
|
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
24 |
# define PCILIB_PYTHON_WRAPPER "pcipywrap"
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
25 |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
26 |
typedef struct pcilib_script_s pcilib_script_t; |
27 |
||
28 |
struct pcilib_script_s { |
|
29 |
const char *name; /**< Script name */ |
|
30 |
PyObject *module; /**< PyModule object, contains script enviroment */ |
|
31 |
UT_hash_handle hh; /**< hash */ |
|
32 |
};
|
|
346.1.10
by Vasilii Chernov
1. Cmakelists - move copy xml folder command to root file |
33 |
|
309
by Suren A. Chilingaryan
Base functions for views |
34 |
struct pcilib_py_s { |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
35 |
int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */ |
36 |
PyObject *main_module; /**< Main interpreter */ |
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
37 |
PyObject *pywrap_module; /**< Pcilib python wrapper */ |
38 |
PyObject *threading_module; /**< Threading module */ |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
39 |
PyObject *global_dict; /**< Dictionary of main interpreter */ |
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
40 |
PyObject *pcilib_pywrap; /**< pcilib wrapper context */ |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
41 |
pcilib_script_t *script_hash; /**< Hash with loaded scripts */ |
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
42 |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
43 |
# if PY_MAJOR_VERSION >= 3
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
44 |
int status; /**< Indicates if python was initialized successfuly (0) or error have occured */ |
45 |
pthread_t pth; /**< Helper thread for Python initialization */ |
|
46 |
pthread_cond_t cond; /**< Condition informing about initialization success and request for clean-up */ |
|
47 |
pthread_mutex_t lock; /**< Condition lock */ |
|
48 |
||
49 |
// PyInterpreterState *istate;
|
|
50 |
// PyThreadState *tstate;
|
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
51 |
# endif /* PY_MAJOR_VERSION > 3 */ |
309
by Suren A. Chilingaryan
Base functions for views |
52 |
};
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
53 |
#endif /* HAVE_PYTHON */ |
54 |
||
55 |
void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...) { |
|
56 |
va_list va; |
|
57 |
const char *type = NULL; |
|
58 |
const char *val = NULL; |
|
59 |
||
60 |
#ifdef HAVE_PYTHON
|
|
354
by Suren A. Chilingaryan
Stabilize merged code |
61 |
PyGILState_STATE gstate; |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
62 |
PyObject *pytype = NULL; |
63 |
PyObject *pyval = NULL; |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
64 |
PyObject *pystr = NULL; |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
65 |
PyObject *pytraceback = NULL; |
66 |
||
354
by Suren A. Chilingaryan
Stabilize merged code |
67 |
|
68 |
gstate = PyGILState_Ensure(); |
|
69 |
if (PyErr_Occurred()) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
70 |
PyErr_Fetch(&pytype, &pyval, &pytraceback); |
71 |
PyErr_NormalizeException(&pytype, &pyval, &pytraceback); |
|
72 |
if (pyval) pystr = PyObject_Str(pyval); |
|
346.1.35
by Vasilii Chernov
Add Python3 support |
73 |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
74 |
# if PY_MAJOR_VERSION >= 3
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
75 |
if (pytype) { |
76 |
if (PyUnicode_Check(pytype)) |
|
77 |
type = PyUnicode_AsUTF8(pytype); |
|
78 |
else
|
|
79 |
type = PyExceptionClass_Name(pytype); |
|
80 |
}
|
|
81 |
if (pystr) { |
|
82 |
val = PyUnicode_AsUTF8(pystr); |
|
83 |
}
|
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
84 |
# else /* PY_MAJOR_VERSION >= 3 */ |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
85 |
if (pytype) { |
86 |
if (PyString_Check(pytype)) |
|
87 |
type = PyString_AsString(pytype); |
|
88 |
else
|
|
89 |
type = PyExceptionClass_Name(pytype); |
|
90 |
}
|
|
91 |
if (pystr) { |
|
92 |
val = PyString_AsString(pystr); |
|
93 |
}
|
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
94 |
# endif /*PY_MAJOR_VERSION >= 3*/ |
354
by Suren A. Chilingaryan
Stabilize merged code |
95 |
}
|
96 |
PyGILState_Release(gstate); |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
97 |
#endif /* HAVE_PYTHON */ |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
98 |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
99 |
va_start(va, msg); |
100 |
if (type) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
101 |
char *str; |
102 |
size_t len = 32; |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
103 |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
104 |
if (msg) len += strlen(msg); |
105 |
if (type) len += strlen(type); |
|
106 |
if (val) len += strlen(val); |
|
107 |
||
108 |
str = alloca(len * sizeof(char)); |
|
109 |
if (str) { |
|
110 |
if (msg&&val) |
|
111 |
sprintf(str, "%s <%s: %s>", msg, type, val); |
|
112 |
else if (msg) |
|
113 |
sprintf(str, "%s <%s>", msg, type); |
|
114 |
else if (val) |
|
115 |
sprintf(str, "Python error %s: %s", type, val); |
|
116 |
else
|
|
117 |
sprintf(str, "Python error %s", type); |
|
118 |
||
119 |
pcilib_log_vmessage(file, line, flags, prio, str, va); |
|
120 |
}
|
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
121 |
} else { |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
122 |
pcilib_log_vmessage(file, line, flags, prio, msg, va); |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
123 |
}
|
124 |
va_end(va); |
|
125 |
||
126 |
#ifdef HAVE_PYTHON
|
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
127 |
if (pystr) Py_DECREF(pystr); |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
128 |
if (pytype) Py_DECREF(pytype); |
129 |
if (pyval) Py_DECREF(pyval); |
|
130 |
if (pytraceback) Py_DECREF(pytraceback); |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
131 |
#endif /* HAVE_PYTHON */ |
132 |
}
|
|
133 |
||
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
134 |
#ifdef HAVE_PYTHON
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
135 |
static int pcilib_py_load_default_modules(pcilib_t *ctx) { |
136 |
PyGILState_STATE gstate = PyGILState_Ensure(); |
|
137 |
||
138 |
ctx->py->main_module = PyImport_AddModule("__parser__"); |
|
139 |
if (!ctx->py->main_module) { |
|
140 |
PyGILState_Release(gstate); |
|
141 |
pcilib_python_warning("Error importing python parser"); |
|
142 |
return PCILIB_ERROR_FAILED; |
|
143 |
}
|
|
144 |
||
145 |
ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); |
|
146 |
if (!ctx->py->global_dict) { |
|
147 |
PyGILState_Release(gstate); |
|
148 |
pcilib_python_warning("Error locating global python dictionary"); |
|
149 |
return PCILIB_ERROR_FAILED; |
|
150 |
}
|
|
151 |
||
152 |
ctx->py->pywrap_module = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER); |
|
153 |
if (!ctx->py->pywrap_module) { |
|
154 |
PyGILState_Release(gstate); |
|
155 |
pcilib_python_warning("Error importing pcilib python wrapper"); |
|
156 |
return PCILIB_ERROR_FAILED; |
|
157 |
}
|
|
158 |
||
159 |
/**
|
|
160 |
* We need to load threading module here, otherwise if any of the scripts
|
|
161 |
* will use threading, on cleanup Python3 will complain:
|
|
162 |
* Exception KeyError: KeyError(140702199305984,) in <module 'threading' from '/usr/lib64/python3.3/threading.py'> ignored
|
|
163 |
* The idea to load threading module is inspired by
|
|
164 |
* http://stackoverflow.com/questions/8774958/keyerror-in-module-threading-after-a-successful-py-test-run
|
|
165 |
*/
|
|
166 |
ctx->py->threading_module = PyImport_ImportModule("threading"); |
|
167 |
if (!ctx->py->threading_module) { |
|
168 |
PyGILState_Release(gstate); |
|
169 |
pcilib_python_warning("Error importing threading python module"); |
|
170 |
return PCILIB_ERROR_FAILED; |
|
171 |
}
|
|
172 |
||
173 |
PyObject *mod_name = PyUnicode_FromString(PCILIB_PYTHON_WRAPPER); |
|
174 |
PyObject *pyctx = PyCapsule_New(ctx, "pcilib", NULL); |
|
175 |
ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(ctx->py->pywrap_module, mod_name, pyctx, NULL); |
|
176 |
Py_XDECREF(pyctx); |
|
177 |
Py_XDECREF(mod_name); |
|
178 |
||
179 |
if (!ctx->py->pcilib_pywrap) { |
|
180 |
PyGILState_Release(gstate); |
|
181 |
pcilib_python_warning("Error initializing python wrapper"); |
|
182 |
return PCILIB_ERROR_FAILED; |
|
183 |
}
|
|
184 |
||
185 |
PyGILState_Release(gstate); |
|
186 |
return 0; |
|
187 |
}
|
|
188 |
||
189 |
static void pcilib_py_clean_default_modules(pcilib_t *ctx) { |
|
190 |
PyGILState_STATE gstate; |
|
191 |
||
192 |
gstate = PyGILState_Ensure(); |
|
193 |
||
194 |
if (ctx->py->pcilib_pywrap) Py_DECREF(ctx->py->pcilib_pywrap); |
|
195 |
||
196 |
if (ctx->py->threading_module) Py_DECREF(ctx->py->threading_module); |
|
197 |
if (ctx->py->pywrap_module) Py_DECREF(ctx->py->pywrap_module); |
|
198 |
||
199 |
// Crashes Python2
|
|
200 |
// if (ctx->py->main_module) Py_DECREF(ctx->py->main_module);
|
|
201 |
||
202 |
PyGILState_Release(gstate); |
|
203 |
}
|
|
204 |
||
205 |
||
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
206 |
# if PY_MAJOR_VERSION >= 3
|
207 |
/**
|
|
208 |
* Python3 specially treats the main thread intializing Python. It crashes if
|
|
209 |
* the Lock is released and any Python code is executed under the GIL compaling
|
|
210 |
* that GIL is not locked. Python3 assumes that the main thread most of the time
|
|
211 |
* holds the Lock, only shortly giving it away to other threads and re-obtaining
|
|
212 |
* it hereafter. This is not possible to do with GILs, but instead (probably)
|
|
213 |
* PyEval_{Save,Restore}Thread() should be used. On other hand, the other threads
|
|
214 |
* are working fine with GILs. This makes things complicated as we need to know
|
|
215 |
* if we are running in main thread or not.
|
|
216 |
* To simplify matters, during initalization we start a new thread which will
|
|
217 |
* performa actual initialization of Python and, hence, act as main thread.
|
|
218 |
* We only intialize here. No python code is executed afterwards. So we don't
|
|
219 |
* need to care about special locking mechanisms in main thread. Instead all
|
|
220 |
* our user threads can use GILs normally.
|
|
221 |
* See more details here:
|
|
222 |
* http://stackoverflow.com/questions/24499393/cpython-locking-the-gil-in-the-main-thread
|
|
223 |
* http://stackoverflow.com/questions/15470367/pyeval-initthreads-in-python-3-how-when-to-call-it-the-saga-continues-ad-naus
|
|
224 |
*/
|
|
225 |
static void *pcilib_py_run_init_thread(void *arg) { |
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
226 |
PyThreadState *state; |
227 |
pcilib_t *ctx = (pcilib_t*)arg; |
|
228 |
pcilib_py_t *py = ctx->py; |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
229 |
|
230 |
Py_Initialize(); |
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
231 |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
232 |
PyEval_InitThreads(); |
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
233 |
|
234 |
// state = PyThreadState_Get();
|
|
235 |
// py->istate = state->interp;
|
|
236 |
||
237 |
py->status = pcilib_py_load_default_modules(ctx); |
|
238 |
||
239 |
state = PyEval_SaveThread(); |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
240 |
|
241 |
// Ensure that main thread waiting for our signal
|
|
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
242 |
pthread_mutex_lock(&(py->lock)); |
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
243 |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
244 |
// Inform the parent thread that initialization is finished
|
245 |
pthread_cond_signal(&(py->cond)); |
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
246 |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
247 |
// Wait untill cleanup is requested
|
248 |
pthread_cond_wait(&(py->cond), &(py->lock)); |
|
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
249 |
pthread_mutex_unlock(&(py->lock)); |
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
250 |
|
251 |
PyEval_RestoreThread(state); |
|
252 |
pcilib_py_clean_default_modules(ctx); |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
253 |
Py_Finalize(); |
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
254 |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
255 |
return NULL; |
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
256 |
}
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
257 |
# endif /* PY_MAJOR_VERSION < 3 */ |
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
258 |
#endif /* HAVE_PYTHON */ |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
259 |
|
309
by Suren A. Chilingaryan
Base functions for views |
260 |
int pcilib_init_py(pcilib_t *ctx) { |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
261 |
#ifdef HAVE_PYTHON
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
262 |
int err = 0; |
263 |
||
309
by Suren A. Chilingaryan
Base functions for views |
264 |
ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); |
265 |
if (!ctx->py) return PCILIB_ERROR_MEMORY; |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
266 |
memset(ctx->py, 0, sizeof(pcilib_py_t)); |
267 |
||
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
268 |
if (!Py_IsInitialized()) { |
269 |
# if PY_MAJOR_VERSION < 3
|
|
270 |
Py_Initialize(); |
|
271 |
// Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads
|
|
272 |
PyEval_InitThreads(); |
|
273 |
PyEval_ReleaseLock(); |
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
274 |
|
275 |
err = pcilib_py_load_default_modules(ctx); |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
276 |
# else /* PY_MAJOR_VERSION < 3 */ |
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
277 |
int err = pthread_mutex_init(&(ctx->py->lock), NULL); |
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
278 |
if (err) return PCILIB_ERROR_FAILED; |
279 |
||
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
280 |
err = pthread_cond_init(&(ctx->py->cond), NULL); |
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
281 |
if (err) { |
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
282 |
pthread_mutex_destroy(&(ctx->py->lock)); |
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
283 |
return PCILIB_ERROR_FAILED; |
284 |
}
|
|
285 |
||
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
286 |
err = pthread_mutex_lock(&(ctx->py->lock)); |
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
287 |
if (err) { |
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
288 |
pthread_cond_destroy(&(ctx->py->cond)); |
289 |
pthread_mutex_destroy(&(ctx->py->lock)); |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
290 |
return PCILIB_ERROR_FAILED; |
291 |
}
|
|
292 |
||
293 |
// Create initalizer thread and wait until it releases the Lock
|
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
294 |
err = pthread_create(&(ctx->py->pth), NULL, pcilib_py_run_init_thread, (void*)ctx); |
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
295 |
if (err) { |
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
296 |
pthread_mutex_unlock(&(ctx->py->lock)); |
297 |
pthread_cond_destroy(&(ctx->py->cond)); |
|
298 |
pthread_mutex_destroy(&(ctx->py->lock)); |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
299 |
return PCILIB_ERROR_FAILED; |
300 |
}
|
|
301 |
||
302 |
// Wait until initialized and keep the lock afterwards until free executed
|
|
373
by Suren A. Chilingaryan
Fix compillation issues for Python3 |
303 |
pthread_cond_wait(&(ctx->py->cond), &(ctx->py->lock)); |
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
304 |
err = ctx->py->status; |
305 |
||
306 |
// ctx->py->tstate = PyThreadState_New(ctx->py->istate);
|
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
307 |
# endif /* PY_MAJOR_VERSION < 3 */ |
308 |
ctx->py->finalyze = 1; |
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
309 |
} else { |
310 |
err = pcilib_py_load_default_modules(ctx); |
|
311 |
}
|
|
312 |
||
313 |
if (err) { |
|
314 |
pcilib_free_py(ctx); |
|
315 |
return err; |
|
316 |
}
|
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
317 |
#endif /* HAVE_PYTHON */ |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
318 |
|
346.1.16
by Vasilii Chernov
1. Add cmake BUILD_PYTHON_MODULES option. |
319 |
return 0; |
320 |
}
|
|
321 |
||
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
322 |
void pcilib_free_py(pcilib_t *ctx) { |
323 |
#ifdef HAVE_PYTHON
|
|
324 |
if (ctx->py) { |
|
325 |
PyGILState_STATE gstate; |
|
326 |
||
327 |
gstate = PyGILState_Ensure(); |
|
328 |
if (ctx->py->script_hash) { |
|
329 |
pcilib_script_t *script, *script_tmp; |
|
330 |
||
331 |
HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) { |
|
332 |
Py_DECREF(script->module); |
|
333 |
HASH_DEL(ctx->py->script_hash, script); |
|
334 |
free(script); |
|
335 |
}
|
|
336 |
ctx->py->script_hash = NULL; |
|
337 |
}
|
|
338 |
PyGILState_Release(gstate); |
|
339 |
||
340 |
#if PY_MAJOR_VERSION < 3
|
|
341 |
pcilib_py_clean_default_modules(ctx); |
|
342 |
#endif /* PY_MAJOR_VERSION < 3 */ |
|
343 |
||
344 |
if (ctx->py->finalyze) { |
|
345 |
#if PY_MAJOR_VERSION < 3
|
|
346 |
Py_Finalize(); |
|
347 |
#else /* PY_MAJOR_VERSION < 3 */ |
|
348 |
// PyThreadState_Delete(ctx->py->tstate);
|
|
349 |
||
350 |
// singal python init thread to stop and wait it to finish
|
|
351 |
pthread_cond_signal(&(ctx->py->cond)); |
|
352 |
pthread_mutex_unlock(&(ctx->py->lock)); |
|
353 |
pthread_join(ctx->py->pth, NULL); |
|
354 |
||
355 |
// destroy synchronization primitives
|
|
356 |
pthread_cond_destroy(&(ctx->py->cond)); |
|
357 |
pthread_mutex_destroy(&(ctx->py->lock)); |
|
358 |
#endif /* PY_MAJOR_VERSION < 3 */ |
|
359 |
}
|
|
360 |
free(ctx->py); |
|
361 |
ctx->py = NULL; |
|
362 |
}
|
|
363 |
#endif /* HAVE_PYTHON */ |
|
364 |
}
|
|
365 |
||
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
366 |
int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { |
367 |
#ifdef HAVE_PYTHON
|
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
368 |
int err = 0; |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
369 |
PyObject *pypath, *pynewdir; |
370 |
PyObject *pydict, *pystr, *pyret = NULL; |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
371 |
char *script_dir; |
372 |
||
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
373 |
if (!ctx->py) return 0; |
374 |
||
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
375 |
const char *model_dir = getenv("PCILIB_MODEL_DIR"); |
376 |
if (!model_dir) model_dir = PCILIB_MODEL_DIR; |
|
377 |
||
378 |
if (!dir) dir = ctx->model; |
|
379 |
||
380 |
if (*dir == '/') { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
381 |
script_dir = (char*)dir; |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
382 |
} else { |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
383 |
script_dir = alloca(strlen(model_dir) + strlen(dir) + 2); |
384 |
if (!script_dir) return PCILIB_ERROR_MEMORY; |
|
385 |
sprintf(script_dir, "%s/%s", model_dir, dir); |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
386 |
}
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
387 |
|
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
388 |
PyGILState_STATE gstate = PyGILState_Ensure(); |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
389 |
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
390 |
pypath = PySys_GetObject("path"); |
391 |
if (!pypath) { |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
392 |
PyGILState_Release(gstate); |
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
393 |
pcilib_python_warning("Can't get python path"); |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
394 |
return PCILIB_ERROR_FAILED; |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
395 |
}
|
396 |
||
346.1.35
by Vasilii Chernov
Add Python3 support |
397 |
pynewdir = PyUnicode_FromString(script_dir); |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
398 |
if (!pynewdir) { |
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
399 |
PyGILState_Release(gstate); |
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
400 |
pcilib_python_warning("Can't create python string"); |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
401 |
return PCILIB_ERROR_MEMORY; |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
402 |
}
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
403 |
|
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
404 |
// Checking if the directory already in the path?
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
405 |
pydict = PyDict_New(); |
406 |
if (pydict) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
407 |
pystr = PyUnicode_FromString("cur"); |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
408 |
if (pystr) { |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
409 |
PyDict_SetItem(pydict, pystr, pynewdir); |
410 |
Py_DECREF(pystr); |
|
411 |
}
|
|
412 |
||
413 |
pystr = PyUnicode_FromString("path"); |
|
414 |
if (pystr) { |
|
415 |
PyDict_SetItem(pydict, pystr, pypath); |
|
416 |
Py_DECREF(pystr); |
|
417 |
}
|
|
418 |
||
419 |
pyret = PyRun_String("cur in path", Py_eval_input, ctx->py->global_dict, pydict); |
|
420 |
Py_DECREF(pydict); |
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
421 |
}
|
422 |
||
423 |
if ((pyret == Py_False)&&(PyList_Append(pypath, pynewdir) == -1)) |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
424 |
err = PCILIB_ERROR_FAILED; |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
425 |
|
426 |
if (pyret) Py_DECREF(pyret); |
|
427 |
Py_DECREF(pynewdir); |
|
428 |
||
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
429 |
PyGILState_Release(gstate); |
430 |
||
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
431 |
if (err) { |
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
432 |
pcilib_python_warning("Can't add directory (%s) to python path", script_dir); |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
433 |
return err; |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
434 |
}
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
435 |
#endif /* HAVE_PYTHON */ |
436 |
||
437 |
return 0; |
|
309
by Suren A. Chilingaryan
Base functions for views |
438 |
}
|
439 |
||
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
440 |
|
441 |
int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) { |
|
442 |
#ifdef HAVE_PYTHON
|
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
443 |
PyObject* pymodule; |
444 |
pcilib_script_t *module = NULL; |
|
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
445 |
PyGILState_STATE gstate; |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
446 |
|
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
447 |
if (!ctx->py) return 0; |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
448 |
|
449 |
char *module_name = strdupa(script_name); |
|
450 |
if (!module_name) return PCILIB_ERROR_MEMORY; |
|
451 |
||
452 |
char *py = strrchr(module_name, '.'); |
|
453 |
if ((!py)||(strcasecmp(py, ".py"))) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
454 |
pcilib_error("Invalid script name (%s) is specified", script_name); |
455 |
return PCILIB_ERROR_INVALID_ARGUMENT; |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
456 |
}
|
457 |
*py = 0; |
|
458 |
||
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
459 |
HASH_FIND_STR(ctx->py->script_hash, script_name, module); |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
460 |
if (module) return 0; |
461 |
||
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
462 |
gstate = PyGILState_Ensure(); |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
463 |
pymodule = PyImport_ImportModule(module_name); |
464 |
if (!pymodule) { |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
465 |
PyGILState_Release(gstate); |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
466 |
pcilib_python_error("Error importing script (%s)", script_name); |
467 |
return PCILIB_ERROR_FAILED; |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
468 |
}
|
469 |
||
470 |
module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); |
|
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
471 |
if (!module) { |
472 |
Py_DECREF(pymodule); |
|
473 |
PyGILState_Release(gstate); |
|
474 |
return PCILIB_ERROR_MEMORY; |
|
475 |
}
|
|
476 |
||
477 |
PyGILState_Release(gstate); |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
478 |
|
479 |
module->module = pymodule; |
|
480 |
module->name = script_name; |
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
481 |
HASH_ADD_KEYPTR(hh, ctx->py->script_hash, module->name, strlen(module->name), module); |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
482 |
#endif /* HAVE_PYTHON */ |
483 |
return 0; |
|
484 |
}
|
|
485 |
||
486 |
int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_name, pcilib_access_mode_t *mode_ret) { |
|
487 |
pcilib_access_mode_t mode = 0; |
|
488 |
||
489 |
#ifdef HAVE_PYTHON
|
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
490 |
PyObject *dict; |
491 |
PyObject *pystr; |
|
492 |
pcilib_script_t *module; |
|
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
493 |
PyGILState_STATE gstate; |
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
494 |
|
495 |
if (!ctx->py) { |
|
496 |
if (mode_ret) *mode_ret = mode; |
|
497 |
return 0; |
|
498 |
}
|
|
499 |
||
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
500 |
HASH_FIND_STR(ctx->py->script_hash, script_name, module); |
501 |
||
502 |
if(!module) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
503 |
pcilib_error("Script (%s) is not loaded yet", script_name); |
504 |
return PCILIB_ERROR_NOTFOUND; |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
505 |
}
|
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
506 |
|
507 |
gstate = PyGILState_Ensure(); |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
508 |
|
509 |
dict = PyModule_GetDict(module->module); |
|
510 |
if (!dict) { |
|
372
by Suren A. Chilingaryan
Integrate last part of Python code from Vasiliy Chernov |
511 |
PyGILState_Release(gstate); |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
512 |
pcilib_python_error("Error getting dictionary for script (%s)", script_name); |
513 |
return PCILIB_ERROR_FAILED; |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
514 |
}
|
515 |
||
346.1.35
by Vasilii Chernov
Add Python3 support |
516 |
pystr = PyUnicode_FromString("read_from_register"); |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
517 |
if (pystr) { |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
518 |
if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_R; |
519 |
Py_DECREF(pystr); |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
520 |
}
|
521 |
||
346.1.35
by Vasilii Chernov
Add Python3 support |
522 |
pystr = PyUnicode_FromString("write_to_register"); |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
523 |
if (pystr) { |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
524 |
if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W; |
525 |
Py_DECREF(pystr); |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
526 |
}
|
346.1.38
by Vasilii Chernov
Fix python3 initialization from pcilib_t |
527 |
|
528 |
PyGILState_Release(gstate); |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
529 |
#endif /* HAVE_PYTHON */ |
530 |
||
375
by Suren A. Chilingaryan
Fix more threading problems in Python3 |
531 |
// pcilib_py_load_default_modules(py->ctx);
|
532 |
||
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
533 |
if (mode_ret) *mode_ret = mode; |
534 |
return 0; |
|
535 |
}
|
|
536 |
||
537 |
pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) { |
|
538 |
#ifdef HAVE_PYTHON
|
|
539 |
int err = 0; |
|
540 |
PyObject *res = NULL; |
|
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
541 |
PyGILState_STATE gstate; |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
542 |
|
543 |
long ival; |
|
544 |
double fval; |
|
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
545 |
|
546 |
if (!ctx->py) return NULL; |
|
547 |
||
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
548 |
gstate = PyGILState_Ensure(); |
549 |
switch(val->type) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
550 |
case PCILIB_TYPE_LONG: |
551 |
ival = pcilib_get_value_as_int(ctx, val, &err); |
|
552 |
if (!err) res = (PyObject*)PyLong_FromLong(ival); |
|
553 |
break; |
|
554 |
case PCILIB_TYPE_DOUBLE: |
|
555 |
fval = pcilib_get_value_as_float(ctx, val, &err); |
|
556 |
if (!err) res = (PyObject*)PyFloat_FromDouble(fval); |
|
557 |
break; |
|
558 |
default: |
|
559 |
PyGILState_Release(gstate); |
|
560 |
pcilib_error("Can't convert pcilib value of type (%lu) to PyObject", val->type); |
|
561 |
if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; |
|
562 |
return NULL; |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
563 |
}
|
564 |
PyGILState_Release(gstate); |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
565 |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
566 |
if (err) { |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
567 |
if (ret) *ret = err; |
568 |
return NULL; |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
569 |
} else if (!res) { |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
570 |
if (ret) *ret = PCILIB_ERROR_MEMORY; |
571 |
return res; |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
572 |
}
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
573 |
|
574 |
if (ret) *ret = 0; |
|
575 |
return res; |
|
576 |
#else /* HAVE_PYTHON */ |
|
577 |
pcilib_error("Python is not supported"); |
|
578 |
return NULL; |
|
579 |
#endif /* HAVE_PYTHON */ |
|
580 |
}
|
|
581 |
||
582 |
int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object *pval) { |
|
583 |
#ifdef HAVE_PYTHON
|
|
584 |
int err = 0; |
|
585 |
PyObject *pyval = (PyObject*)pval; |
|
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
586 |
PyGILState_STATE gstate; |
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
587 |
|
588 |
if (!ctx->py) return PCILIB_ERROR_NOTINITIALIZED; |
|
589 |
||
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
590 |
gstate = PyGILState_Ensure(); |
346.1.35
by Vasilii Chernov
Add Python3 support |
591 |
if (PyLong_Check(pyval)) { |
592 |
err = pcilib_set_value_from_int(ctx, val, PyLong_AsLong(pyval)); |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
593 |
} else if (PyFloat_Check(pyval)) { |
594 |
err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyval)); |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
595 |
#if PY_MAJOR_VERSION < 3
|
596 |
} else if (PyInt_Check(pyval)) { |
|
597 |
err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyval)); |
|
598 |
} else if (PyString_Check(pyval)) { |
|
599 |
err = pcilib_set_value_from_string(ctx, val, PyString_AsString(pyval)); |
|
600 |
} else if (PyUnicode_Check(pyval)) { |
|
601 |
PyObject *buf = PyUnicode_AsASCIIString(pyval); |
|
602 |
if (buf) { |
|
603 |
err = pcilib_set_value_from_string(ctx, val, PyString_AsString(buf)); |
|
604 |
Py_DecRef(buf); |
|
605 |
} else { |
|
606 |
err = PCILIB_ERROR_FAILED; |
|
607 |
}
|
|
608 |
#else /* PY_MAJOR_VERSION < 3 */ |
|
609 |
} else if (PyUnicode_Check(pyval)) { |
|
346.1.35
by Vasilii Chernov
Add Python3 support |
610 |
err = pcilib_set_value_from_string(ctx, val, PyUnicode_AsUTF8(pyval)); |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
611 |
#endif /* PY_MAJOR_VERSION < 3 */ |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
612 |
} else { |
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
613 |
PyGILState_Release(gstate); |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
614 |
pcilib_error("Can't convert PyObject to polymorphic pcilib value"); |
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
615 |
return PCILIB_ERROR_NOTSUPPORTED; |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
616 |
}
|
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
617 |
PyGILState_Release(gstate); |
618 |
||
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
619 |
return err; |
620 |
#else /* HAVE_PYTHON */ |
|
621 |
pcilib_error("Python is not supported"); |
|
622 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
623 |
#endif /* HAVE_PYTHON */ |
|
624 |
}
|
|
625 |
||
626 |
#ifdef HAVE_PYTHON
|
|
309
by Suren A. Chilingaryan
Base functions for views |
627 |
static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { |
628 |
int i; |
|
629 |
int err = 0; |
|
312
by Suren A. Chilingaryan
Support transform views |
630 |
pcilib_value_t val = {0}; |
309
by Suren A. Chilingaryan
Base functions for views |
631 |
pcilib_register_value_t regval; |
632 |
||
633 |
char save; |
|
634 |
char *reg, *cur; |
|
635 |
size_t offset = 0; |
|
636 |
||
637 |
size_t size; |
|
638 |
char *src; |
|
639 |
char *dst; |
|
640 |
||
641 |
size_t max_repl = 2 + 2 * sizeof(pcilib_value_t); // the text representation of largest integer |
|
642 |
||
643 |
if (value) { |
|
644 |
err = pcilib_copy_value(ctx, &val, value); |
|
645 |
if (err) return NULL; |
|
646 |
||
647 |
err = pcilib_convert_value_type(ctx, &val, PCILIB_TYPE_STRING); |
|
648 |
if (err) return NULL; |
|
649 |
||
650 |
if (strlen(val.sval) > max_repl) |
|
651 |
max_repl = strlen(val.sval); |
|
652 |
}
|
|
653 |
||
654 |
size = ((max_repl + 1) / 3 + 1) * strlen(codestr); // minimum register length is 3 symbols ($a + delimiter space), it is replaces with (max_repl+1) symbols |
|
655 |
||
656 |
src = strdup(codestr); |
|
657 |
dst = (char*)malloc(size); // allocating maximum required space |
|
658 |
||
659 |
if ((!src)||(!dst)) { |
|
660 |
if (src) free(src); |
|
661 |
if (dst) free(dst); |
|
662 |
pcilib_error("Failed to allocate memory for string formulas"); |
|
663 |
return NULL; |
|
664 |
}
|
|
665 |
||
666 |
cur = src; |
|
667 |
reg = strchr(src, '$'); |
|
668 |
while (reg) { |
|
669 |
strcpy(dst + offset, cur); |
|
670 |
offset += reg - cur; |
|
671 |
||
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
672 |
// find the end of the register name
|
309
by Suren A. Chilingaryan
Base functions for views |
673 |
reg++; |
317
by Suren A. Chilingaryan
Support properties in transform formulas |
674 |
if (*reg == '{') { |
675 |
reg++; |
|
676 |
for (i = 0; (reg[i])&&(reg[i] != '}'); i++); |
|
677 |
if (!reg[i]) { |
|
678 |
pcilib_error("Python formula (%s) contains unterminated variable reference", codestr); |
|
679 |
err = PCILIB_ERROR_INVALID_DATA; |
|
680 |
break; |
|
681 |
}
|
|
682 |
} else { |
|
683 |
for (i = 0; isalnum(reg[i])||(reg[i] == '_'); i++); |
|
684 |
}
|
|
309
by Suren A. Chilingaryan
Base functions for views |
685 |
save = reg[i]; |
686 |
reg[i] = 0; |
|
687 |
||
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
688 |
// determine replacement value
|
309
by Suren A. Chilingaryan
Base functions for views |
689 |
if (!strcasecmp(reg, "value")) { |
690 |
if (!value) { |
|
691 |
pcilib_error("Python formula (%s) relies on the value of register, but it is not provided", codestr); |
|
692 |
err = PCILIB_ERROR_INVALID_REQUEST; |
|
693 |
break; |
|
694 |
}
|
|
695 |
||
696 |
strcpy(dst + offset, val.sval); |
|
697 |
} else { |
|
317
by Suren A. Chilingaryan
Support properties in transform formulas |
698 |
if (*reg == '/') { |
699 |
pcilib_value_t val = {0}; |
|
700 |
err = pcilib_get_property(ctx, reg, &val); |
|
701 |
if (err) break; |
|
702 |
err = pcilib_convert_value_type(ctx, &val, PCILIB_TYPE_STRING); |
|
703 |
if (err) break; |
|
704 |
sprintf(dst + offset, "%s", val.sval); |
|
705 |
} else { |
|
706 |
err = pcilib_read_register(ctx, NULL, reg, ®val); |
|
707 |
if (err) break; |
|
330
by Suren A. Chilingaryan
Support for 64-bit registes |
708 |
sprintf(dst + offset, "0x%lx", regval); |
317
by Suren A. Chilingaryan
Support properties in transform formulas |
709 |
}
|
309
by Suren A. Chilingaryan
Base functions for views |
710 |
}
|
711 |
||
712 |
offset += strlen(dst + offset); |
|
317
by Suren A. Chilingaryan
Support properties in transform formulas |
713 |
if (save == '}') i++; |
714 |
else reg[i] = save; |
|
309
by Suren A. Chilingaryan
Base functions for views |
715 |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
716 |
// Advance to the next register if any
|
309
by Suren A. Chilingaryan
Base functions for views |
717 |
cur = reg + i; |
718 |
reg = strchr(cur, '$'); |
|
719 |
}
|
|
720 |
||
721 |
strcpy(dst + offset, cur); |
|
722 |
||
723 |
free(src); |
|
724 |
||
725 |
if (err) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
726 |
free(dst); |
727 |
return NULL; |
|
309
by Suren A. Chilingaryan
Base functions for views |
728 |
}
|
729 |
||
730 |
return dst; |
|
731 |
}
|
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
732 |
#endif /* HAVE_PYTHON */ |
309
by Suren A. Chilingaryan
Base functions for views |
733 |
|
734 |
int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
735 |
#ifdef HAVE_PYTHON
|
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
736 |
int err; |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
737 |
|
309
by Suren A. Chilingaryan
Base functions for views |
738 |
PyGILState_STATE gstate; |
739 |
char *code; |
|
740 |
PyObject* obj; |
|
741 |
||
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
742 |
if (!ctx->py) return PCILIB_ERROR_NOTINITIALIZED; |
743 |
||
309
by Suren A. Chilingaryan
Base functions for views |
744 |
code = pcilib_py_parse_string(ctx, codestr, value); |
745 |
if (!code) { |
|
746 |
pcilib_error("Failed to parse registers in the code: %s", codestr); |
|
747 |
return PCILIB_ERROR_FAILED; |
|
748 |
}
|
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
749 |
|
309
by Suren A. Chilingaryan
Base functions for views |
750 |
gstate = PyGILState_Ensure(); |
751 |
obj = PyRun_String(code, Py_eval_input, ctx->py->global_dict, ctx->py->global_dict); |
|
752 |
PyGILState_Release(gstate); |
|
753 |
||
754 |
if (!obj) { |
|
755 |
pcilib_error("Failed to run the Python code: %s", code); |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
756 |
free(code); |
309
by Suren A. Chilingaryan
Base functions for views |
757 |
return PCILIB_ERROR_FAILED; |
758 |
}
|
|
759 |
||
314
by Suren A. Chilingaryan
Support writting register views |
760 |
pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code); |
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
761 |
err = pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
762 |
|
346.1.24
by Vasilii Chernov
Merge with Suren branch. Fix memory leaks. |
763 |
Py_DECREF(obj); |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
764 |
free(code); |
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
765 |
|
766 |
return err; |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
767 |
#else /* HAVE_PYTHON */ |
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
768 |
pcilib_error("Current build not support python."); |
346.1.16
by Vasilii Chernov
1. Add cmake BUILD_PYTHON_MODULES option. |
769 |
return PCILIB_ERROR_NOTAVAILABLE; |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
770 |
#endif /* HAVE_PYTHON */ |
771 |
}
|
|
772 |
||
773 |
int pcilib_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func_name, pcilib_value_t *val) { |
|
774 |
#ifdef HAVE_PYTHON
|
|
775 |
int err = 0; |
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
776 |
PyObject *pyfunc; |
777 |
PyObject *pyval = NULL, *pyret; |
|
778 |
pcilib_script_t *module = NULL; |
|
779 |
||
369
by Suren A. Chilingaryan
Make Python problems non-fatal |
780 |
if (!ctx->py) return PCILIB_ERROR_NOTINITIALIZED; |
781 |
||
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
782 |
HASH_FIND_STR(ctx->py->script_hash, script_name, module); |
783 |
||
784 |
if (!module) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
785 |
pcilib_error("Script (%s) is not loaded", script_name); |
786 |
return PCILIB_ERROR_NOTFOUND; |
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
787 |
}
|
346.1.29
by Vasilii Chernov
1. multithreading: |
788 |
|
789 |
if (val) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
790 |
pyval = pcilib_get_value_as_pyobject(ctx, val, &err); |
791 |
if (err) return err; |
|
346.1.29
by Vasilii Chernov
1. multithreading: |
792 |
}
|
793 |
||
356
by Suren A. Chilingaryan
Add more GILs to prevent Python crashes in multithreaded applications |
794 |
PyGILState_STATE gstate = PyGILState_Ensure(); |
795 |
||
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
796 |
pyfunc = PyUnicode_FromString(func_name); |
797 |
if (!pyfunc) { |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
798 |
if (pyval) Py_DECREF(pyval); |
799 |
PyGILState_Release(gstate); |
|
800 |
return PCILIB_ERROR_MEMORY; |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
801 |
}
|
802 |
||
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
803 |
pyret = PyObject_CallMethodObjArgs(module->module, pyfunc, ctx->py->pcilib_pywrap, pyval, NULL); |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
804 |
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
805 |
Py_DECREF(pyfunc); |
806 |
Py_DECREF(pyval); |
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
807 |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
808 |
if (!pyret) { |
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
809 |
PyGILState_Release(gstate); |
810 |
pcilib_python_error("Error executing function (%s) of python script (%s)", func_name, script_name); |
|
811 |
return PCILIB_ERROR_FAILED; |
|
346.1.29
by Vasilii Chernov
1. multithreading: |
812 |
}
|
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
813 |
|
814 |
if ((val)&&(pyret != Py_None)) |
|
367
by Suren A. Chilingaryan
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov |
815 |
err = pcilib_set_value_from_pyobject(ctx, val, pyret); |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
816 |
|
817 |
Py_DECREF(pyret); |
|
346.1.29
by Vasilii Chernov
1. multithreading: |
818 |
PyGILState_Release(gstate); |
346.1.33
by Vasilii Chernov
Move scripts handing code from py.c to Python wrap |
819 |
|
820 |
return err; |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
821 |
#else /* HAVE_PYTHON */ |
822 |
pcilib_error("Python is not supported"); |
|
823 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
824 |
#endif /* HAVE_PYTHON */ |
|
346.1.6
by Vasilii Chernov
Merge script and transform view. Add get register and properties info to python wrap. |
825 |
}
|