PageRenderTime 38ms CodeModel.GetById 18ms app.highlight 17ms RepoModel.GetById 0ms app.codeStats 1ms

/necco/python/Python/modsupport.c

https://github.com/brosner/cleese
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}