diff -r ffa851df0825 -r 2fb8b9db1c86 symbian-qemu-0.9.1-12/python-2.6.1/Modules/xxsubtype.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian-qemu-0.9.1-12/python-2.6.1/Modules/xxsubtype.c Fri Jul 31 15:01:17 2009 +0100 @@ -0,0 +1,297 @@ +#include "Python.h" +#include "structmember.h" + +PyDoc_STRVAR(xxsubtype__doc__, +"xxsubtype is an example module showing how to subtype builtin types from C.\n" +"test_descr.py in the standard test suite requires it in order to complete.\n" +"If you don't care about the examples, and don't intend to run the Python\n" +"test suite, you can recompile Python without Modules/xxsubtype.c."); + +/* We link this module statically for convenience. If compiled as a shared + library instead, some compilers don't allow addresses of Python objects + defined in other libraries to be used in static initializers here. The + DEFERRED_ADDRESS macro is used to tag the slots where such addresses + appear; the module init function must fill in the tagged slots at runtime. + The argument is for documentation -- the macro ignores it. +*/ +#define DEFERRED_ADDRESS(ADDR) 0 + +/* spamlist -- a list subtype */ + +typedef struct { + PyListObject list; + int state; +} spamlistobject; + +static PyObject * +spamlist_getstate(spamlistobject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":getstate")) + return NULL; + return PyInt_FromLong(self->state); +} + +static PyObject * +spamlist_setstate(spamlistobject *self, PyObject *args) +{ + int state; + + if (!PyArg_ParseTuple(args, "i:setstate", &state)) + return NULL; + self->state = state; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *result = PyTuple_New(3); + + if (result != NULL) { + if (self == NULL) + self = Py_None; + if (kw == NULL) + kw = Py_None; + Py_INCREF(self); + PyTuple_SET_ITEM(result, 0, self); + Py_INCREF(args); + PyTuple_SET_ITEM(result, 1, args); + Py_INCREF(kw); + PyTuple_SET_ITEM(result, 2, kw); + } + return result; +} + +static PyMethodDef spamlist_methods[] = { + {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS, + PyDoc_STR("getstate() -> state")}, + {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS, + PyDoc_STR("setstate(state)")}, + /* These entries differ only in the flags; they are used by the tests + in test.test_descr. */ + {"classmeth", (PyCFunction)spamlist_specialmeth, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("classmeth(*args, **kw)")}, + {"staticmeth", (PyCFunction)spamlist_specialmeth, + METH_VARARGS | METH_KEYWORDS | METH_STATIC, + PyDoc_STR("staticmeth(*args, **kw)")}, + {NULL, NULL}, +}; + +static int +spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds) +{ + if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0) + return -1; + self->state = 0; + return 0; +} + +static PyObject * +spamlist_state_get(spamlistobject *self) +{ + return PyInt_FromLong(self->state); +} + +static PyGetSetDef spamlist_getsets[] = { + {"state", (getter)spamlist_state_get, NULL, + PyDoc_STR("an int variable for demonstration purposes")}, + {0} +}; + +static PyTypeObject spamlist_type = { + PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) + "xxsubtype.spamlist", + sizeof(spamlistobject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + spamlist_methods, /* tp_methods */ + 0, /* tp_members */ + spamlist_getsets, /* tp_getset */ + DEFERRED_ADDRESS(&PyList_Type), /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)spamlist_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +/* spamdict -- a dict subtype */ + +typedef struct { + PyDictObject dict; + int state; +} spamdictobject; + +static PyObject * +spamdict_getstate(spamdictobject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":getstate")) + return NULL; + return PyInt_FromLong(self->state); +} + +static PyObject * +spamdict_setstate(spamdictobject *self, PyObject *args) +{ + int state; + + if (!PyArg_ParseTuple(args, "i:setstate", &state)) + return NULL; + self->state = state; + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef spamdict_methods[] = { + {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS, + PyDoc_STR("getstate() -> state")}, + {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS, + PyDoc_STR("setstate(state)")}, + {NULL, NULL}, +}; + +static int +spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds) +{ + if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) + return -1; + self->state = 0; + return 0; +} + +static PyMemberDef spamdict_members[] = { + {"state", T_INT, offsetof(spamdictobject, state), READONLY, + PyDoc_STR("an int variable for demonstration purposes")}, + {0} +}; + +static PyTypeObject spamdict_type = { + PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) + "xxsubtype.spamdict", + sizeof(spamdictobject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + spamdict_methods, /* tp_methods */ + spamdict_members, /* tp_members */ + 0, /* tp_getset */ + DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)spamdict_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +static PyObject * +spam_bench(PyObject *self, PyObject *args) +{ + PyObject *obj, *name, *res; + int n = 1000; + time_t t0, t1; + + if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n)) + return NULL; + t0 = clock(); + while (--n >= 0) { + res = PyObject_GetAttr(obj, name); + if (res == NULL) + return NULL; + Py_DECREF(res); + } + t1 = clock(); + return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC); +} + +static PyMethodDef xxsubtype_functions[] = { + {"bench", spam_bench, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + +PyMODINIT_FUNC +initxxsubtype(void) +{ + PyObject *m; + + /* Fill in deferred data addresses. This must be done before + PyType_Ready() is called. Note that PyType_Ready() automatically + initializes the ob.ob_type field to &PyType_Type if it's NULL, + so it's not necessary to fill in ob_type first. */ + spamdict_type.tp_base = &PyDict_Type; + if (PyType_Ready(&spamdict_type) < 0) + return; + + spamlist_type.tp_base = &PyList_Type; + if (PyType_Ready(&spamlist_type) < 0) + return; + + m = Py_InitModule3("xxsubtype", + xxsubtype_functions, + xxsubtype__doc__); + if (m == NULL) + return; + + if (PyType_Ready(&spamlist_type) < 0) + return; + if (PyType_Ready(&spamdict_type) < 0) + return; + + Py_INCREF(&spamlist_type); + if (PyModule_AddObject(m, "spamlist", + (PyObject *) &spamlist_type) < 0) + return; + + Py_INCREF(&spamdict_type); + if (PyModule_AddObject(m, "spamdict", + (PyObject *) &spamdict_type) < 0) + return; +}