py.c 4.2 KB

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