py.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. #include "config.h"
  2. #ifdef HAVE_PYTHON
  3. # include <Python.h>
  4. # if PY_MAJOR_VERSION >= 3
  5. # include <pthread.h>
  6. # endif /* PY_MAJOR_VERSION >= 3 */
  7. #endif /* HAVE_PYTHON */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <strings.h>
  12. #include <alloca.h>
  13. #include "pci.h"
  14. #include "debug.h"
  15. #include "pcilib.h"
  16. #include "py.h"
  17. #include "error.h"
  18. #ifdef HAVE_PYTHON
  19. # define PCILIB_PYTHON_WRAPPER "pcipywrap"
  20. typedef struct pcilib_script_s pcilib_script_t;
  21. struct pcilib_script_s {
  22. const char *name; /**< Script name */
  23. PyObject *module; /**< PyModule object, contains script enviroment */
  24. UT_hash_handle hh; /**< hash */
  25. };
  26. struct pcilib_py_s {
  27. int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */
  28. PyObject *main_module; /**< Main interpreter */
  29. PyObject *global_dict; /**< Dictionary of main interpreter */
  30. PyObject *pcilib_pywrap; /**< pcilib wrapper module */
  31. pcilib_script_t *script_hash; /**< Hash with loaded scripts */
  32. # if PY_MAJOR_VERSION >= 3
  33. pthread_t pth;
  34. pthread_cond_t cond;
  35. pthread_mutex_t lock;
  36. # endif /* PY_MAJOR_VERSION > 3 */
  37. };
  38. #endif /* HAVE_PYTHON */
  39. void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...) {
  40. va_list va;
  41. const char *type = NULL;
  42. const char *val = NULL;
  43. #ifdef HAVE_PYTHON
  44. PyGILState_STATE gstate;
  45. PyObject *pytype = NULL;
  46. PyObject *pyval = NULL;
  47. PyObject *pystr = NULL;
  48. PyObject *pytraceback = NULL;
  49. gstate = PyGILState_Ensure();
  50. if (PyErr_Occurred()) {
  51. PyErr_Fetch(&pytype, &pyval, &pytraceback);
  52. PyErr_NormalizeException(&pytype, &pyval, &pytraceback);
  53. if (pyval) pystr = PyObject_Str(pyval);
  54. # if PY_MAJOR_VERSION >= 3
  55. if (pytype) {
  56. if (PyUnicode_Check(pytype))
  57. type = PyUnicode_AsUTF8(pytype);
  58. else
  59. type = PyExceptionClass_Name(pytype);
  60. }
  61. if (pystr) {
  62. val = PyUnicode_AsUTF8(pystr);
  63. }
  64. # else /* PY_MAJOR_VERSION >= 3 */
  65. if (pytype) {
  66. if (PyString_Check(pytype))
  67. type = PyString_AsString(pytype);
  68. else
  69. type = PyExceptionClass_Name(pytype);
  70. }
  71. if (pystr) {
  72. val = PyString_AsString(pystr);
  73. }
  74. # endif /*PY_MAJOR_VERSION >= 3*/
  75. }
  76. PyGILState_Release(gstate);
  77. #endif /* HAVE_PYTHON */
  78. va_start(va, msg);
  79. if (type) {
  80. char *str;
  81. size_t len = 32;
  82. if (msg) len += strlen(msg);
  83. if (type) len += strlen(type);
  84. if (val) len += strlen(val);
  85. str = alloca(len * sizeof(char));
  86. if (str) {
  87. if (msg&&val)
  88. sprintf(str, "%s <%s: %s>", msg, type, val);
  89. else if (msg)
  90. sprintf(str, "%s <%s>", msg, type);
  91. else if (val)
  92. sprintf(str, "Python error %s: %s", type, val);
  93. else
  94. sprintf(str, "Python error %s", type);
  95. pcilib_log_vmessage(file, line, flags, prio, str, va);
  96. }
  97. } else {
  98. pcilib_log_vmessage(file, line, flags, prio, msg, va);
  99. }
  100. va_end(va);
  101. #ifdef HAVE_PYTHON
  102. if (pystr) Py_DECREF(pystr);
  103. if (pytype) Py_DECREF(pytype);
  104. if (pyval) Py_DECREF(pyval);
  105. if (pytraceback) Py_DECREF(pytraceback);
  106. #endif /* HAVE_PYTHON */
  107. }
  108. #ifdef HAVE_PYTHON
  109. # if PY_MAJOR_VERSION >= 3
  110. /**
  111. * Python3 specially treats the main thread intializing Python. It crashes if
  112. * the Lock is released and any Python code is executed under the GIL compaling
  113. * that GIL is not locked. Python3 assumes that the main thread most of the time
  114. * holds the Lock, only shortly giving it away to other threads and re-obtaining
  115. * it hereafter. This is not possible to do with GILs, but instead (probably)
  116. * PyEval_{Save,Restore}Thread() should be used. On other hand, the other threads
  117. * are working fine with GILs. This makes things complicated as we need to know
  118. * if we are running in main thread or not.
  119. * To simplify matters, during initalization we start a new thread which will
  120. * performa actual initialization of Python and, hence, act as main thread.
  121. * We only intialize here. No python code is executed afterwards. So we don't
  122. * need to care about special locking mechanisms in main thread. Instead all
  123. * our user threads can use GILs normally.
  124. * See more details here:
  125. * http://stackoverflow.com/questions/24499393/cpython-locking-the-gil-in-the-main-thread
  126. * http://stackoverflow.com/questions/15470367/pyeval-initthreads-in-python-3-how-when-to-call-it-the-saga-continues-ad-naus
  127. */
  128. static void *pcilib_py_run_init_thread(void *arg) {
  129. pcilib_py_t *py = (pcilib_py_t*)(arg);
  130. Py_Initialize();
  131. PyEval_InitThreads();
  132. PyEval_ReleaseLock();
  133. // Ensure that main thread waiting for our signal
  134. pthread_lock(&(py->lock));
  135. // Inform the parent thread that initialization is finished
  136. pthread_cond_signal(&(py->cond));
  137. // Wait untill cleanup is requested
  138. pthread_cond_wait(&(py->cond), &(py->lock));
  139. pthread_unlock(&(py->lock)));
  140. Py_Finalize();
  141. return NULL;
  142. }
  143. # endif /* PY_MAJOR_VERSION < 3 */
  144. #endif /* HAVE_PYTHON */
  145. int pcilib_init_py(pcilib_t *ctx) {
  146. #ifdef HAVE_PYTHON
  147. ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
  148. if (!ctx->py) return PCILIB_ERROR_MEMORY;
  149. memset(ctx->py, 0, sizeof(pcilib_py_t));
  150. if (!Py_IsInitialized()) {
  151. # if PY_MAJOR_VERSION < 3
  152. Py_Initialize();
  153. // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads
  154. PyEval_InitThreads();
  155. PyEval_ReleaseLock();
  156. # else /* PY_MAJOR_VERSION < 3 */
  157. err = pthread_mutex_init(&(ctx->py.lock));
  158. if (err) return PCILIB_ERROR_FAILED;
  159. err = pthread_cond_init(&(ctx->py.cond));
  160. if (err) {
  161. pthread_mutex_destroy(&(ctx->py.lock));
  162. return PCILIB_ERROR_FAILED;
  163. }
  164. err = pthread_mutex_lock(&(ctx->py.lock));
  165. if (err) {
  166. pthread_cond_destroy(&(ctx->py.lock));
  167. pthread_mutex_destroy(&(ctx->py.lock));
  168. return PCILIB_ERROR_FAILED;
  169. }
  170. // Create initalizer thread and wait until it releases the Lock
  171. err = pthread_create(&(ctx->py.pth), NULL, pcilib_py_run_init_thread, &(ctx->py));
  172. if (err) {
  173. pthread_mutex_unlock(&(ctx->py.lock));
  174. pthread_cond_destroy(&(ctx->py.cond));
  175. pthread_mutex_destroy(&(ctx->py.lock));
  176. return PCILIB_ERROR_FAILED;
  177. }
  178. // Wait until initialized and keep the lock afterwards until free executed
  179. pthread_cond_wait(&(ctx->py.cond), (ctx->py.lock));
  180. # endif /* PY_MAJOR_VERSION < 3 */
  181. ctx->py->finalyze = 1;
  182. }
  183. PyGILState_STATE gstate = PyGILState_Ensure();
  184. ctx->py->main_module = PyImport_AddModule("__parser__");
  185. if (!ctx->py->main_module) {
  186. PyGILState_Release(gstate);
  187. pcilib_python_warning("Error importing python parser");
  188. return PCILIB_ERROR_FAILED;
  189. }
  190. ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module);
  191. if (!ctx->py->global_dict) {
  192. PyGILState_Release(gstate);
  193. pcilib_python_warning("Error locating global python dictionary");
  194. return PCILIB_ERROR_FAILED;
  195. }
  196. PyObject *pywrap = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER);
  197. if (!pywrap) {
  198. PyGILState_Release(gstate);
  199. pcilib_python_warning("Error importing pcilib python wrapper");
  200. return PCILIB_ERROR_FAILED;
  201. }
  202. PyObject *mod_name = PyUnicode_FromString(PCILIB_PYTHON_WRAPPER);
  203. PyObject *pyctx = PyCapsule_New(ctx, "pcilib", NULL);
  204. ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(pywrap, mod_name, pyctx, NULL);
  205. Py_XDECREF(pyctx);
  206. Py_XDECREF(mod_name);
  207. if (!ctx->py->pcilib_pywrap) {
  208. PyGILState_Release(gstate);
  209. pcilib_python_warning("Error initializing python wrapper");
  210. return PCILIB_ERROR_FAILED;
  211. }
  212. PyGILState_Release(gstate);
  213. #endif /* HAVE_PYTHON */
  214. return 0;
  215. }
  216. int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
  217. #ifdef HAVE_PYTHON
  218. int err = 0;
  219. PyObject *pypath, *pynewdir;
  220. PyObject *pydict, *pystr, *pyret = NULL;
  221. char *script_dir;
  222. if (!ctx->py) return 0;
  223. const char *model_dir = getenv("PCILIB_MODEL_DIR");
  224. if (!model_dir) model_dir = PCILIB_MODEL_DIR;
  225. if (!dir) dir = ctx->model;
  226. if (*dir == '/') {
  227. script_dir = (char*)dir;
  228. } else {
  229. script_dir = alloca(strlen(model_dir) + strlen(dir) + 2);
  230. if (!script_dir) return PCILIB_ERROR_MEMORY;
  231. sprintf(script_dir, "%s/%s", model_dir, dir);
  232. }
  233. PyGILState_STATE gstate = PyGILState_Ensure();
  234. pypath = PySys_GetObject("path");
  235. if (!pypath) {
  236. PyGILState_Release(gstate);
  237. pcilib_python_warning("Can't get python path");
  238. return PCILIB_ERROR_FAILED;
  239. }
  240. pynewdir = PyUnicode_FromString(script_dir);
  241. if (!pynewdir) {
  242. PyGILState_Release(gstate);
  243. pcilib_python_warning("Can't create python string");
  244. return PCILIB_ERROR_MEMORY;
  245. }
  246. // Checking if the directory already in the path?
  247. pydict = PyDict_New();
  248. if (pydict) {
  249. pystr = PyUnicode_FromString("cur");
  250. if (pystr) {
  251. PyDict_SetItem(pydict, pystr, pynewdir);
  252. Py_DECREF(pystr);
  253. }
  254. pystr = PyUnicode_FromString("path");
  255. if (pystr) {
  256. PyDict_SetItem(pydict, pystr, pypath);
  257. Py_DECREF(pystr);
  258. }
  259. pyret = PyRun_String("cur in path", Py_eval_input, ctx->py->global_dict, pydict);
  260. Py_DECREF(pydict);
  261. }
  262. if ((pyret == Py_False)&&(PyList_Append(pypath, pynewdir) == -1))
  263. err = PCILIB_ERROR_FAILED;
  264. if (pyret) Py_DECREF(pyret);
  265. Py_DECREF(pynewdir);
  266. PyGILState_Release(gstate);
  267. if (err) {
  268. pcilib_python_warning("Can't add directory (%s) to python path", script_dir);
  269. return err;
  270. }
  271. #endif /* HAVE_PYTHON */
  272. return 0;
  273. }
  274. void pcilib_free_py(pcilib_t *ctx) {
  275. #ifdef HAVE_PYTHON
  276. int finalyze = 0;
  277. if (ctx->py) {
  278. PyGILState_STATE gstate;
  279. if (ctx->py->finalyze) finalyze = 1;
  280. gstate = PyGILState_Ensure();
  281. if (ctx->py->script_hash) {
  282. pcilib_script_t *script, *script_tmp;
  283. HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) {
  284. Py_DECREF(script->module);
  285. HASH_DEL(ctx->py->script_hash, script);
  286. free(script);
  287. }
  288. ctx->py->script_hash = NULL;
  289. }
  290. if (ctx->py->pcilib_pywrap)
  291. Py_DECREF(ctx->py->pcilib_pywrap);
  292. PyGILState_Release(gstate);
  293. free(ctx->py);
  294. ctx->py = NULL;
  295. }
  296. if (finalyze) {
  297. #if PY_MAJOR_VERSION >= 3
  298. // singal python init thread to stop and wait it to finish
  299. pthread_cond_signal(&(ctx->py.cond));
  300. pthread_mutex_unlock(&(ctx->py.lock));
  301. pthread_join(ctx->py.pth, NULL);
  302. // destroy synchronization primitives
  303. pthread_cond_destroy(&(ctx->py.cond));
  304. pthread_mutex_destroy(&(ctx->py.lock));
  305. #else /* PY_MAJOR_VERSION < 3 */
  306. Py_Finalize();
  307. #endif /* PY_MAJOR_VERSION < 3 */
  308. }
  309. #endif /* HAVE_PYTHON */
  310. }
  311. int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
  312. #ifdef HAVE_PYTHON
  313. PyObject* pymodule;
  314. pcilib_script_t *module = NULL;
  315. PyGILState_STATE gstate;
  316. if (!ctx->py) return 0;
  317. char *module_name = strdupa(script_name);
  318. if (!module_name) return PCILIB_ERROR_MEMORY;
  319. char *py = strrchr(module_name, '.');
  320. if ((!py)||(strcasecmp(py, ".py"))) {
  321. pcilib_error("Invalid script name (%s) is specified", script_name);
  322. return PCILIB_ERROR_INVALID_ARGUMENT;
  323. }
  324. *py = 0;
  325. HASH_FIND_STR(ctx->py->script_hash, script_name, module);
  326. if (module) return 0;
  327. gstate = PyGILState_Ensure();
  328. pymodule = PyImport_ImportModule(module_name);
  329. if (!pymodule) {
  330. PyGILState_Release(gstate);
  331. pcilib_python_error("Error importing script (%s)", script_name);
  332. return PCILIB_ERROR_FAILED;
  333. }
  334. PyGILState_Release(gstate);
  335. module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t));
  336. if (!module) return PCILIB_ERROR_MEMORY;
  337. module->module = pymodule;
  338. module->name = script_name;
  339. HASH_ADD_KEYPTR(hh, ctx->py->script_hash, module->name, strlen(module->name), module);
  340. #endif /* HAVE_PYTHON */
  341. return 0;
  342. }
  343. int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_name, pcilib_access_mode_t *mode_ret) {
  344. pcilib_access_mode_t mode = 0;
  345. #ifdef HAVE_PYTHON
  346. PyObject *dict;
  347. PyObject *pystr;
  348. pcilib_script_t *module;
  349. PyGILState_STATE gstate;
  350. if (!ctx->py) {
  351. if (mode_ret) *mode_ret = mode;
  352. return 0;
  353. }
  354. HASH_FIND_STR(ctx->py->script_hash, script_name, module);
  355. if(!module) {
  356. pcilib_error("Script (%s) is not loaded yet", script_name);
  357. return PCILIB_ERROR_NOTFOUND;
  358. }
  359. gstate = PyGILState_Ensure();
  360. dict = PyModule_GetDict(module->module);
  361. if (!dict) {
  362. PyGILState_Release(gstate);
  363. pcilib_python_error("Error getting dictionary for script (%s)", script_name);
  364. return PCILIB_ERROR_FAILED;
  365. }
  366. pystr = PyUnicode_FromString("read_from_register");
  367. if (pystr) {
  368. if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_R;
  369. Py_DECREF(pystr);
  370. }
  371. pystr = PyUnicode_FromString("write_to_register");
  372. if (pystr) {
  373. if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W;
  374. Py_DECREF(pystr);
  375. }
  376. PyGILState_Release(gstate);
  377. #endif /* HAVE_PYTHON */
  378. if (mode_ret) *mode_ret = mode;
  379. return 0;
  380. }
  381. pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) {
  382. #ifdef HAVE_PYTHON
  383. int err = 0;
  384. PyObject *res = NULL;
  385. PyGILState_STATE gstate;
  386. long ival;
  387. double fval;
  388. if (!ctx->py) return NULL;
  389. gstate = PyGILState_Ensure();
  390. switch(val->type) {
  391. case PCILIB_TYPE_LONG:
  392. ival = pcilib_get_value_as_int(ctx, val, &err);
  393. if (!err) res = (PyObject*)PyLong_FromLong(ival);
  394. break;
  395. case PCILIB_TYPE_DOUBLE:
  396. fval = pcilib_get_value_as_float(ctx, val, &err);
  397. if (!err) res = (PyObject*)PyFloat_FromDouble(fval);
  398. break;
  399. default:
  400. PyGILState_Release(gstate);
  401. pcilib_error("Can't convert pcilib value of type (%lu) to PyObject", val->type);
  402. if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED;
  403. return NULL;
  404. }
  405. PyGILState_Release(gstate);
  406. if (err) {
  407. if (ret) *ret = err;
  408. return NULL;
  409. } else if (!res) {
  410. if (ret) *ret = PCILIB_ERROR_MEMORY;
  411. return res;
  412. }
  413. if (ret) *ret = 0;
  414. return res;
  415. #else /* HAVE_PYTHON */
  416. pcilib_error("Python is not supported");
  417. return NULL;
  418. #endif /* HAVE_PYTHON */
  419. }
  420. int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object *pval) {
  421. #ifdef HAVE_PYTHON
  422. int err = 0;
  423. PyObject *pyval = (PyObject*)pval;
  424. PyGILState_STATE gstate;
  425. if (!ctx->py) return PCILIB_ERROR_NOTINITIALIZED;
  426. gstate = PyGILState_Ensure();
  427. if (PyLong_Check(pyval)) {
  428. err = pcilib_set_value_from_int(ctx, val, PyLong_AsLong(pyval));
  429. } else if (PyFloat_Check(pyval)) {
  430. err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyval));
  431. #if PY_MAJOR_VERSION < 3
  432. } else if (PyInt_Check(pyval)) {
  433. err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyval));
  434. } else if (PyString_Check(pyval)) {
  435. err = pcilib_set_value_from_string(ctx, val, PyString_AsString(pyval));
  436. } else if (PyUnicode_Check(pyval)) {
  437. PyObject *buf = PyUnicode_AsASCIIString(pyval);
  438. if (buf) {
  439. err = pcilib_set_value_from_string(ctx, val, PyString_AsString(buf));
  440. Py_DecRef(buf);
  441. } else {
  442. err = PCILIB_ERROR_FAILED;
  443. }
  444. #else /* PY_MAJOR_VERSION < 3 */
  445. } else if (PyUnicode_Check(pyval)) {
  446. err = pcilib_set_value_from_string(ctx, val, PyUnicode_AsUTF8(pyval));
  447. #endif /* PY_MAJOR_VERSION < 3 */
  448. } else {
  449. PyGILState_Release(gstate);
  450. pcilib_error("Can't convert PyObject to polymorphic pcilib value");
  451. return PCILIB_ERROR_NOTSUPPORTED;
  452. }
  453. PyGILState_Release(gstate);
  454. return err;
  455. #else /* HAVE_PYTHON */
  456. pcilib_error("Python is not supported");
  457. return PCILIB_ERROR_NOTSUPPORTED;
  458. #endif /* HAVE_PYTHON */
  459. }
  460. #ifdef HAVE_PYTHON
  461. static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) {
  462. int i;
  463. int err = 0;
  464. pcilib_value_t val = {0};
  465. pcilib_register_value_t regval;
  466. char save;
  467. char *reg, *cur;
  468. size_t offset = 0;
  469. size_t size;
  470. char *src;
  471. char *dst;
  472. size_t max_repl = 2 + 2 * sizeof(pcilib_value_t); // the text representation of largest integer
  473. if (value) {
  474. err = pcilib_copy_value(ctx, &val, value);
  475. if (err) return NULL;
  476. err = pcilib_convert_value_type(ctx, &val, PCILIB_TYPE_STRING);
  477. if (err) return NULL;
  478. if (strlen(val.sval) > max_repl)
  479. max_repl = strlen(val.sval);
  480. }
  481. 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
  482. src = strdup(codestr);
  483. dst = (char*)malloc(size); // allocating maximum required space
  484. if ((!src)||(!dst)) {
  485. if (src) free(src);
  486. if (dst) free(dst);
  487. pcilib_error("Failed to allocate memory for string formulas");
  488. return NULL;
  489. }
  490. cur = src;
  491. reg = strchr(src, '$');
  492. while (reg) {
  493. strcpy(dst + offset, cur);
  494. offset += reg - cur;
  495. // find the end of the register name
  496. reg++;
  497. if (*reg == '{') {
  498. reg++;
  499. for (i = 0; (reg[i])&&(reg[i] != '}'); i++);
  500. if (!reg[i]) {
  501. pcilib_error("Python formula (%s) contains unterminated variable reference", codestr);
  502. err = PCILIB_ERROR_INVALID_DATA;
  503. break;
  504. }
  505. } else {
  506. for (i = 0; isalnum(reg[i])||(reg[i] == '_'); i++);
  507. }
  508. save = reg[i];
  509. reg[i] = 0;
  510. // determine replacement value
  511. if (!strcasecmp(reg, "value")) {
  512. if (!value) {
  513. pcilib_error("Python formula (%s) relies on the value of register, but it is not provided", codestr);
  514. err = PCILIB_ERROR_INVALID_REQUEST;
  515. break;
  516. }
  517. strcpy(dst + offset, val.sval);
  518. } else {
  519. if (*reg == '/') {
  520. pcilib_value_t val = {0};
  521. err = pcilib_get_property(ctx, reg, &val);
  522. if (err) break;
  523. err = pcilib_convert_value_type(ctx, &val, PCILIB_TYPE_STRING);
  524. if (err) break;
  525. sprintf(dst + offset, "%s", val.sval);
  526. } else {
  527. err = pcilib_read_register(ctx, NULL, reg, &regval);
  528. if (err) break;
  529. sprintf(dst + offset, "0x%lx", regval);
  530. }
  531. }
  532. offset += strlen(dst + offset);
  533. if (save == '}') i++;
  534. else reg[i] = save;
  535. // Advance to the next register if any
  536. cur = reg + i;
  537. reg = strchr(cur, '$');
  538. }
  539. strcpy(dst + offset, cur);
  540. free(src);
  541. if (err) {
  542. free(dst);
  543. return NULL;
  544. }
  545. return dst;
  546. }
  547. #endif /* HAVE_PYTHON */
  548. int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) {
  549. #ifdef HAVE_PYTHON
  550. int err;
  551. PyGILState_STATE gstate;
  552. char *code;
  553. PyObject* obj;
  554. if (!ctx->py) return PCILIB_ERROR_NOTINITIALIZED;
  555. code = pcilib_py_parse_string(ctx, codestr, value);
  556. if (!code) {
  557. pcilib_error("Failed to parse registers in the code: %s", codestr);
  558. return PCILIB_ERROR_FAILED;
  559. }
  560. gstate = PyGILState_Ensure();
  561. obj = PyRun_String(code, Py_eval_input, ctx->py->global_dict, ctx->py->global_dict);
  562. PyGILState_Release(gstate);
  563. if (!obj) {
  564. pcilib_error("Failed to run the Python code: %s", code);
  565. free(code);
  566. return PCILIB_ERROR_FAILED;
  567. }
  568. pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code);
  569. err = pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
  570. Py_DECREF(obj);
  571. free(code);
  572. return err;
  573. #else /* HAVE_PYTHON */
  574. pcilib_error("Current build not support python.");
  575. return PCILIB_ERROR_NOTAVAILABLE;
  576. #endif /* HAVE_PYTHON */
  577. }
  578. int pcilib_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func_name, pcilib_value_t *val) {
  579. #ifdef HAVE_PYTHON
  580. int err = 0;
  581. PyObject *pyfunc;
  582. PyObject *pyval = NULL, *pyret;
  583. pcilib_script_t *module = NULL;
  584. if (!ctx->py) return PCILIB_ERROR_NOTINITIALIZED;
  585. HASH_FIND_STR(ctx->py->script_hash, script_name, module);
  586. if (!module) {
  587. pcilib_error("Script (%s) is not loaded", script_name);
  588. return PCILIB_ERROR_NOTFOUND;
  589. }
  590. if (val) {
  591. pyval = pcilib_get_value_as_pyobject(ctx, val, &err);
  592. if (err) return err;
  593. }
  594. PyGILState_STATE gstate = PyGILState_Ensure();
  595. pyfunc = PyUnicode_FromString(func_name);
  596. if (!pyfunc) {
  597. if (pyval) Py_DECREF(pyval);
  598. PyGILState_Release(gstate);
  599. return PCILIB_ERROR_MEMORY;
  600. }
  601. pyret = PyObject_CallMethodObjArgs(module->module, pyfunc, ctx->py->pcilib_pywrap, pyval, NULL);
  602. Py_DECREF(pyfunc);
  603. Py_DECREF(pyval);
  604. if (!pyret) {
  605. PyGILState_Release(gstate);
  606. pcilib_python_error("Error executing function (%s) of python script (%s)", func_name, script_name);
  607. return PCILIB_ERROR_FAILED;
  608. }
  609. if ((val)&&(pyret != Py_None))
  610. err = pcilib_set_value_from_pyobject(ctx, val, pyret);
  611. Py_DECREF(pyret);
  612. PyGILState_Release(gstate);
  613. return err;
  614. #else /* HAVE_PYTHON */
  615. pcilib_error("Python is not supported");
  616. return PCILIB_ERROR_NOTSUPPORTED;
  617. #endif /* HAVE_PYTHON */
  618. }