/necco/python/Python/modsupport.c
C | 405 lines | 357 code | 44 blank | 4 comment | 91 complexity | 9b53b90b5af7c53be900e5b5abf5a53e MD5 | raw file
1
2/* Module support implementation */
3
4#include "Python.h"
5
6typedef double va_double;
7
8PyObject *
9Py_InitModule4(char *name, PyMethodDef *methods, char *doc,
10 PyObject *passthrough, int module_api_version)
11{
12 PyObject *m, *d, *v, *n;
13 PyMethodDef *ml;
14 if ((m = PyImport_AddModule(name)) == NULL)
15 return NULL;
16 d = PyModule_GetDict(m);
17 if (methods != NULL) {
18 n = PyString_FromString(name);
19 if (n == NULL)
20 return NULL;
21 for (ml = methods; ml->ml_name != NULL; ml++) {
22 v = PyCFunction_NewEx(ml, passthrough, n);
23 if (v == NULL)
24 return NULL;
25 if (PyDict_SetItemString(d, ml->ml_name, v) != 0) {
26 Py_DECREF(v);
27 return NULL;
28 }
29 Py_DECREF(v);
30 }
31 }
32 return m;
33}
34
35static int
36countformat(char *format, int endchar)
37{
38 int count = 0;
39 int level = 0;
40 while (level > 0 || *format != endchar) {
41 switch (*format) {
42 case '\0':
43 /* Premature end */
44 printf("unmatched paren in format\n");
45 return -1;
46 case '(':
47 case '[':
48 case '{':
49 if (level == 0)
50 count++;
51 level++;
52 break;
53 case ')':
54 case ']':
55 case '}':
56 level--;
57 break;
58 case '#':
59 case '&':
60 case ',':
61 case ':':
62 case ' ':
63 case '\t':
64 break;
65 default:
66 if (level == 0)
67 count++;
68 }
69 format++;
70 }
71 return count;
72}
73
74/* forward reference */
75static PyObject *do_mklist(char**, va_list *, int, int);
76static PyObject *do_mkdict(char**, va_list *, int, int);
77static PyObject *do_mkvalue(char**, va_list *);
78
79static PyObject *
80do_mkdict(char **p_format, va_list *p_va, int endchar, int n)
81{
82 PyObject *d;
83 int i;
84 if (n < 0)
85 return NULL;
86 if ((d = PyDict_New()) == NULL)
87 return NULL;
88 for (i = 0; i < n; i+= 2) {
89 PyObject *k, *v;
90 int err;
91 k = do_mkvalue(p_format, p_va);
92 if (k == NULL) {
93 Py_DECREF(d);
94 return NULL;
95 }
96 v = do_mkvalue(p_format, p_va);
97 if (v == NULL) {
98 Py_DECREF(k);
99 Py_DECREF(d);
100 return NULL;
101 }
102 err = PyDict_SetItem(d, k, v);
103 Py_DECREF(k);
104 Py_DECREF(v);
105 if (err < 0) {
106 Py_DECREF(d);
107 return NULL;
108 }
109 }
110 if (d != NULL && **p_format != endchar) {
111 Py_DECREF(d);
112 d = NULL;
113 PyErr_SetString(PyExc_SystemError,
114 "Unmatched paren in format");
115 }
116 else if (endchar)
117 ++*p_format;
118 return d;
119}
120
121static PyObject *
122do_mklist(char **p_format, va_list *p_va, int endchar, int n)
123{
124 PyObject *v;
125 int i;
126 if (n < 0)
127 return NULL;
128 if ((v = PyList_New(n)) == NULL)
129 return NULL;
130 for (i = 0; i < n; i++) {
131 PyObject *w = do_mkvalue(p_format, p_va);
132 if (w == NULL) {
133 Py_DECREF(v);
134 return NULL;
135 }
136 PyList_SetItem(v, i, w);
137 }
138 if (v != NULL && **p_format != endchar) {
139 Py_DECREF(v);
140 v = NULL;
141 PyErr_SetString(PyExc_SystemError,
142 "Unmatched paren in format");
143 }
144 else if (endchar)
145 ++*p_format;
146 return v;
147}
148
149static PyObject *
150do_mktuple(char **p_format, va_list *p_va, int endchar, int n)
151{
152 PyObject *v;
153 int i;
154 if (n < 0)
155 return NULL;
156 if ((v = PyTuple_New(n)) == NULL)
157 return NULL;
158 for (i = 0; i < n; i++) {
159 PyObject *w = do_mkvalue(p_format, p_va);
160 if (w == NULL) {
161 Py_DECREF(v);
162 return NULL;
163 }
164 PyTuple_SetItem(v, i, w);
165 }
166 if (v != NULL && **p_format != endchar) {
167 Py_DECREF(v);
168 v = NULL;
169 printf("Unmatched paren in format");
170 }
171 else if (endchar)
172 ++*p_format;
173 return v;
174}
175
176static PyObject *
177do_mkvalue(char **p_format, va_list *p_va)
178{
179 for (;;) {
180 switch (*(*p_format)++) {
181 case '(':
182 return do_mktuple(p_format, p_va, ')',
183 countformat(*p_format, ')'));
184
185 case '[':
186 return do_mklist(p_format, p_va, ']',
187 countformat(*p_format, ']'));
188
189 case '{':
190 return do_mkdict(p_format, p_va, '}',
191 countformat(*p_format, '}'));
192
193 case 'b':
194 case 'B':
195 case 'h':
196 case 'i':
197 return PyInt_FromLong((long)va_arg(*p_va, int));
198
199 case 'H':
200 return PyInt_FromLong((long)va_arg(*p_va, unsigned int));
201
202 case 'l':
203 return PyInt_FromLong((long)va_arg(*p_va, long));
204
205 case 'k':
206 return PyInt_FromLong((long)va_arg(*p_va, unsigned long));
207
208 case 'f':
209 case 'd':
210 return PyFloat_FromDouble(
211 (double)va_arg(*p_va, va_double));
212
213 case 'c':
214 {
215 char p[1];
216 p[0] = va_arg(*p_va, int);
217 return PyString_FromStringAndSize(p, 1);
218 }
219
220 case 's':
221 case 'z':
222 {
223 PyObject *v;
224 char *str = va_arg(*p_va, char *);
225 int n;
226 if (**p_format == '#') {
227 ++*p_format;
228 n = va_arg(*p_va, int);
229 }
230 else
231 n = -1;
232 if (str == NULL) {
233 v = Py_None;
234 Py_INCREF(v);
235 }
236 else {
237 if (n < 0) {
238 size_t m = strlen(str);
239 if (m > INT_MAX) {
240 printf("string too long for Python string");
241 return NULL;
242 }
243 n = (int)m;
244 }
245 v = PyString_FromStringAndSize(str, n);
246 }
247 return v;
248 }
249
250 case 'N':
251 case 'S':
252 case 'O':
253 if (**p_format == '&') {
254 typedef PyObject *(*converter)(void *);
255 converter func = va_arg(*p_va, converter);
256 void *arg = va_arg(*p_va, void *);
257 ++*p_format;
258 return (*func)(arg);
259 }
260 else {
261 PyObject *v;
262 v = va_arg(*p_va, PyObject *);
263 if (v != NULL) {
264 if (*(*p_format - 1) != 'N')
265 Py_INCREF(v);
266 }
267 else
268 printf("NULL object passed to Py_BuildValue");
269 return v;
270 }
271
272 case ':':
273 case ',':
274 case ' ':
275 case '\t':
276 break;
277
278 default:
279 printf("bad format char passed to Py_BuildValue\n");
280 return NULL;
281
282 }
283 }
284}
285
286PyObject *
287Py_VaBuildValue(char *format, va_list va)
288{
289 char *f = format;
290 int n = countformat(f, '\0');
291 va_list lva;
292
293 lva = va;
294
295 if (n < 0)
296 return NULL;
297 if (n == 0) {
298 Py_INCREF(Py_None);
299 return Py_None;
300 }
301 if (n == 1)
302 return do_mkvalue(&f, &lva);
303 return do_mktuple(&f, &lva, '\0', n);
304}
305
306PyObject *
307Py_BuildValue(char *format, ...)
308{
309 va_list va;
310 PyObject* retval;
311 va_start(va, format);
312 retval = Py_VaBuildValue(format, va);
313 va_end(va);
314 return retval;
315}
316
317PyObject *
318PyEval_CallFunction(PyObject *obj, char *format, ...)
319{
320 va_list vargs;
321 PyObject *args;
322 PyObject *res;
323
324 va_start(vargs, format);
325
326 args = Py_VaBuildValue(format, vargs);
327 va_end(vargs);
328
329 if (args == NULL)
330 return NULL;
331
332 res = PyEval_CallObject(obj, args);
333 Py_DECREF(args);
334
335 return res;
336}
337
338PyObject *
339PyEval_CallMethod(PyObject *obj, char *methodname, char *format, ...)
340{
341 va_list vargs;
342 PyObject *meth;
343 PyObject *args;
344 PyObject *res;
345
346 meth = PyObject_GetAttrString(obj, methodname);
347 if (meth == NULL)
348 return NULL;
349
350 va_start(vargs, format);
351
352 args = Py_VaBuildValue(format, vargs);
353 va_end(vargs);
354
355 if (args == NULL) {
356 Py_DECREF(meth);
357 return NULL;
358 }
359
360 res = PyEval_CallObject(meth, args);
361 Py_DECREF(meth);
362 Py_DECREF(args);
363
364 return res;
365}
366
367int
368PyModule_AddObject(PyObject *m, char *name, PyObject *o)
369{
370 PyObject *dict;
371 if (!PyModule_Check(m)) {
372 PyErr_SetString(PyExc_TypeError,
373 "PyModule_AddObject() needs module as first arg");
374 return -1;
375 }
376 if (!o) {
377 PyErr_SetString(PyExc_TypeError,
378 "PyModule_AddObject() needs non-NULL value");
379 return -1;
380 }
381
382 dict = PyModule_GetDict(m);
383 if (dict == NULL) {
384 /* Internal error -- modules must have a dict! */
385 PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
386 PyModule_GetName(m));
387 return -1;
388 }
389 if (PyDict_SetItemString(dict, name, o))
390 return -1;
391 Py_DECREF(o);
392 return 0;
393}
394
395int
396PyModule_AddIntConstant(PyObject *m, char *name, long value)
397{
398 return PyModule_AddObject(m, name, PyInt_FromLong(value));
399}
400
401int
402PyModule_AddStringConstant(PyObject *m, char *name, char *value)
403{
404 return PyModule_AddObject(m, name, PyString_FromString(value));
405}