py.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. for (i = 0; isalnum(reg[i]); i++);
  87. save = reg[i];
  88. reg[i] = 0;
  89. // determine replacement value
  90. if (!strcasecmp(reg, "value")) {
  91. if (!value) {
  92. pcilib_error("Python formula (%s) relies on the value of register, but it is not provided", codestr);
  93. err = PCILIB_ERROR_INVALID_REQUEST;
  94. break;
  95. }
  96. strcpy(dst + offset, val.sval);
  97. } else {
  98. err = pcilib_read_register(ctx, NULL, reg, &regval);
  99. if (err) break;
  100. sprintf(dst + offset, "0x%x", regval);
  101. }
  102. offset += strlen(dst + offset);
  103. reg[i] = save;
  104. // Advance to the next register if any
  105. cur = reg + i;
  106. reg = strchr(cur, '$');
  107. }
  108. strcpy(dst + offset, cur);
  109. free(src);
  110. if (err) {
  111. free(dst);
  112. return NULL;
  113. }
  114. return dst;
  115. }
  116. int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) {
  117. PyGILState_STATE gstate;
  118. char *code;
  119. PyObject* obj;
  120. code = pcilib_py_parse_string(ctx, codestr, value);
  121. if (!code) {
  122. pcilib_error("Failed to parse registers in the code: %s", codestr);
  123. return PCILIB_ERROR_FAILED;
  124. }
  125. gstate = PyGILState_Ensure();
  126. obj = PyRun_String(code, Py_eval_input, ctx->py->global_dict, ctx->py->global_dict);
  127. PyGILState_Release(gstate);
  128. if (!obj) {
  129. pcilib_error("Failed to run the Python code: %s", code);
  130. return PCILIB_ERROR_FAILED;
  131. }
  132. pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code);
  133. return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
  134. }