Skip to content

Commit 73c79e3

Browse files
author
gvanrossum
committed
Missing file structseq.c for SF patch #462296
git-svn-id: http://svn.python.org/projects/python/trunk@23805 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 92f2b1d commit 73c79e3

File tree

1 file changed

+284
-0
lines changed

1 file changed

+284
-0
lines changed

Objects/structseq.c

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
/* Implementation helper: a struct that looks like a tuple. See timemodule
2+
and posixmodule for example uses. */
3+
4+
#include "Python.h"
5+
#include "structmember.h"
6+
#include "structseq.h"
7+
8+
static char visible_length_key[] = "n_sequence_fields";
9+
static char real_length_key[] = "n_fields";
10+
11+
#define VISIBLE_SIZE(op) ((op)->ob_size)
12+
#define VISIBLE_SIZE_TP(tp) PyInt_AsLong( \
13+
PyDict_GetItemString((tp)->tp_dict, visible_length_key))
14+
15+
#define REAL_SIZE_TP(tp) PyInt_AsLong( \
16+
PyDict_GetItemString((tp)->tp_dict, real_length_key))
17+
#define REAL_SIZE(op) REAL_SIZE_TP((op)->ob_type)
18+
19+
20+
PyObject *
21+
PyStructSequence_New(PyTypeObject *type)
22+
{
23+
PyStructSequence *obj;
24+
25+
obj = PyObject_New(PyStructSequence, type);
26+
obj->ob_size = VISIBLE_SIZE_TP(type);
27+
28+
return (PyObject*) obj;
29+
}
30+
31+
static void
32+
structseq_dealloc(PyStructSequence *obj)
33+
{
34+
int i, size;
35+
36+
size = REAL_SIZE(obj);
37+
for (i = 0; i < size; ++i) {
38+
Py_XDECREF(obj->ob_item[i]);
39+
}
40+
PyObject_FREE(obj);
41+
}
42+
43+
static int
44+
structseq_length(PyStructSequence *obj)
45+
{
46+
return VISIBLE_SIZE(obj);
47+
}
48+
49+
static PyObject*
50+
structseq_item(PyStructSequence *obj, int i)
51+
{
52+
if (i < 0 || i >= VISIBLE_SIZE(obj)) {
53+
PyErr_SetString(PyExc_IndexError, "tuple index out of range");
54+
return NULL;
55+
}
56+
Py_INCREF(obj->ob_item[i]);
57+
return obj->ob_item[i];
58+
}
59+
60+
static PyObject*
61+
structseq_slice(PyStructSequence *obj, int low, int high)
62+
{
63+
PyTupleObject *np;
64+
int i;
65+
66+
if (low < 0)
67+
low = 0;
68+
if (high > VISIBLE_SIZE(obj))
69+
high = VISIBLE_SIZE(obj);
70+
if (high < low)
71+
high = low;
72+
np = (PyTupleObject *)PyTuple_New(high-low);
73+
if (np == NULL)
74+
return NULL;
75+
for(i = low; i < high; ++i) {
76+
PyObject *v = obj->ob_item[i];
77+
Py_INCREF(v);
78+
PyTuple_SET_ITEM(np, i, v);
79+
}
80+
return (PyObject *) np;
81+
}
82+
83+
static PyObject *
84+
structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
85+
{
86+
PyObject *arg = NULL;
87+
PyStructSequence *res = NULL;
88+
int len, required_len, i;
89+
static char *kwlist[] = {"sequence", 0};
90+
static char msgbuf[128];
91+
92+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:structseq",
93+
kwlist, &arg))
94+
return NULL;
95+
96+
if (!PySequence_Check(arg)) {
97+
PyErr_SetString(PyExc_TypeError,
98+
"constructor requires a sequence");
99+
return NULL;
100+
}
101+
102+
len = PySequence_Length(arg);
103+
required_len = REAL_SIZE_TP(type);
104+
if (len != required_len) {
105+
sprintf(msgbuf,
106+
"constructor takes exactly %d arguments (%d given)",
107+
required_len,
108+
len);
109+
PyErr_SetString(PyExc_TypeError, msgbuf);
110+
return NULL;
111+
}
112+
113+
res = (PyStructSequence*) PyStructSequence_New(type);
114+
for (i = 0; i < len; ++i) {
115+
/* INCREF???? XXXX */
116+
res->ob_item[i] = PySequence_GetItem(arg, i);
117+
}
118+
119+
return (PyObject*) res;
120+
}
121+
122+
static PyObject *
123+
make_tuple(PyStructSequence *obj)
124+
{
125+
return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
126+
}
127+
128+
static PyObject *
129+
structseq_repr(PyStructSequence *obj)
130+
{
131+
PyObject *tup, *str;
132+
tup = make_tuple(obj);
133+
str = PyObject_Repr(tup);
134+
Py_DECREF(tup);
135+
return str;
136+
}
137+
138+
static PyObject *
139+
structseq_concat(PyStructSequence *obj, PyObject *b)
140+
{
141+
PyObject *tup, *result;
142+
tup = make_tuple(obj);
143+
result = PySequence_Concat(tup, b);
144+
Py_DECREF(tup);
145+
return result;
146+
}
147+
148+
static PyObject *
149+
structseq_repeat(PyStructSequence *obj, int n)
150+
{
151+
PyObject *tup, *result;
152+
tup = make_tuple(obj);
153+
result = PySequence_Repeat(tup, n);
154+
Py_DECREF(tup);
155+
return result;
156+
}
157+
158+
static int
159+
structseq_contains(PyStructSequence *obj, PyObject *o)
160+
{
161+
PyObject *tup;
162+
int result;
163+
tup = make_tuple(obj);
164+
result = PySequence_Contains(tup, o);
165+
Py_DECREF(tup);
166+
return result;
167+
}
168+
169+
static long
170+
structseq_hash(PyObject *obj)
171+
{
172+
PyObject *tup;
173+
long result;
174+
tup = make_tuple((PyStructSequence*) obj);
175+
result = PyObject_Hash(tup);
176+
Py_DECREF(tup);
177+
return result;
178+
}
179+
180+
static PyObject *
181+
structseq_richcompare(PyObject *obj, PyObject *o2, int op)
182+
{
183+
PyObject *tup, *result;
184+
tup = make_tuple((PyStructSequence*) obj);
185+
result = PyObject_RichCompare(tup, o2, op);
186+
Py_DECREF(tup);
187+
return result;
188+
}
189+
190+
static PySequenceMethods structseq_as_sequence = {
191+
(inquiry)structseq_length,
192+
(binaryfunc)structseq_concat, /* sq_concat */
193+
(intargfunc)structseq_repeat, /* sq_repeat */
194+
(intargfunc)structseq_item, /* sq_item */
195+
(intintargfunc)structseq_slice, /* sq_slice */
196+
0, /* sq_ass_item */
197+
0, /* sq_ass_slice */
198+
(objobjproc)structseq_contains, /* sq_contains */
199+
};
200+
201+
static PyTypeObject _struct_sequence_template = {
202+
PyObject_HEAD_INIT(&PyType_Type)
203+
0, /* ob_size */
204+
NULL, /* tp_name */
205+
0, /* tp_basicsize */
206+
0, /* tp_itemsize */
207+
(destructor)structseq_dealloc, /* tp_dealloc */
208+
0, /* tp_print */
209+
0, /* tp_getattr */
210+
0, /* tp_setattr */
211+
0, /* tp_compare */
212+
(reprfunc)structseq_repr, /* tp_repr */
213+
0, /* tp_as_number */
214+
&structseq_as_sequence, /* tp_as_sequence */
215+
0, /* tp_as_mapping */
216+
(hashfunc)structseq_hash, /* tp_hash */
217+
0, /* tp_call */
218+
0, /* tp_str */
219+
0, /* tp_getattro */
220+
0, /* tp_setattro */
221+
0, /* tp_as_buffer */
222+
Py_TPFLAGS_DEFAULT, /* tp_flags */
223+
NULL, /* tp_doc */
224+
0, /* tp_traverse */
225+
0, /* tp_clear */
226+
structseq_richcompare, /* tp_richcompare */
227+
0, /* tp_weaklistoffset */
228+
0, /* tp_iter */
229+
0, /* tp_iternext */
230+
0, /* tp_methods */
231+
NULL, /* tp_members */
232+
0, /* tp_getset */
233+
0, /* tp_base */
234+
0, /* tp_dict */
235+
0, /* tp_descr_get */
236+
0, /* tp_descr_set */
237+
0, /* tp_dictoffset */
238+
0, /* tp_init */
239+
0, /* tp_alloc */
240+
structseq_new, /* tp_new */
241+
};
242+
243+
void
244+
PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
245+
{
246+
PyObject *dict;
247+
PyMemberDef* members;
248+
int n_members, i;
249+
250+
for (i = 0; desc->fields[i].name != NULL; ++i)
251+
;
252+
n_members = i;
253+
254+
memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
255+
type->tp_name = desc->name;
256+
type->tp_doc = desc->doc;
257+
type->tp_basicsize = sizeof(PyStructSequence)+
258+
sizeof(PyObject*)*(n_members-1);
259+
type->tp_itemsize = 0;
260+
261+
members = PyMem_NEW(PyMemberDef, n_members+1);
262+
263+
for (i = 0; i < n_members; ++i) {
264+
members[i].name = desc->fields[i].name;
265+
members[i].type = T_OBJECT;
266+
members[i].offset = offsetof(PyStructSequence, ob_item)
267+
+ i * sizeof(PyObject*);
268+
members[i].flags = READONLY;
269+
members[i].doc = desc->fields[i].doc;
270+
}
271+
members[n_members].name = NULL;
272+
273+
type->tp_members = members;
274+
275+
if (PyType_Ready(type) < 0)
276+
return;
277+
Py_INCREF(type);
278+
279+
dict = type->tp_dict;
280+
PyDict_SetItemString(dict, visible_length_key,
281+
PyInt_FromLong((long) desc->n_in_sequence));
282+
PyDict_SetItemString(dict, real_length_key,
283+
PyInt_FromLong((long) n_members));
284+
}

0 commit comments

Comments
 (0)