blob: 9feb71aae3be5b0e9a62a45d7ce63067ac936f2e [file] [log] [blame]
Georg Brandl8ec7f652007-08-15 14:28:01 +00001#include <Python.h>
2#include "structmember.h"
3
4typedef struct {
5 PyObject_HEAD
6 PyObject *first;
7 PyObject *last;
8 int number;
9} Noddy;
10
11static int
12Noddy_traverse(Noddy *self, visitproc visit, void *arg)
13{
14 int vret;
15
16 if (self->first) {
17 vret = visit(self->first, arg);
18 if (vret != 0)
19 return vret;
20 }
21 if (self->last) {
22 vret = visit(self->last, arg);
23 if (vret != 0)
24 return vret;
25 }
26
27 return 0;
28}
29
INADA Naoki9436bbd2017-02-21 21:12:03 +090030static int
Georg Brandl8ec7f652007-08-15 14:28:01 +000031Noddy_clear(Noddy *self)
32{
33 PyObject *tmp;
34
35 tmp = self->first;
36 self->first = NULL;
37 Py_XDECREF(tmp);
38
39 tmp = self->last;
40 self->last = NULL;
41 Py_XDECREF(tmp);
42
43 return 0;
44}
45
46static void
47Noddy_dealloc(Noddy* self)
48{
49 Noddy_clear(self);
INADA Naoki9436bbd2017-02-21 21:12:03 +090050 Py_TYPE(self)->tp_free((PyObject*)self);
Georg Brandl8ec7f652007-08-15 14:28:01 +000051}
52
53static PyObject *
54Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
55{
56 Noddy *self;
57
58 self = (Noddy *)type->tp_alloc(type, 0);
59 if (self != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +000060 self->first = PyString_FromString("");
INADA Naoki9436bbd2017-02-21 21:12:03 +090061 if (self->first == NULL) {
Georg Brandl8ec7f652007-08-15 14:28:01 +000062 Py_DECREF(self);
63 return NULL;
INADA Naoki9436bbd2017-02-21 21:12:03 +090064 }
65
Gregory P. Smithdd96db62008-06-09 04:58:54 +000066 self->last = PyString_FromString("");
INADA Naoki9436bbd2017-02-21 21:12:03 +090067 if (self->last == NULL) {
Georg Brandl8ec7f652007-08-15 14:28:01 +000068 Py_DECREF(self);
69 return NULL;
INADA Naoki9436bbd2017-02-21 21:12:03 +090070 }
Georg Brandl8ec7f652007-08-15 14:28:01 +000071
72 self->number = 0;
73 }
74
75 return (PyObject *)self;
76}
77
78static int
79Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
80{
81 PyObject *first=NULL, *last=NULL, *tmp;
82
83 static char *kwlist[] = {"first", "last", "number", NULL};
84
INADA Naoki9436bbd2017-02-21 21:12:03 +090085 if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
86 &first, &last,
Georg Brandl8ec7f652007-08-15 14:28:01 +000087 &self->number))
INADA Naoki9436bbd2017-02-21 21:12:03 +090088 return -1;
Georg Brandl8ec7f652007-08-15 14:28:01 +000089
90 if (first) {
91 tmp = self->first;
92 Py_INCREF(first);
93 self->first = first;
94 Py_XDECREF(tmp);
95 }
96
97 if (last) {
98 tmp = self->last;
99 Py_INCREF(last);
100 self->last = last;
101 Py_XDECREF(tmp);
102 }
103
104 return 0;
105}
106
107
108static PyMemberDef Noddy_members[] = {
109 {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
110 "first name"},
111 {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
112 "last name"},
113 {"number", T_INT, offsetof(Noddy, number), 0,
114 "noddy number"},
115 {NULL} /* Sentinel */
116};
117
118static PyObject *
119Noddy_name(Noddy* self)
120{
121 static PyObject *format = NULL;
122 PyObject *args, *result;
123
124 if (format == NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000125 format = PyString_FromString("%s %s");
Georg Brandl8ec7f652007-08-15 14:28:01 +0000126 if (format == NULL)
127 return NULL;
128 }
129
130 if (self->first == NULL) {
131 PyErr_SetString(PyExc_AttributeError, "first");
132 return NULL;
133 }
134
135 if (self->last == NULL) {
136 PyErr_SetString(PyExc_AttributeError, "last");
137 return NULL;
138 }
139
140 args = Py_BuildValue("OO", self->first, self->last);
141 if (args == NULL)
142 return NULL;
143
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000144 result = PyString_Format(format, args);
Georg Brandl8ec7f652007-08-15 14:28:01 +0000145 Py_DECREF(args);
INADA Naoki9436bbd2017-02-21 21:12:03 +0900146
Georg Brandl8ec7f652007-08-15 14:28:01 +0000147 return result;
148}
149
150static PyMethodDef Noddy_methods[] = {
151 {"name", (PyCFunction)Noddy_name, METH_NOARGS,
152 "Return the name, combining the first and last name"
153 },
154 {NULL} /* Sentinel */
155};
156
157static PyTypeObject NoddyType = {
INADA Naoki9436bbd2017-02-21 21:12:03 +0900158 PyVarObject_HEAD_INIT(NULL, 0)
159 "noddy.Noddy", /* tp_name */
160 sizeof(Noddy), /* tp_basicsize */
161 0, /* tp_itemsize */
162 (destructor)Noddy_dealloc, /* tp_dealloc */
163 0, /* tp_print */
164 0, /* tp_getattr */
165 0, /* tp_setattr */
166 0, /* tp_compare */
167 0, /* tp_repr */
168 0, /* tp_as_number */
169 0, /* tp_as_sequence */
170 0, /* tp_as_mapping */
171 0, /* tp_hash */
172 0, /* tp_call */
173 0, /* tp_str */
174 0, /* tp_getattro */
175 0, /* tp_setattro */
176 0, /* tp_as_buffer */
177 Py_TPFLAGS_DEFAULT |
178 Py_TPFLAGS_BASETYPE |
179 Py_TPFLAGS_HAVE_GC, /* tp_flags */
Georg Brandl8ec7f652007-08-15 14:28:01 +0000180 "Noddy objects", /* tp_doc */
181 (traverseproc)Noddy_traverse, /* tp_traverse */
182 (inquiry)Noddy_clear, /* tp_clear */
INADA Naoki9436bbd2017-02-21 21:12:03 +0900183 0, /* tp_richcompare */
184 0, /* tp_weaklistoffset */
185 0, /* tp_iter */
186 0, /* tp_iternext */
Georg Brandl8ec7f652007-08-15 14:28:01 +0000187 Noddy_methods, /* tp_methods */
188 Noddy_members, /* tp_members */
189 0, /* tp_getset */
190 0, /* tp_base */
191 0, /* tp_dict */
192 0, /* tp_descr_get */
193 0, /* tp_descr_set */
194 0, /* tp_dictoffset */
195 (initproc)Noddy_init, /* tp_init */
196 0, /* tp_alloc */
197 Noddy_new, /* tp_new */
198};
199
200static PyMethodDef module_methods[] = {
201 {NULL} /* Sentinel */
202};
203
204#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
205#define PyMODINIT_FUNC void
206#endif
207PyMODINIT_FUNC
INADA Naoki9436bbd2017-02-21 21:12:03 +0900208initnoddy4(void)
Georg Brandl8ec7f652007-08-15 14:28:01 +0000209{
210 PyObject* m;
211
212 if (PyType_Ready(&NoddyType) < 0)
213 return;
214
215 m = Py_InitModule3("noddy4", module_methods,
216 "Example module that creates an extension type.");
217
218 if (m == NULL)
INADA Naoki9436bbd2017-02-21 21:12:03 +0900219 return;
Georg Brandl8ec7f652007-08-15 14:28:01 +0000220
221 Py_INCREF(&NoddyType);
222 PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
223}