+++ /dev/null
-\r
-/* Use this file as a template to start implementing a module that\r
- also declares object types. All occurrences of 'Xxo' should be changed\r
- to something reasonable for your objects. After that, all other\r
- occurrences of 'xx' should be changed to something reasonable for your\r
- module. If your module is named foo your sourcefile should be named\r
- foomodule.c.\r
-\r
- You will probably want to delete all references to 'x_attr' and add\r
- your own types of attributes instead. Maybe you want to name your\r
- local variables other than 'self'. If your object type is needed in\r
- other files, you'll have to create a file "foobarobject.h"; see\r
- intobject.h for an example. */\r
-\r
-/* Xxo objects */\r
-\r
-#include "Python.h"\r
-\r
-static PyObject *ErrorObject;\r
-\r
-typedef struct {\r
- PyObject_HEAD\r
- PyObject *x_attr; /* Attributes dictionary */\r
-} XxoObject;\r
-\r
-static PyTypeObject Xxo_Type;\r
-\r
-#define XxoObject_Check(v) (Py_TYPE(v) == &Xxo_Type)\r
-\r
-static XxoObject *\r
-newXxoObject(PyObject *arg)\r
-{\r
- XxoObject *self;\r
- self = PyObject_New(XxoObject, &Xxo_Type);\r
- if (self == NULL)\r
- return NULL;\r
- self->x_attr = NULL;\r
- return self;\r
-}\r
-\r
-/* Xxo methods */\r
-\r
-static void\r
-Xxo_dealloc(XxoObject *self)\r
-{\r
- Py_XDECREF(self->x_attr);\r
- PyObject_Del(self);\r
-}\r
-\r
-static PyObject *\r
-Xxo_demo(XxoObject *self, PyObject *args)\r
-{\r
- if (!PyArg_ParseTuple(args, ":demo"))\r
- return NULL;\r
- Py_INCREF(Py_None);\r
- return Py_None;\r
-}\r
-\r
-static PyMethodDef Xxo_methods[] = {\r
- {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,\r
- PyDoc_STR("demo() -> None")},\r
- {NULL, NULL} /* sentinel */\r
-};\r
-\r
-static PyObject *\r
-Xxo_getattr(XxoObject *self, char *name)\r
-{\r
- if (self->x_attr != NULL) {\r
- PyObject *v = PyDict_GetItemString(self->x_attr, name);\r
- if (v != NULL) {\r
- Py_INCREF(v);\r
- return v;\r
- }\r
- }\r
- return Py_FindMethod(Xxo_methods, (PyObject *)self, name);\r
-}\r
-\r
-static int\r
-Xxo_setattr(XxoObject *self, char *name, PyObject *v)\r
-{\r
- if (self->x_attr == NULL) {\r
- self->x_attr = PyDict_New();\r
- if (self->x_attr == NULL)\r
- return -1;\r
- }\r
- if (v == NULL) {\r
- int rv = PyDict_DelItemString(self->x_attr, name);\r
- if (rv < 0)\r
- PyErr_SetString(PyExc_AttributeError,\r
- "delete non-existing Xxo attribute");\r
- return rv;\r
- }\r
- else\r
- return PyDict_SetItemString(self->x_attr, name, v);\r
-}\r
-\r
-static PyTypeObject Xxo_Type = {\r
- /* The ob_type field must be initialized in the module init function\r
- * to be portable to Windows without using C++. */\r
- PyVarObject_HEAD_INIT(NULL, 0)\r
- "xxmodule.Xxo", /*tp_name*/\r
- sizeof(XxoObject), /*tp_basicsize*/\r
- 0, /*tp_itemsize*/\r
- /* methods */\r
- (destructor)Xxo_dealloc, /*tp_dealloc*/\r
- 0, /*tp_print*/\r
- (getattrfunc)Xxo_getattr, /*tp_getattr*/\r
- (setattrfunc)Xxo_setattr, /*tp_setattr*/\r
- 0, /*tp_compare*/\r
- 0, /*tp_repr*/\r
- 0, /*tp_as_number*/\r
- 0, /*tp_as_sequence*/\r
- 0, /*tp_as_mapping*/\r
- 0, /*tp_hash*/\r
- 0, /*tp_call*/\r
- 0, /*tp_str*/\r
- 0, /*tp_getattro*/\r
- 0, /*tp_setattro*/\r
- 0, /*tp_as_buffer*/\r
- Py_TPFLAGS_DEFAULT, /*tp_flags*/\r
- 0, /*tp_doc*/\r
- 0, /*tp_traverse*/\r
- 0, /*tp_clear*/\r
- 0, /*tp_richcompare*/\r
- 0, /*tp_weaklistoffset*/\r
- 0, /*tp_iter*/\r
- 0, /*tp_iternext*/\r
- 0, /*tp_methods*/\r
- 0, /*tp_members*/\r
- 0, /*tp_getset*/\r
- 0, /*tp_base*/\r
- 0, /*tp_dict*/\r
- 0, /*tp_descr_get*/\r
- 0, /*tp_descr_set*/\r
- 0, /*tp_dictoffset*/\r
- 0, /*tp_init*/\r
- 0, /*tp_alloc*/\r
- 0, /*tp_new*/\r
- 0, /*tp_free*/\r
- 0, /*tp_is_gc*/\r
-};\r
-/* --------------------------------------------------------------------- */\r
-\r
-/* Function of two integers returning integer */\r
-\r
-PyDoc_STRVAR(xx_foo_doc,\r
-"foo(i,j)\n\\r
-\n\\r
-Return the sum of i and j.");\r
-\r
-static PyObject *\r
-xx_foo(PyObject *self, PyObject *args)\r
-{\r
- long i, j;\r
- long res;\r
- if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))\r
- return NULL;\r
- res = i+j; /* XXX Do something here */\r
- return PyInt_FromLong(res);\r
-}\r
-\r
-\r
-/* Function of no arguments returning new Xxo object */\r
-\r
-static PyObject *\r
-xx_new(PyObject *self, PyObject *args)\r
-{\r
- XxoObject *rv;\r
-\r
- if (!PyArg_ParseTuple(args, ":new"))\r
- return NULL;\r
- rv = newXxoObject(args);\r
- if (rv == NULL)\r
- return NULL;\r
- return (PyObject *)rv;\r
-}\r
-\r
-/* Example with subtle bug from extensions manual ("Thin Ice"). */\r
-\r
-static PyObject *\r
-xx_bug(PyObject *self, PyObject *args)\r
-{\r
- PyObject *list, *item;\r
-\r
- if (!PyArg_ParseTuple(args, "O:bug", &list))\r
- return NULL;\r
-\r
- item = PyList_GetItem(list, 0);\r
- /* Py_INCREF(item); */\r
- PyList_SetItem(list, 1, PyInt_FromLong(0L));\r
- PyObject_Print(item, stdout, 0);\r
- printf("\n");\r
- /* Py_DECREF(item); */\r
-\r
- Py_INCREF(Py_None);\r
- return Py_None;\r
-}\r
-\r
-/* Test bad format character */\r
-\r
-static PyObject *\r
-xx_roj(PyObject *self, PyObject *args)\r
-{\r
- PyObject *a;\r
- long b;\r
- if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))\r
- return NULL;\r
- Py_INCREF(Py_None);\r
- return Py_None;\r
-}\r
-\r
-\r
-/* ---------- */\r
-\r
-static PyTypeObject Str_Type = {\r
- /* The ob_type field must be initialized in the module init function\r
- * to be portable to Windows without using C++. */\r
- PyVarObject_HEAD_INIT(NULL, 0)\r
- "xxmodule.Str", /*tp_name*/\r
- 0, /*tp_basicsize*/\r
- 0, /*tp_itemsize*/\r
- /* methods */\r
- 0, /*tp_dealloc*/\r
- 0, /*tp_print*/\r
- 0, /*tp_getattr*/\r
- 0, /*tp_setattr*/\r
- 0, /*tp_compare*/\r
- 0, /*tp_repr*/\r
- 0, /*tp_as_number*/\r
- 0, /*tp_as_sequence*/\r
- 0, /*tp_as_mapping*/\r
- 0, /*tp_hash*/\r
- 0, /*tp_call*/\r
- 0, /*tp_str*/\r
- 0, /*tp_getattro*/\r
- 0, /*tp_setattro*/\r
- 0, /*tp_as_buffer*/\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/\r
- 0, /*tp_doc*/\r
- 0, /*tp_traverse*/\r
- 0, /*tp_clear*/\r
- 0, /*tp_richcompare*/\r
- 0, /*tp_weaklistoffset*/\r
- 0, /*tp_iter*/\r
- 0, /*tp_iternext*/\r
- 0, /*tp_methods*/\r
- 0, /*tp_members*/\r
- 0, /*tp_getset*/\r
- 0, /* see initxx */ /*tp_base*/\r
- 0, /*tp_dict*/\r
- 0, /*tp_descr_get*/\r
- 0, /*tp_descr_set*/\r
- 0, /*tp_dictoffset*/\r
- 0, /*tp_init*/\r
- 0, /*tp_alloc*/\r
- 0, /*tp_new*/\r
- 0, /*tp_free*/\r
- 0, /*tp_is_gc*/\r
-};\r
-\r
-/* ---------- */\r
-\r
-static PyObject *\r
-null_richcompare(PyObject *self, PyObject *other, int op)\r
-{\r
- Py_INCREF(Py_NotImplemented);\r
- return Py_NotImplemented;\r
-}\r
-\r
-static PyTypeObject Null_Type = {\r
- /* The ob_type field must be initialized in the module init function\r
- * to be portable to Windows without using C++. */\r
- PyVarObject_HEAD_INIT(NULL, 0)\r
- "xxmodule.Null", /*tp_name*/\r
- 0, /*tp_basicsize*/\r
- 0, /*tp_itemsize*/\r
- /* methods */\r
- 0, /*tp_dealloc*/\r
- 0, /*tp_print*/\r
- 0, /*tp_getattr*/\r
- 0, /*tp_setattr*/\r
- 0, /*tp_compare*/\r
- 0, /*tp_repr*/\r
- 0, /*tp_as_number*/\r
- 0, /*tp_as_sequence*/\r
- 0, /*tp_as_mapping*/\r
- 0, /*tp_hash*/\r
- 0, /*tp_call*/\r
- 0, /*tp_str*/\r
- 0, /*tp_getattro*/\r
- 0, /*tp_setattro*/\r
- 0, /*tp_as_buffer*/\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/\r
- 0, /*tp_doc*/\r
- 0, /*tp_traverse*/\r
- 0, /*tp_clear*/\r
- null_richcompare, /*tp_richcompare*/\r
- 0, /*tp_weaklistoffset*/\r
- 0, /*tp_iter*/\r
- 0, /*tp_iternext*/\r
- 0, /*tp_methods*/\r
- 0, /*tp_members*/\r
- 0, /*tp_getset*/\r
- 0, /* see initxx */ /*tp_base*/\r
- 0, /*tp_dict*/\r
- 0, /*tp_descr_get*/\r
- 0, /*tp_descr_set*/\r
- 0, /*tp_dictoffset*/\r
- 0, /*tp_init*/\r
- 0, /*tp_alloc*/\r
- 0, /* see initxx */ /*tp_new*/\r
- 0, /*tp_free*/\r
- 0, /*tp_is_gc*/\r
-};\r
-\r
-\r
-/* ---------- */\r
-\r
-\r
-/* List of functions defined in the module */\r
-\r
-static PyMethodDef xx_methods[] = {\r
- {"roj", xx_roj, METH_VARARGS,\r
- PyDoc_STR("roj(a,b) -> None")},\r
- {"foo", xx_foo, METH_VARARGS,\r
- xx_foo_doc},\r
- {"new", xx_new, METH_VARARGS,\r
- PyDoc_STR("new() -> new Xx object")},\r
- {"bug", xx_bug, METH_VARARGS,\r
- PyDoc_STR("bug(o) -> None")},\r
- {NULL, NULL} /* sentinel */\r
-};\r
-\r
-PyDoc_STRVAR(module_doc,\r
-"This is a template module just for instruction.");\r
-\r
-/* Initialization function for the module (*must* be called initxx) */\r
-\r
-PyMODINIT_FUNC\r
-initxx(void)\r
-{\r
- PyObject *m;\r
-\r
- /* Due to cross platform compiler issues the slots must be filled\r
- * here. It's required for portability to Windows without requiring\r
- * C++. */\r
- Null_Type.tp_base = &PyBaseObject_Type;\r
- Null_Type.tp_new = PyType_GenericNew;\r
- Str_Type.tp_base = &PyUnicode_Type;\r
-\r
- /* Finalize the type object including setting type of the new type\r
- * object; doing it here is required for portability, too. */\r
- if (PyType_Ready(&Xxo_Type) < 0)\r
- return;\r
-\r
- /* Create the module and add the functions */\r
- m = Py_InitModule3("xx", xx_methods, module_doc);\r
- if (m == NULL)\r
- return;\r
-\r
- /* Add some symbolic constants to the module */\r
- if (ErrorObject == NULL) {\r
- ErrorObject = PyErr_NewException("xx.error", NULL, NULL);\r
- if (ErrorObject == NULL)\r
- return;\r
- }\r
- Py_INCREF(ErrorObject);\r
- PyModule_AddObject(m, "error", ErrorObject);\r
-\r
- /* Add Str */\r
- if (PyType_Ready(&Str_Type) < 0)\r
- return;\r
- PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);\r
-\r
- /* Add Null */\r
- if (PyType_Ready(&Null_Type) < 0)\r
- return;\r
- PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);\r
-}\r