bison_callback.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * Callback functions called by bison.
  3. *
  4. * The original py_callback function is removed from bison_.pyx because Cython
  5. * generated crappy code for that callback. Cython's generated code caused
  6. * segfaults when python triggered its garbage collection. Thus, something was
  7. * wrong with references. Debugging the generated code was hard and the
  8. * callbacks are part of PyBison's core, so implementing the callbacks in C
  9. * instead of generating them by Cython seems the right way to go.
  10. *
  11. * Written januari 2012 by Sander Mathijs van Veen <smvv@kompiler.org>
  12. * Copyright (c) 2012 by Sander Mathijs van Veen, all rights reserved.
  13. *
  14. * Released under the GNU General Public License, a copy of which should appear
  15. * in this distribution in the file called 'COPYING'. If this file is missing,
  16. * then you can obtain a copy of the GPL license document from the GNU website
  17. * at http://www.gnu.org.
  18. *
  19. * This software is released with no warranty whatsoever. Use it at your own
  20. * risk.
  21. *
  22. * If you wish to use this software in a commercial application, and wish to
  23. * depart from the GPL licensing requirements, please contact the author and
  24. * apply for a commercial license.
  25. */
  26. #include "Python.h"
  27. #include <stdarg.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #define likely(x) __builtin_expect((x),1)
  31. #define unlikely(x) __builtin_expect((x),0)
  32. static PyObject *py_attr_hook_handler_name;
  33. static PyObject *py_attr_hook_read_after_name;
  34. static PyObject *py_attr_hook_read_before_name;
  35. static PyObject *py_attr_handle_name;
  36. static PyObject *py_attr_read_name;
  37. static PyObject *py_attr_file_name;
  38. static PyObject *py_attr_close_name;
  39. // Construct attribute names (only the first time)
  40. // TODO: where do we Py_DECREF(handle_name) ??
  41. #define INIT_ATTR(variable, name, failure) \
  42. if (unlikely(!variable)) { \
  43. variable = PyString_FromString(name); \
  44. if (!variable) failure; \
  45. }
  46. #define debug_refcnt(variable, count) { \
  47. printf(#variable ": %d\n", Py_REFCNT(variable)); \
  48. assert(Py_REFCNT(variable) == count); \
  49. }
  50. /*
  51. * Callback function which is invoked by target handlers within the C yyparse()
  52. * function. This callback function will return parser._handle's python object
  53. * or, on failure, NULL is returned.
  54. */
  55. PyObject* py_callback(PyObject *parser, char *target, int option, int nargs,
  56. ...)
  57. {
  58. va_list ap;
  59. int i;
  60. PyObject *res;
  61. PyObject *names = PyList_New(nargs),
  62. *values = PyList_New(nargs);
  63. va_start(ap, nargs);
  64. // Construct the names and values list from the variable argument list.
  65. for(i = 0; i < nargs; i++) {
  66. PyObject *name = PyString_FromString(va_arg(ap, char *));
  67. PyList_SetItem(names, i, name);
  68. PyObject *value = va_arg(ap, PyObject *);
  69. Py_INCREF(value);
  70. PyList_SetItem(values, i, value);
  71. }
  72. va_end(ap);
  73. INIT_ATTR(py_attr_handle_name, "_handle", return NULL);
  74. INIT_ATTR(py_attr_hook_handler_name, "hook_handler", return NULL);
  75. // Call the handler with the arguments
  76. PyObject *handle = PyObject_GetAttr(parser, py_attr_handle_name);
  77. if (unlikely(!handle)) return NULL;
  78. PyObject *arglist = Py_BuildValue("(siOO)", target, option, names, values);
  79. if (unlikely(!arglist)) { Py_DECREF(handle); return NULL; }
  80. res = PyObject_CallObject(handle, arglist);
  81. Py_DECREF(handle);
  82. Py_DECREF(arglist);
  83. if (unlikely(!res)) return res;
  84. // Check if the "hook_handler" callback exists
  85. handle = PyObject_GetAttr(parser, py_attr_hook_handler_name);
  86. if (!handle) {
  87. PyErr_Clear();
  88. return res;
  89. }
  90. // Call the "hook_handler" callback
  91. arglist = Py_BuildValue("(siOOO)", target, option, names, values, res);
  92. if (unlikely(!arglist)) { Py_DECREF(handle); return res; }
  93. res = PyObject_CallObject(handle, arglist);
  94. Py_DECREF(handle);
  95. Py_DECREF(arglist);
  96. return res;
  97. }
  98. void py_input(PyObject *parser, char *buf, int *result, int max_size)
  99. {
  100. PyObject *handle, *arglist, *res;
  101. char *bufstr;
  102. INIT_ATTR(py_attr_hook_read_after_name, "hook_read_after", return);
  103. INIT_ATTR(py_attr_hook_read_before_name, "hook_read_before", return);
  104. INIT_ATTR(py_attr_read_name, "read", return);
  105. INIT_ATTR(py_attr_file_name, "file", return);
  106. INIT_ATTR(py_attr_close_name, "close", return);
  107. // Check if the "hook_READ_BEFORE" callback exists
  108. if (PyObject_HasAttr(parser, py_attr_hook_read_before_name))
  109. {
  110. handle = PyObject_GetAttr(parser, py_attr_hook_read_before_name);
  111. if (unlikely(!handle)) return;
  112. // Call the "hook_READ_BEFORE" callback
  113. arglist = PyTuple_New(0);
  114. if (unlikely(!arglist)) { Py_DECREF(handle); return; }
  115. res = PyObject_CallObject(handle, arglist);
  116. Py_DECREF(handle);
  117. Py_DECREF(arglist);
  118. }
  119. // Read the input string and catch keyboard interrupt exceptions.
  120. handle = PyObject_GetAttr(parser, py_attr_read_name);
  121. if (unlikely(!handle)) {
  122. // TODO: set exception message for missing attribute error
  123. return;
  124. }
  125. arglist = Py_BuildValue("(i)", max_size);
  126. if (unlikely(!arglist)) { Py_DECREF(handle); return; }
  127. res = PyObject_CallObject(handle, arglist);
  128. Py_DECREF(handle);
  129. Py_DECREF(arglist);
  130. if (unlikely(!res)) {
  131. // Catch and reset KeyboardInterrupt exception
  132. PyObject *given = PyErr_Occurred();
  133. if (given && PyErr_GivenExceptionMatches(given,
  134. PyExc_KeyboardInterrupt)) {
  135. PyErr_Clear();
  136. }
  137. return;
  138. }
  139. // Check if the "hook_read_after" callback exists
  140. if (unlikely(!PyObject_HasAttr(parser, py_attr_hook_read_after_name)))
  141. goto finish_input;
  142. handle = PyObject_GetAttr(parser, py_attr_hook_read_after_name);
  143. if (unlikely(!handle)) return;
  144. // Call the "hook_READ_AFTER" callback
  145. arglist = Py_BuildValue("(O)", res);
  146. if (unlikely(!arglist)) { Py_DECREF(handle); return; }
  147. res = PyObject_CallObject(handle, arglist);
  148. Py_DECREF(res);
  149. Py_DECREF(handle);
  150. Py_DECREF(arglist);
  151. if (unlikely(!res)) return;
  152. finish_input:
  153. // Copy the read python input string to the buffer
  154. bufstr = PyString_AsString(res);
  155. *result = strlen(bufstr);
  156. memcpy(buf, bufstr, *result);
  157. // Close the read buffer if nothing is read. Marks the Python file object
  158. // as being closed from Python's point of view. This does not close the
  159. // associated C stream (which is not necessary here, otherwise use
  160. // "os.close(0)").
  161. if (!*result && PyObject_HasAttr(parser, py_attr_file_name)) {
  162. PyObject *file_handle = PyObject_GetAttr(parser, py_attr_file_name);
  163. if (unlikely(!file_handle)) return;
  164. handle = PyObject_GetAttr(file_handle, py_attr_close_name);
  165. Py_DECREF(file_handle);
  166. if (unlikely(!handle)) return;
  167. arglist = PyTuple_New(0);
  168. if (unlikely(!arglist)) { Py_DECREF(handle); return; }
  169. res = PyObject_CallObject(handle, arglist);
  170. Py_DECREF(res);
  171. Py_DECREF(handle);
  172. Py_DECREF(arglist);
  173. // TODO: something went wrong while closing the buffer.
  174. if (unlikely(!res)) return;
  175. }
  176. }