PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/echo/python/Python/modsupport.c

https://github.com/jtauber/cleese
C | 241 lines | 205 code | 22 blank | 14 comment | 53 complexity | c555c4b6e512828bc8b94ec67dd727a7 MD5 | raw file
  1. /* Module support implementation */
  2. #include "Python.h"
  3. PyObject *
  4. Py_InitModule4(char *name, PyMethodDef *methods, char *doc,
  5. PyObject *passthrough, int module_api_version)
  6. {
  7. PyObject *m, *d, *v, *n;
  8. PyMethodDef *ml;
  9. if ((m = PyImport_AddModule(name)) == NULL)
  10. return NULL;
  11. d = PyModule_GetDict(m);
  12. if (methods != NULL) {
  13. n = PyString_FromString(name);
  14. if (n == NULL)
  15. return NULL;
  16. for (ml = methods; ml->ml_name != NULL; ml++) {
  17. v = PyCFunction_NewEx(ml, passthrough, n);
  18. if (v == NULL)
  19. return NULL;
  20. if (PyDict_SetItemString(d, ml->ml_name, v) != 0) {
  21. Py_DECREF(v);
  22. return NULL;
  23. }
  24. Py_DECREF(v);
  25. }
  26. }
  27. return m;
  28. }
  29. static int
  30. countformat(char *format, int endchar)
  31. {
  32. int count = 0;
  33. int level = 0;
  34. while (level > 0 || *format != endchar) {
  35. switch (*format) {
  36. case '\0':
  37. /* Premature end */
  38. printf("unmatched paren in format\n");
  39. return -1;
  40. case '(':
  41. case '[':
  42. case '{':
  43. if (level == 0)
  44. count++;
  45. level++;
  46. break;
  47. case ')':
  48. case ']':
  49. case '}':
  50. level--;
  51. break;
  52. case '#':
  53. case '&':
  54. case ',':
  55. case ':':
  56. case ' ':
  57. case '\t':
  58. break;
  59. default:
  60. if (level == 0)
  61. count++;
  62. }
  63. format++;
  64. }
  65. return count;
  66. }
  67. /* forward reference */
  68. static PyObject *do_mkvalue(char**, va_list *);
  69. static PyObject *
  70. do_mktuple(char **p_format, va_list *p_va, int endchar, int n)
  71. {
  72. PyObject *v;
  73. int i;
  74. if (n < 0)
  75. return NULL;
  76. if ((v = PyTuple_New(n)) == NULL)
  77. return NULL;
  78. for (i = 0; i < n; i++) {
  79. PyObject *w = do_mkvalue(p_format, p_va);
  80. if (w == NULL) {
  81. Py_DECREF(v);
  82. return NULL;
  83. }
  84. PyTuple_SetItem(v, i, w);
  85. }
  86. if (v != NULL && **p_format != endchar) {
  87. Py_DECREF(v);
  88. v = NULL;
  89. printf("Unmatched paren in format");
  90. }
  91. else if (endchar)
  92. ++*p_format;
  93. return v;
  94. }
  95. static PyObject *
  96. do_mkvalue(char **p_format, va_list *p_va)
  97. {
  98. for (;;) {
  99. switch (*(*p_format)++) {
  100. case '(':
  101. return do_mktuple(p_format, p_va, ')',
  102. countformat(*p_format, ')'));
  103. // case '[':
  104. // return do_mklist(p_format, p_va, ']',
  105. // countformat(*p_format, ']'));
  106. //
  107. // case '{':
  108. // return do_mkdict(p_format, p_va, '}',
  109. // countformat(*p_format, '}'));
  110. //
  111. case 'b':
  112. case 'B':
  113. case 'h':
  114. case 'i':
  115. return PyInt_FromLong((long)va_arg(*p_va, int));
  116. case 'H':
  117. return PyInt_FromLong((long)va_arg(*p_va, unsigned int));
  118. case 'l':
  119. return PyInt_FromLong((long)va_arg(*p_va, long));
  120. case 'k':
  121. return PyInt_FromLong((long)va_arg(*p_va, unsigned long));
  122. case 'f':
  123. // case 'd':
  124. // return PyFloat_FromDouble(
  125. // (double)va_arg(*p_va, va_double));
  126. case 'c':
  127. {
  128. char p[1];
  129. p[0] = va_arg(*p_va, int);
  130. return PyString_FromStringAndSize(p, 1);
  131. }
  132. case 's':
  133. case 'z':
  134. {
  135. PyObject *v;
  136. char *str = va_arg(*p_va, char *);
  137. int n;
  138. if (**p_format == '#') {
  139. ++*p_format;
  140. n = va_arg(*p_va, int);
  141. }
  142. else
  143. n = -1;
  144. if (str == NULL) {
  145. v = Py_None;
  146. Py_INCREF(v);
  147. }
  148. else {
  149. if (n < 0) {
  150. size_t m = strlen(str);
  151. if (m > INT_MAX) {
  152. printf("string too long for Python string");
  153. return NULL;
  154. }
  155. n = (int)m;
  156. }
  157. v = PyString_FromStringAndSize(str, n);
  158. }
  159. return v;
  160. }
  161. case 'N':
  162. case 'S':
  163. case 'O':
  164. if (**p_format == '&') {
  165. typedef PyObject *(*converter)(void *);
  166. converter func = va_arg(*p_va, converter);
  167. void *arg = va_arg(*p_va, void *);
  168. ++*p_format;
  169. return (*func)(arg);
  170. }
  171. else {
  172. PyObject *v;
  173. v = va_arg(*p_va, PyObject *);
  174. if (v != NULL) {
  175. if (*(*p_format - 1) != 'N')
  176. Py_INCREF(v);
  177. }
  178. else
  179. printf("NULL object passed to Py_BuildValue");
  180. return v;
  181. }
  182. case ':':
  183. case ',':
  184. case ' ':
  185. case '\t':
  186. break;
  187. default:
  188. printf("bad format char passed to Py_BuildValue");
  189. return NULL;
  190. }
  191. }
  192. }
  193. PyObject *
  194. Py_VaBuildValue(char *format, va_list va)
  195. {
  196. char *f = format;
  197. int n = countformat(f, '\0');
  198. va_list lva;
  199. lva = va;
  200. if (n < 0)
  201. return NULL;
  202. if (n == 0) {
  203. Py_INCREF(Py_None);
  204. return Py_None;
  205. }
  206. if (n == 1)
  207. return do_mkvalue(&f, &lva);
  208. return do_mktuple(&f, &lva, '\0', n);
  209. }
  210. PyObject *
  211. Py_BuildValue(char *format, ...)
  212. {
  213. va_list va;
  214. PyObject* retval;
  215. va_start(va, format);
  216. retval = Py_VaBuildValue(format, va);
  217. va_end(va);
  218. return retval;
  219. }