py.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include <Python.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <strings.h>
  6. #include "pci.h"
  7. #include "debug.h"
  8. #include "pcilib.h"
  9. #include "py.h"
  10. #include "error.h"
  11. struct pcilib_py_s {
  12. PyObject *main_module;
  13. PyObject *global_dict;
  14. };
  15. int pcilib_init_py(pcilib_t *ctx) {
  16. ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
  17. if (!ctx->py) return PCILIB_ERROR_MEMORY;
  18. Py_Initialize();
  19. ctx->py->main_module = PyImport_AddModule("__parser__");
  20. if (!ctx->py->main_module)
  21. return PCILIB_ERROR_FAILED;
  22. ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module);
  23. if (!ctx->py->global_dict)
  24. return PCILIB_ERROR_FAILED;
  25. return 0;
  26. }
  27. void pcilib_free_py(pcilib_t *ctx) {
  28. if (ctx->py) {
  29. // Dict and module references are borrowed
  30. free(ctx->py);
  31. ctx->py = NULL;
  32. }
  33. Py_Finalize();
  34. }
  35. /*
  36. static int pcilib_py_realloc_string(pcilib_t *ctx, size_t required, size_t *size, char **str) {
  37. char *ptr;
  38. size_t cur = *size;
  39. if ((required + 1) > cur) {
  40. while (cur < required) cur *= 2;
  41. ptr = (char*)realloc(*str, cur);
  42. if (!ptr) return PCILIB_ERROR_MEMORY;
  43. *size = cur;
  44. *str = ptr;
  45. }
  46. ]
  47. return 0;
  48. }
  49. */
  50. static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) {
  51. int i;
  52. int err = 0;
  53. pcilib_value_t val = {0};
  54. pcilib_register_value_t regval;
  55. char save;
  56. char *reg, *cur;
  57. size_t offset = 0;
  58. size_t size;
  59. char *src;
  60. char *dst;
  61. size_t max_repl = 2 + 2 * sizeof(pcilib_value_t); // the text representation of largest integer
  62. if (value) {
  63. err = pcilib_copy_value(ctx, &val, value);
  64. if (err) return NULL;
  65. err = pcilib_convert_value_type(ctx, &val, PCILIB_TYPE_STRING);
  66. if (err) return NULL;
  67. if (strlen(val.sval) > max_repl)
  68. max_repl = strlen(val.sval);
  69. }
  70. 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
  71. src = strdup(codestr);
  72. dst = (char*)malloc(size); // allocating maximum required space
  73. if ((!src)||(!dst)) {
  74. if (src) free(src);
  75. if (dst) free(dst);
  76. pcilib_error("Failed to allocate memory for string formulas");
  77. return NULL;
  78. }
  79. cur = src;
  80. reg = strchr(src, '$');
  81. while (reg) {
  82. strcpy(dst + offset, cur);
  83. offset += reg - cur;
  84. // find the end of the register name
  85. reg++;
  86. if (*reg == '{') {
  87. reg++;
  88. for (i = 0; (reg[i])&&(reg[i] != '}'); i++);
  89. if (!reg[i]) {
  90. pcilib_error("Python formula (%s) contains unterminated variable reference", codestr);
  91. err = PCILIB_ERROR_INVALID_DATA;
  92. break;
  93. }
  94. } else {
  95. for (i = 0; isalnum(reg[i])||(reg[i] == '_'); i++);
  96. }
  97. save = reg[i];
  98. reg[i] = 0;
  99. // determine replacement value
  100. if (!strcasecmp(reg, "value")) {
  101. if (!value) {
  102. pcilib_error("Python formula (%s) relies on the value of register, but it is not provided", codestr);
  103. err = PCILIB_ERROR_INVALID_REQUEST;
  104. break;
  105. }
  106. strcpy(dst + offset, val.sval);
  107. } else {
  108. if (*reg == '/') {
  109. pcilib_value_t val = {0};
  110. err = pcilib_get_property(ctx, reg, &val);
  111. if (err) break;
  112. err = pcilib_convert_value_type(ctx, &val, PCILIB_TYPE_STRING);
  113. if (err) break;
  114. sprintf(dst + offset, "%s", val.sval);
  115. } else {
  116. err = pcilib_read_register(ctx, NULL, reg, &regval);
  117. if (err) break;
  118. sprintf(dst + offset, "0x%lx", regval);
  119. }
  120. }
  121. offset += strlen(dst + offset);
  122. if (save == '}') i++;
  123. else reg[i] = save;
  124. // Advance to the next register if any
  125. cur = reg + i;
  126. reg = strchr(cur, '$');
  127. }
  128. strcpy(dst + offset, cur);
  129. free(src);
  130. if (err) {
  131. free(dst);
  132. return NULL;
  133. }
  134. return dst;
  135. }
  136. int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) {
  137. PyGILState_STATE gstate;
  138. char *code;
  139. PyObject* obj;
  140. code = pcilib_py_parse_string(ctx, codestr, value);
  141. if (!code) {
  142. pcilib_error("Failed to parse registers in the code: %s", codestr);
  143. return PCILIB_ERROR_FAILED;
  144. }
  145. gstate = PyGILState_Ensure();
  146. obj = PyRun_String(code, Py_eval_input, ctx->py->global_dict, ctx->py->global_dict);
  147. PyGILState_Release(gstate);
  148. if (!obj) {
  149. pcilib_error("Failed to run the Python code: %s", code);
  150. return PCILIB_ERROR_FAILED;
  151. }
  152. pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code);
  153. return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
  154. }