PageRenderTime 32ms CodeModel.GetById 17ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/lib/libPython/Python/Objects/methodobject.c

https://github.com/tmacreturns/XBMC_wireless_setup
C | 374 lines | 326 code | 36 blank | 12 comment | 90 complexity | e022a5465aac48dfd9dc8cb8eea41a31 MD5 | raw file
  1
  2/* Method object implementation */
  3
  4#include "Python.h"
  5#include "structmember.h"
  6
  7static PyCFunctionObject *free_list = NULL;
  8
  9PyObject *
 10PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
 11{
 12	PyCFunctionObject *op;
 13	op = free_list;
 14	if (op != NULL) {
 15		free_list = (PyCFunctionObject *)(op->m_self);
 16		PyObject_INIT(op, &PyCFunction_Type);
 17	}
 18	else {
 19		op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
 20		if (op == NULL)
 21			return NULL;
 22	}
 23	op->m_ml = ml;
 24	Py_XINCREF(self);
 25	op->m_self = self;
 26	Py_XINCREF(module);
 27	op->m_module = module;
 28	_PyObject_GC_TRACK(op);
 29	return (PyObject *)op;
 30}
 31
 32PyCFunction
 33PyCFunction_GetFunction(PyObject *op)
 34{
 35	if (!PyCFunction_Check(op)) {
 36		PyErr_BadInternalCall();
 37		return NULL;
 38	}
 39	return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
 40}
 41
 42PyObject *
 43PyCFunction_GetSelf(PyObject *op)
 44{
 45	if (!PyCFunction_Check(op)) {
 46		PyErr_BadInternalCall();
 47		return NULL;
 48	}
 49	return ((PyCFunctionObject *)op) -> m_self;
 50}
 51
 52int
 53PyCFunction_GetFlags(PyObject *op)
 54{
 55	if (!PyCFunction_Check(op)) {
 56		PyErr_BadInternalCall();
 57		return -1;
 58	}
 59	return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
 60}
 61
 62PyObject *
 63PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
 64{
 65	PyCFunctionObject* f = (PyCFunctionObject*)func;
 66	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
 67	PyObject *self = PyCFunction_GET_SELF(func);
 68	int size;
 69
 70	switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
 71	case METH_VARARGS:
 72		if (kw == NULL || PyDict_Size(kw) == 0)
 73			return (*meth)(self, arg);
 74		break;
 75	case METH_VARARGS | METH_KEYWORDS:
 76	case METH_OLDARGS | METH_KEYWORDS:
 77		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
 78	case METH_NOARGS:
 79		if (kw == NULL || PyDict_Size(kw) == 0) {
 80			size = PyTuple_GET_SIZE(arg);
 81			if (size == 0)
 82				return (*meth)(self, NULL);
 83			PyErr_Format(PyExc_TypeError,
 84			    "%.200s() takes no arguments (%d given)",
 85			    f->m_ml->ml_name, size);
 86			return NULL;
 87		}
 88		break;
 89	case METH_O:
 90		if (kw == NULL || PyDict_Size(kw) == 0) {
 91			size = PyTuple_GET_SIZE(arg);
 92			if (size == 1)
 93				return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
 94			PyErr_Format(PyExc_TypeError,
 95			    "%.200s() takes exactly one argument (%d given)",
 96			    f->m_ml->ml_name, size);
 97			return NULL;
 98		}
 99		break;
100	case METH_OLDARGS:
101		/* the really old style */
102		if (kw == NULL || PyDict_Size(kw) == 0) {
103			size = PyTuple_GET_SIZE(arg);
104			if (size == 1)
105				arg = PyTuple_GET_ITEM(arg, 0);
106			else if (size == 0)
107				arg = NULL;
108			return (*meth)(self, arg);
109		}
110		break;
111	default:
112		PyErr_BadInternalCall();
113		return NULL;
114	}
115	PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
116		     f->m_ml->ml_name);
117	return NULL;
118}
119
120/* Methods (the standard built-in methods, that is) */
121
122static void
123meth_dealloc(PyCFunctionObject *m)
124{
125	_PyObject_GC_UNTRACK(m);
126	Py_XDECREF(m->m_self);
127	Py_XDECREF(m->m_module);
128	m->m_self = (PyObject *)free_list;
129	free_list = m;
130}
131
132static PyObject *
133meth_get__doc__(PyCFunctionObject *m, void *closure)
134{
135	char *doc = m->m_ml->ml_doc;
136
137	if (doc != NULL)
138		return PyString_FromString(doc);
139	Py_INCREF(Py_None);
140	return Py_None;
141}
142
143static PyObject *
144meth_get__name__(PyCFunctionObject *m, void *closure)
145{
146	return PyString_FromString(m->m_ml->ml_name);
147}
148
149static int
150meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
151{
152	int err;
153	if (m->m_self != NULL) {
154		err = visit(m->m_self, arg);
155		if (err)
156			return err;
157	}
158	if (m->m_module != NULL) {
159		err = visit(m->m_module, arg);
160		if (err)
161			return err;
162	}
163	return 0;
164}
165
166static PyObject *
167meth_get__self__(PyCFunctionObject *m, void *closure)
168{
169	PyObject *self;
170	if (PyEval_GetRestricted()) {
171		PyErr_SetString(PyExc_RuntimeError,
172			"method.__self__ not accessible in restricted mode");
173		return NULL;
174	}
175	self = m->m_self;
176	if (self == NULL)
177		self = Py_None;
178	Py_INCREF(self);
179	return self;
180}
181
182static PyGetSetDef meth_getsets [] = {
183	{"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
184	{"__name__", (getter)meth_get__name__, NULL, NULL},
185	{"__self__", (getter)meth_get__self__, NULL, NULL},
186	{0}
187};
188
189#define OFF(x) offsetof(PyCFunctionObject, x)
190
191static PyMemberDef meth_members[] = {
192	{"__module__",    T_OBJECT,     OFF(m_module), WRITE_RESTRICTED},
193	{NULL}
194};
195
196static PyObject *
197meth_repr(PyCFunctionObject *m)
198{
199	if (m->m_self == NULL)
200		return PyString_FromFormat("<built-in function %s>",
201					   m->m_ml->ml_name);
202	return PyString_FromFormat("<built-in method %s of %s object at %p>",
203				   m->m_ml->ml_name,
204				   m->m_self->ob_type->tp_name,
205				   m->m_self);
206}
207
208static int
209meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
210{
211	if (a->m_self != b->m_self)
212		return (a->m_self < b->m_self) ? -1 : 1;
213	if (a->m_ml->ml_meth == b->m_ml->ml_meth)
214		return 0;
215	if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
216		return -1;
217	else
218		return 1;
219}
220
221static long
222meth_hash(PyCFunctionObject *a)
223{
224	long x,y;
225	if (a->m_self == NULL)
226		x = 0;
227	else {
228		x = PyObject_Hash(a->m_self);
229		if (x == -1)
230			return -1;
231	}
232	y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
233	if (y == -1)
234		return -1;
235	x ^= y;
236	if (x == -1)
237		x = -2;
238	return x;
239}
240
241
242PyTypeObject PyCFunction_Type = {
243	PyObject_HEAD_INIT(&PyType_Type)
244	0,
245	"builtin_function_or_method",
246	sizeof(PyCFunctionObject),
247	0,
248	(destructor)meth_dealloc, 		/* tp_dealloc */
249	0,					/* tp_print */
250	0,					/* tp_getattr */
251	0,					/* tp_setattr */
252	(cmpfunc)meth_compare,			/* tp_compare */
253	(reprfunc)meth_repr,			/* tp_repr */
254	0,					/* tp_as_number */
255	0,					/* tp_as_sequence */
256	0,					/* tp_as_mapping */
257	(hashfunc)meth_hash,			/* tp_hash */
258	PyCFunction_Call,			/* tp_call */
259	0,					/* tp_str */
260	PyObject_GenericGetAttr,		/* tp_getattro */
261	0,					/* tp_setattro */
262	0,					/* tp_as_buffer */
263	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
264 	0,					/* tp_doc */
265 	(traverseproc)meth_traverse,		/* tp_traverse */
266	0,					/* tp_clear */
267	0,					/* tp_richcompare */
268	0,					/* tp_weaklistoffset */
269	0,					/* tp_iter */
270	0,					/* tp_iternext */
271	0,					/* tp_methods */
272	meth_members,				/* tp_members */
273	meth_getsets,				/* tp_getset */
274	0,					/* tp_base */
275	0,					/* tp_dict */
276};
277
278/* List all methods in a chain -- helper for findmethodinchain */
279
280static PyObject *
281listmethodchain(PyMethodChain *chain)
282{
283	PyMethodChain *c;
284	PyMethodDef *ml;
285	int i, n;
286	PyObject *v;
287
288	n = 0;
289	for (c = chain; c != NULL; c = c->link) {
290		for (ml = c->methods; ml->ml_name != NULL; ml++)
291			n++;
292	}
293	v = PyList_New(n);
294	if (v == NULL)
295		return NULL;
296	i = 0;
297	for (c = chain; c != NULL; c = c->link) {
298		for (ml = c->methods; ml->ml_name != NULL; ml++) {
299			PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
300			i++;
301		}
302	}
303	if (PyErr_Occurred()) {
304		Py_DECREF(v);
305		return NULL;
306	}
307	PyList_Sort(v);
308	return v;
309}
310
311/* Find a method in a method chain */
312
313PyObject *
314Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, char *name)
315{
316	if (name[0] == '_' && name[1] == '_') {
317		if (strcmp(name, "__methods__") == 0)
318			return listmethodchain(chain);
319		if (strcmp(name, "__doc__") == 0) {
320			char *doc = self->ob_type->tp_doc;
321			if (doc != NULL)
322				return PyString_FromString(doc);
323		}
324	}
325	while (chain != NULL) {
326		PyMethodDef *ml = chain->methods;
327		for (; ml->ml_name != NULL; ml++) {
328			if (name[0] == ml->ml_name[0] &&
329			    strcmp(name+1, ml->ml_name+1) == 0)
330				/* XXX */
331				return PyCFunction_New(ml, self);
332		}
333		chain = chain->link;
334	}
335	PyErr_SetString(PyExc_AttributeError, name);
336	return NULL;
337}
338
339/* Find a method in a single method list */
340
341PyObject *
342Py_FindMethod(PyMethodDef *methods, PyObject *self, char *name)
343{
344	PyMethodChain chain;
345	chain.methods = methods;
346	chain.link = NULL;
347	return Py_FindMethodInChain(&chain, self, name);
348}
349
350/* Clear out the free list */
351
352void
353PyCFunction_Fini(void)
354{
355	while (free_list) {
356		PyCFunctionObject *v = free_list;
357		free_list = (PyCFunctionObject *)(v->m_self);
358		PyObject_GC_Del(v);
359	}
360}
361
362/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
363   but it's part of the API so we need to keep a function around that
364   existing C extensions can call.
365*/
366   
367#undef PyCFunction_New
368PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
369
370PyObject *
371PyCFunction_New(PyMethodDef *ml, PyObject *self)
372{
373	return PyCFunction_NewEx(ml, self, NULL);
374}