#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 PyTypeObject spamlist_type;

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 = {
	PyObject_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 PyTypeObject spamdict_type;

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 = {
	PyObject_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;
}
