~ubuntu-branches/ubuntu/natty/python3.1/natty-security

« back to all changes in this revision

Viewing changes to Objects/structseq.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-07-06 16:52:42 UTC
  • mfrom: (1.2.1 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100706165242-2xv4i019r3et6c0j
Tags: 3.1.2+20100706-1ubuntu1
* Merge with Debian; remaining changes:
  - Regenerate the control file.
  - Add debian/patches/overwrite-semaphore-check for Lucid buildds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
static char real_length_key[] = "n_fields";
10
10
static char unnamed_fields_key[] = "n_unnamed_fields";
11
11
 
12
 
/* Fields with this name have only a field index, not a field name. 
 
12
/* Fields with this name have only a field index, not a field name.
13
13
   They are only allowed for indices < n_visible_fields. */
14
14
char *PyStructSequence_UnnamedField = "unnamed field";
15
15
 
29
29
PyObject *
30
30
PyStructSequence_New(PyTypeObject *type)
31
31
{
32
 
        PyStructSequence *obj;
33
 
 
34
 
        obj = PyObject_New(PyStructSequence, type);
35
 
        if (obj == NULL)
36
 
                return NULL;
37
 
        Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
38
 
 
39
 
        return (PyObject*) obj;
 
32
    PyStructSequence *obj;
 
33
 
 
34
    obj = PyObject_New(PyStructSequence, type);
 
35
    if (obj == NULL)
 
36
        return NULL;
 
37
    Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
 
38
 
 
39
    return (PyObject*) obj;
40
40
}
41
41
 
42
42
static void
43
43
structseq_dealloc(PyStructSequence *obj)
44
44
{
45
 
        Py_ssize_t i, size;
 
45
    Py_ssize_t i, size;
46
46
 
47
 
        size = REAL_SIZE(obj);
48
 
        for (i = 0; i < size; ++i) {
49
 
                Py_XDECREF(obj->ob_item[i]);
50
 
        }
51
 
        PyObject_Del(obj);
 
47
    size = REAL_SIZE(obj);
 
48
    for (i = 0; i < size; ++i) {
 
49
        Py_XDECREF(obj->ob_item[i]);
 
50
    }
 
51
    PyObject_Del(obj);
52
52
}
53
53
 
54
54
static Py_ssize_t
55
55
structseq_length(PyStructSequence *obj)
56
56
{
57
 
        return VISIBLE_SIZE(obj);
 
57
    return VISIBLE_SIZE(obj);
58
58
}
59
59
 
60
60
static PyObject*
61
61
structseq_item(PyStructSequence *obj, Py_ssize_t i)
62
62
{
63
 
        if (i < 0 || i >= VISIBLE_SIZE(obj)) {
64
 
                PyErr_SetString(PyExc_IndexError, "tuple index out of range");
65
 
                return NULL;
66
 
        }
67
 
        Py_INCREF(obj->ob_item[i]);
68
 
        return obj->ob_item[i];
 
63
    if (i < 0 || i >= VISIBLE_SIZE(obj)) {
 
64
        PyErr_SetString(PyExc_IndexError, "tuple index out of range");
 
65
        return NULL;
 
66
    }
 
67
    Py_INCREF(obj->ob_item[i]);
 
68
    return obj->ob_item[i];
69
69
}
70
70
 
71
71
static PyObject*
72
72
structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high)
73
73
{
74
 
        PyTupleObject *np;
75
 
        Py_ssize_t i;
 
74
    PyTupleObject *np;
 
75
    Py_ssize_t i;
76
76
 
77
 
        if (low < 0)
78
 
                low = 0;
79
 
        if (high > VISIBLE_SIZE(obj))
80
 
                high = VISIBLE_SIZE(obj);
81
 
        if (high < low)
82
 
                high = low;
83
 
        np = (PyTupleObject *)PyTuple_New(high-low);
84
 
        if (np == NULL)
85
 
                return NULL;
86
 
        for(i = low; i < high; ++i) {
87
 
                PyObject *v = obj->ob_item[i];
88
 
                Py_INCREF(v);
89
 
                PyTuple_SET_ITEM(np, i-low, v);
90
 
        }
91
 
        return (PyObject *) np;
 
77
    if (low < 0)
 
78
        low = 0;
 
79
    if (high > VISIBLE_SIZE(obj))
 
80
        high = VISIBLE_SIZE(obj);
 
81
    if (high < low)
 
82
        high = low;
 
83
    np = (PyTupleObject *)PyTuple_New(high-low);
 
84
    if (np == NULL)
 
85
        return NULL;
 
86
    for(i = low; i < high; ++i) {
 
87
        PyObject *v = obj->ob_item[i];
 
88
        Py_INCREF(v);
 
89
        PyTuple_SET_ITEM(np, i-low, v);
 
90
    }
 
91
    return (PyObject *) np;
92
92
}
93
93
 
94
94
static PyObject *
95
95
structseq_subscript(PyStructSequence *self, PyObject *item)
96
96
{
97
 
        if (PyIndex_Check(item)) {
98
 
                Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
99
 
                if (i == -1 && PyErr_Occurred())
100
 
                        return NULL;
101
 
 
102
 
                if (i < 0)
103
 
                        i += VISIBLE_SIZE(self);
104
 
 
105
 
                if (i < 0 || i >= VISIBLE_SIZE(self)) {
106
 
                        PyErr_SetString(PyExc_IndexError,
107
 
                                "tuple index out of range");
108
 
                        return NULL;
109
 
                }
110
 
                Py_INCREF(self->ob_item[i]);
111
 
                return self->ob_item[i];
112
 
        }
113
 
        else if (PySlice_Check(item)) {
114
 
                Py_ssize_t start, stop, step, slicelen, cur, i;
115
 
                PyObject *result;
116
 
                
117
 
                if (PySlice_GetIndicesEx((PySliceObject *)item,
118
 
                                         VISIBLE_SIZE(self), &start, &stop,
119
 
                                         &step, &slicelen) < 0) {
120
 
                        return NULL;
121
 
                }
122
 
                if (slicelen <= 0)
123
 
                        return PyTuple_New(0);
124
 
                result = PyTuple_New(slicelen);
125
 
                if (result == NULL)
126
 
                        return NULL;
127
 
                for (cur = start, i = 0; i < slicelen;
128
 
                     cur += step, i++) {
129
 
                        PyObject *v = self->ob_item[cur];
130
 
                        Py_INCREF(v);
131
 
                        PyTuple_SET_ITEM(result, i, v);
132
 
                }
133
 
                return result;
134
 
        }
135
 
        else {
136
 
                PyErr_SetString(PyExc_TypeError,
137
 
                                "structseq index must be integer");
138
 
                return NULL;
139
 
        }
 
97
    if (PyIndex_Check(item)) {
 
98
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
 
99
        if (i == -1 && PyErr_Occurred())
 
100
            return NULL;
 
101
 
 
102
        if (i < 0)
 
103
            i += VISIBLE_SIZE(self);
 
104
 
 
105
        if (i < 0 || i >= VISIBLE_SIZE(self)) {
 
106
            PyErr_SetString(PyExc_IndexError,
 
107
                "tuple index out of range");
 
108
            return NULL;
 
109
        }
 
110
        Py_INCREF(self->ob_item[i]);
 
111
        return self->ob_item[i];
 
112
    }
 
113
    else if (PySlice_Check(item)) {
 
114
        Py_ssize_t start, stop, step, slicelen, cur, i;
 
115
        PyObject *result;
 
116
 
 
117
        if (PySlice_GetIndicesEx((PySliceObject *)item,
 
118
                                 VISIBLE_SIZE(self), &start, &stop,
 
119
                                 &step, &slicelen) < 0) {
 
120
            return NULL;
 
121
        }
 
122
        if (slicelen <= 0)
 
123
            return PyTuple_New(0);
 
124
        result = PyTuple_New(slicelen);
 
125
        if (result == NULL)
 
126
            return NULL;
 
127
        for (cur = start, i = 0; i < slicelen;
 
128
             cur += step, i++) {
 
129
            PyObject *v = self->ob_item[cur];
 
130
            Py_INCREF(v);
 
131
            PyTuple_SET_ITEM(result, i, v);
 
132
        }
 
133
        return result;
 
134
    }
 
135
    else {
 
136
        PyErr_SetString(PyExc_TypeError,
 
137
                        "structseq index must be integer");
 
138
        return NULL;
 
139
    }
140
140
}
141
141
 
142
142
static PyObject *
143
143
structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
144
144
{
145
 
        PyObject *arg = NULL;
146
 
        PyObject *dict = NULL;
147
 
        PyObject *ob;
148
 
        PyStructSequence *res = NULL;
149
 
        Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
150
 
        static char *kwlist[] = {"sequence", "dict", 0};
151
 
 
152
 
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq", 
153
 
                                         kwlist, &arg, &dict))
154
 
                return NULL;
155
 
 
156
 
        arg = PySequence_Fast(arg, "constructor requires a sequence");
157
 
 
158
 
        if (!arg) {                             
159
 
                return NULL;
160
 
        }
161
 
 
162
 
        if (dict && !PyDict_Check(dict)) {
163
 
                PyErr_Format(PyExc_TypeError, 
164
 
                             "%.500s() takes a dict as second arg, if any",
165
 
                             type->tp_name);
166
 
                Py_DECREF(arg);
167
 
                return NULL;
168
 
        }
169
 
 
170
 
        len = PySequence_Fast_GET_SIZE(arg);
171
 
        min_len = VISIBLE_SIZE_TP(type);
172
 
        max_len = REAL_SIZE_TP(type);
173
 
        n_unnamed_fields = UNNAMED_FIELDS_TP(type);
174
 
 
175
 
        if (min_len != max_len) {
176
 
                if (len < min_len) {
177
 
                        PyErr_Format(PyExc_TypeError, 
178
 
               "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
179
 
                                     type->tp_name, min_len, len);
180
 
                        Py_DECREF(arg);
181
 
                        return NULL;
182
 
                }
183
 
 
184
 
                if (len > max_len) {
185
 
                        PyErr_Format(PyExc_TypeError, 
186
 
               "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
187
 
                                     type->tp_name, max_len, len);
188
 
                        Py_DECREF(arg);
189
 
                        return NULL;
190
 
                }
191
 
        } 
192
 
        else {
193
 
                if (len != min_len) {
194
 
                        PyErr_Format(PyExc_TypeError, 
195
 
               "%.500s() takes a %zd-sequence (%zd-sequence given)",
196
 
                                     type->tp_name, min_len, len);
197
 
                        Py_DECREF(arg);
198
 
                        return NULL;
199
 
                }
200
 
        }
201
 
 
202
 
        res = (PyStructSequence*) PyStructSequence_New(type);
203
 
        if (res == NULL) {
204
 
                return NULL;
205
 
        }
206
 
        for (i = 0; i < len; ++i) {
207
 
                PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
208
 
                Py_INCREF(v);
209
 
                res->ob_item[i] = v;
210
 
        }
211
 
        for (; i < max_len; ++i) {
212
 
                if (dict && (ob = PyDict_GetItemString(
213
 
                        dict, type->tp_members[i-n_unnamed_fields].name))) {
214
 
                }
215
 
                else {
216
 
                        ob = Py_None;
217
 
                }
218
 
                Py_INCREF(ob);
219
 
                res->ob_item[i] = ob;
220
 
        }
221
 
        
222
 
        Py_DECREF(arg);
223
 
        return (PyObject*) res;
 
145
    PyObject *arg = NULL;
 
146
    PyObject *dict = NULL;
 
147
    PyObject *ob;
 
148
    PyStructSequence *res = NULL;
 
149
    Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
 
150
    static char *kwlist[] = {"sequence", "dict", 0};
 
151
 
 
152
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq",
 
153
                                     kwlist, &arg, &dict))
 
154
        return NULL;
 
155
 
 
156
    arg = PySequence_Fast(arg, "constructor requires a sequence");
 
157
 
 
158
    if (!arg) {
 
159
        return NULL;
 
160
    }
 
161
 
 
162
    if (dict && !PyDict_Check(dict)) {
 
163
        PyErr_Format(PyExc_TypeError,
 
164
                     "%.500s() takes a dict as second arg, if any",
 
165
                     type->tp_name);
 
166
        Py_DECREF(arg);
 
167
        return NULL;
 
168
    }
 
169
 
 
170
    len = PySequence_Fast_GET_SIZE(arg);
 
171
    min_len = VISIBLE_SIZE_TP(type);
 
172
    max_len = REAL_SIZE_TP(type);
 
173
    n_unnamed_fields = UNNAMED_FIELDS_TP(type);
 
174
 
 
175
    if (min_len != max_len) {
 
176
        if (len < min_len) {
 
177
            PyErr_Format(PyExc_TypeError,
 
178
           "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
 
179
                                 type->tp_name, min_len, len);
 
180
                    Py_DECREF(arg);
 
181
                    return NULL;
 
182
        }
 
183
 
 
184
        if (len > max_len) {
 
185
            PyErr_Format(PyExc_TypeError,
 
186
           "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
 
187
                                 type->tp_name, max_len, len);
 
188
                    Py_DECREF(arg);
 
189
                    return NULL;
 
190
        }
 
191
    }
 
192
    else {
 
193
        if (len != min_len) {
 
194
            PyErr_Format(PyExc_TypeError,
 
195
           "%.500s() takes a %zd-sequence (%zd-sequence given)",
 
196
                                 type->tp_name, min_len, len);
 
197
                    Py_DECREF(arg);
 
198
                    return NULL;
 
199
        }
 
200
    }
 
201
 
 
202
    res = (PyStructSequence*) PyStructSequence_New(type);
 
203
    if (res == NULL) {
 
204
        return NULL;
 
205
    }
 
206
    for (i = 0; i < len; ++i) {
 
207
        PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
 
208
        Py_INCREF(v);
 
209
        res->ob_item[i] = v;
 
210
    }
 
211
    for (; i < max_len; ++i) {
 
212
        if (dict && (ob = PyDict_GetItemString(
 
213
            dict, type->tp_members[i-n_unnamed_fields].name))) {
 
214
        }
 
215
        else {
 
216
            ob = Py_None;
 
217
        }
 
218
        Py_INCREF(ob);
 
219
        res->ob_item[i] = ob;
 
220
    }
 
221
 
 
222
    Py_DECREF(arg);
 
223
    return (PyObject*) res;
224
224
}
225
225
 
226
226
static PyObject *
227
227
make_tuple(PyStructSequence *obj)
228
228
{
229
 
        return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
 
229
    return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
230
230
}
231
231
 
232
232
static PyObject *
233
233
structseq_repr(PyStructSequence *obj)
234
234
{
235
 
        /* buffer and type size were chosen well considered. */
 
235
    /* buffer and type size were chosen well considered. */
236
236
#define REPR_BUFFER_SIZE 512
237
237
#define TYPE_MAXSIZE 100
238
238
 
239
 
        PyObject *tup;
240
 
        PyTypeObject *typ = Py_TYPE(obj);
241
 
        int i, removelast = 0;
242
 
        Py_ssize_t len;
243
 
        char buf[REPR_BUFFER_SIZE];
244
 
        char *endofbuf, *pbuf = buf;
245
 
 
246
 
        /* pointer to end of writeable buffer; safes space for "...)\0" */
247
 
        endofbuf= &buf[REPR_BUFFER_SIZE-5];
248
 
 
249
 
        if ((tup = make_tuple(obj)) == NULL) {
250
 
                return NULL;
251
 
        }
252
 
 
253
 
        /* "typename(", limited to  TYPE_MAXSIZE */
254
 
        len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
255
 
                                                    strlen(typ->tp_name);
256
 
        strncpy(pbuf, typ->tp_name, len);
257
 
        pbuf += len;
258
 
        *pbuf++ = '(';
259
 
 
260
 
        for (i=0; i < VISIBLE_SIZE(obj); i++) {
261
 
                PyObject *val, *repr;
262
 
                char *cname, *crepr;
263
 
 
264
 
                cname = typ->tp_members[i].name;
265
 
                
266
 
                val = PyTuple_GetItem(tup, i);
267
 
                if (cname == NULL || val == NULL) {
268
 
                        return NULL;
269
 
                }
270
 
                repr = PyObject_Repr(val);
271
 
                if (repr == NULL) {
272
 
                        Py_DECREF(tup);
273
 
                        return NULL;
274
 
                }
275
 
                crepr = _PyUnicode_AsString(repr);
276
 
                if (crepr == NULL) {
277
 
                        Py_DECREF(tup);
278
 
                        Py_DECREF(repr);
279
 
                        return NULL;
280
 
                }
281
 
                
282
 
                /* + 3: keep space for "=" and ", " */
283
 
                len = strlen(cname) + strlen(crepr) + 3;
284
 
                if ((pbuf+len) <= endofbuf) {
285
 
                        strcpy(pbuf, cname);
286
 
                        pbuf += strlen(cname);
287
 
                        *pbuf++ = '=';
288
 
                        strcpy(pbuf, crepr);
289
 
                        pbuf += strlen(crepr);
290
 
                        *pbuf++ = ',';
291
 
                        *pbuf++ = ' ';
292
 
                        removelast = 1;
293
 
                        Py_DECREF(repr);
294
 
                }
295
 
                else {
296
 
                        strcpy(pbuf, "...");
297
 
                        pbuf += 3;
298
 
                        removelast = 0;
299
 
                        Py_DECREF(repr);
300
 
                        break;
301
 
                }
302
 
        }
303
 
        Py_DECREF(tup);
304
 
        if (removelast) {
305
 
                /* overwrite last ", " */
306
 
                pbuf-=2;
307
 
        }
308
 
        *pbuf++ = ')';
309
 
        *pbuf = '\0';
310
 
 
311
 
        return PyUnicode_FromString(buf);
 
239
    PyObject *tup;
 
240
    PyTypeObject *typ = Py_TYPE(obj);
 
241
    int i, removelast = 0;
 
242
    Py_ssize_t len;
 
243
    char buf[REPR_BUFFER_SIZE];
 
244
    char *endofbuf, *pbuf = buf;
 
245
 
 
246
    /* pointer to end of writeable buffer; safes space for "...)\0" */
 
247
    endofbuf= &buf[REPR_BUFFER_SIZE-5];
 
248
 
 
249
    if ((tup = make_tuple(obj)) == NULL) {
 
250
        return NULL;
 
251
    }
 
252
 
 
253
    /* "typename(", limited to  TYPE_MAXSIZE */
 
254
    len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
 
255
                            strlen(typ->tp_name);
 
256
    strncpy(pbuf, typ->tp_name, len);
 
257
    pbuf += len;
 
258
    *pbuf++ = '(';
 
259
 
 
260
    for (i=0; i < VISIBLE_SIZE(obj); i++) {
 
261
        PyObject *val, *repr;
 
262
        char *cname, *crepr;
 
263
 
 
264
        cname = typ->tp_members[i].name;
 
265
 
 
266
        val = PyTuple_GetItem(tup, i);
 
267
        if (cname == NULL || val == NULL) {
 
268
            return NULL;
 
269
        }
 
270
        repr = PyObject_Repr(val);
 
271
        if (repr == NULL) {
 
272
            Py_DECREF(tup);
 
273
            return NULL;
 
274
        }
 
275
        crepr = _PyUnicode_AsString(repr);
 
276
        if (crepr == NULL) {
 
277
            Py_DECREF(tup);
 
278
            Py_DECREF(repr);
 
279
            return NULL;
 
280
        }
 
281
 
 
282
        /* + 3: keep space for "=" and ", " */
 
283
        len = strlen(cname) + strlen(crepr) + 3;
 
284
        if ((pbuf+len) <= endofbuf) {
 
285
            strcpy(pbuf, cname);
 
286
            pbuf += strlen(cname);
 
287
            *pbuf++ = '=';
 
288
            strcpy(pbuf, crepr);
 
289
            pbuf += strlen(crepr);
 
290
            *pbuf++ = ',';
 
291
            *pbuf++ = ' ';
 
292
            removelast = 1;
 
293
            Py_DECREF(repr);
 
294
        }
 
295
        else {
 
296
            strcpy(pbuf, "...");
 
297
            pbuf += 3;
 
298
            removelast = 0;
 
299
            Py_DECREF(repr);
 
300
            break;
 
301
        }
 
302
    }
 
303
    Py_DECREF(tup);
 
304
    if (removelast) {
 
305
        /* overwrite last ", " */
 
306
        pbuf-=2;
 
307
    }
 
308
    *pbuf++ = ')';
 
309
    *pbuf = '\0';
 
310
 
 
311
    return PyUnicode_FromString(buf);
312
312
}
313
313
 
314
314
static PyObject *
315
315
structseq_concat(PyStructSequence *obj, PyObject *b)
316
316
{
317
 
        PyObject *tup, *result;
318
 
        tup = make_tuple(obj);
319
 
        result = PySequence_Concat(tup, b);
320
 
        Py_DECREF(tup);
321
 
        return result;
 
317
    PyObject *tup, *result;
 
318
    tup = make_tuple(obj);
 
319
    result = PySequence_Concat(tup, b);
 
320
    Py_DECREF(tup);
 
321
    return result;
322
322
}
323
323
 
324
324
static PyObject *
325
325
structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
326
326
{
327
 
        PyObject *tup, *result;
328
 
        tup = make_tuple(obj);
329
 
        result = PySequence_Repeat(tup, n);
330
 
        Py_DECREF(tup);
331
 
        return result;
 
327
    PyObject *tup, *result;
 
328
    tup = make_tuple(obj);
 
329
    result = PySequence_Repeat(tup, n);
 
330
    Py_DECREF(tup);
 
331
    return result;
332
332
}
333
333
 
334
334
static int
335
335
structseq_contains(PyStructSequence *obj, PyObject *o)
336
336
{
337
 
        PyObject *tup;
338
 
        int result;
339
 
        tup = make_tuple(obj);
340
 
        if (!tup)
341
 
                return -1;
342
 
        result = PySequence_Contains(tup, o);
343
 
        Py_DECREF(tup);
344
 
        return result;
 
337
    PyObject *tup;
 
338
    int result;
 
339
    tup = make_tuple(obj);
 
340
    if (!tup)
 
341
        return -1;
 
342
    result = PySequence_Contains(tup, o);
 
343
    Py_DECREF(tup);
 
344
    return result;
345
345
}
346
346
 
347
347
static long
348
348
structseq_hash(PyObject *obj)
349
349
{
350
 
        PyObject *tup;
351
 
        long result;
352
 
        tup = make_tuple((PyStructSequence*) obj);
353
 
        if (!tup)
354
 
                return -1;
355
 
        result = PyObject_Hash(tup);
356
 
        Py_DECREF(tup);
357
 
        return result;
 
350
    PyObject *tup;
 
351
    long result;
 
352
    tup = make_tuple((PyStructSequence*) obj);
 
353
    if (!tup)
 
354
        return -1;
 
355
    result = PyObject_Hash(tup);
 
356
    Py_DECREF(tup);
 
357
    return result;
358
358
}
359
359
 
360
360
static PyObject *
361
361
structseq_richcompare(PyObject *obj, PyObject *o2, int op)
362
362
{
363
 
        PyObject *tup, *result;
364
 
        tup = make_tuple((PyStructSequence*) obj);
365
 
        result = PyObject_RichCompare(tup, o2, op);
366
 
        Py_DECREF(tup);
367
 
        return result;
 
363
    PyObject *tup, *result;
 
364
    tup = make_tuple((PyStructSequence*) obj);
 
365
    result = PyObject_RichCompare(tup, o2, op);
 
366
    Py_DECREF(tup);
 
367
    return result;
368
368
}
369
369
 
370
370
static PyObject *
371
371
structseq_reduce(PyStructSequence* self)
372
372
{
373
 
        PyObject* tup;
374
 
        PyObject* dict;
375
 
        PyObject* result;
376
 
        Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
377
 
        int i;
378
 
        
379
 
        n_fields = REAL_SIZE(self);
380
 
        n_visible_fields = VISIBLE_SIZE(self);
381
 
        n_unnamed_fields = UNNAMED_FIELDS(self);
382
 
        tup = PyTuple_New(n_visible_fields);
383
 
        if (!tup) {
384
 
                return NULL;
385
 
        }
386
 
 
387
 
        dict = PyDict_New();
388
 
        if (!dict) {
389
 
                Py_DECREF(tup);
390
 
                return NULL;
391
 
        }
392
 
 
393
 
        for (i = 0; i < n_visible_fields; i++) {
394
 
                Py_INCREF(self->ob_item[i]);
395
 
                PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
396
 
        }
397
 
        
398
 
        for (; i < n_fields; i++) {
399
 
                char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
400
 
                PyDict_SetItemString(dict, n,
401
 
                                     self->ob_item[i]);
402
 
        }
403
 
 
404
 
        result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);
405
 
 
406
 
        Py_DECREF(tup);
407
 
        Py_DECREF(dict);
408
 
 
409
 
        return result;
 
373
    PyObject* tup;
 
374
    PyObject* dict;
 
375
    PyObject* result;
 
376
    Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
 
377
    int i;
 
378
 
 
379
    n_fields = REAL_SIZE(self);
 
380
    n_visible_fields = VISIBLE_SIZE(self);
 
381
    n_unnamed_fields = UNNAMED_FIELDS(self);
 
382
    tup = PyTuple_New(n_visible_fields);
 
383
    if (!tup) {
 
384
        return NULL;
 
385
    }
 
386
 
 
387
    dict = PyDict_New();
 
388
    if (!dict) {
 
389
        Py_DECREF(tup);
 
390
        return NULL;
 
391
    }
 
392
 
 
393
    for (i = 0; i < n_visible_fields; i++) {
 
394
        Py_INCREF(self->ob_item[i]);
 
395
        PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
 
396
    }
 
397
 
 
398
    for (; i < n_fields; i++) {
 
399
        char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
 
400
        PyDict_SetItemString(dict, n,
 
401
                             self->ob_item[i]);
 
402
    }
 
403
 
 
404
    result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);
 
405
 
 
406
    Py_DECREF(tup);
 
407
    Py_DECREF(dict);
 
408
 
 
409
    return result;
410
410
}
411
411
 
412
412
static PySequenceMethods structseq_as_sequence = {
413
 
        (lenfunc)structseq_length,
414
 
        (binaryfunc)structseq_concat,           /* sq_concat */
415
 
        (ssizeargfunc)structseq_repeat,         /* sq_repeat */
416
 
        (ssizeargfunc)structseq_item,           /* sq_item */
417
 
        0,                                      /* sq_slice */
418
 
        0,                                      /* sq_ass_item */
419
 
        0,                                      /* sq_ass_slice */
420
 
        (objobjproc)structseq_contains,         /* sq_contains */
 
413
    (lenfunc)structseq_length,
 
414
    (binaryfunc)structseq_concat,           /* sq_concat */
 
415
    (ssizeargfunc)structseq_repeat,         /* sq_repeat */
 
416
    (ssizeargfunc)structseq_item,               /* sq_item */
 
417
    0,                                          /* sq_slice */
 
418
    0,                                          /* sq_ass_item */
 
419
    0,                                          /* sq_ass_slice */
 
420
    (objobjproc)structseq_contains,             /* sq_contains */
421
421
};
422
422
 
423
423
static PyMappingMethods structseq_as_mapping = {
424
 
        (lenfunc)structseq_length,
425
 
        (binaryfunc)structseq_subscript,
 
424
    (lenfunc)structseq_length,
 
425
    (binaryfunc)structseq_subscript,
426
426
};
427
427
 
428
428
static PyMethodDef structseq_methods[] = {
429
 
        {"__reduce__", (PyCFunction)structseq_reduce, 
430
 
         METH_NOARGS, NULL},
431
 
        {NULL, NULL}
 
429
    {"__reduce__", (PyCFunction)structseq_reduce,
 
430
     METH_NOARGS, NULL},
 
431
    {NULL, NULL}
432
432
};
433
433
 
434
434
static PyTypeObject _struct_sequence_template = {
435
 
        PyVarObject_HEAD_INIT(&PyType_Type, 0)
436
 
        NULL,                                   /* tp_name */
437
 
        0,                                      /* tp_basicsize */
438
 
        0,                                      /* tp_itemsize */
439
 
        (destructor)structseq_dealloc,          /* tp_dealloc */
440
 
        0,                                      /* tp_print */
441
 
        0,                                      /* tp_getattr */
442
 
        0,                                      /* tp_setattr */
443
 
        0,                                      /* tp_reserved */
444
 
        (reprfunc)structseq_repr,               /* tp_repr */
445
 
        0,                                      /* tp_as_number */
446
 
        &structseq_as_sequence,                 /* tp_as_sequence */
447
 
        &structseq_as_mapping,                  /* tp_as_mapping */
448
 
        structseq_hash,                         /* tp_hash */
449
 
        0,                                      /* tp_call */
450
 
        0,                                      /* tp_str */
451
 
        0,                                      /* tp_getattro */
452
 
        0,                                      /* tp_setattro */
453
 
        0,                                      /* tp_as_buffer */
454
 
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
455
 
        NULL,                                   /* tp_doc */
456
 
        0,                                      /* tp_traverse */
457
 
        0,                                      /* tp_clear */
458
 
        structseq_richcompare,                  /* tp_richcompare */
459
 
        0,                                      /* tp_weaklistoffset */
460
 
        0,                                      /* tp_iter */
461
 
        0,                                      /* tp_iternext */
462
 
        structseq_methods,                      /* tp_methods */
463
 
        NULL,                                   /* tp_members */
464
 
        0,                                      /* tp_getset */
465
 
        0,                                      /* tp_base */
466
 
        0,                                      /* tp_dict */
467
 
        0,                                      /* tp_descr_get */
468
 
        0,                                      /* tp_descr_set */
469
 
        0,                                      /* tp_dictoffset */
470
 
        0,                                      /* tp_init */
471
 
        0,                                      /* tp_alloc */
472
 
        structseq_new,                          /* tp_new */
 
435
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
 
436
    NULL,                                       /* tp_name */
 
437
    0,                                          /* tp_basicsize */
 
438
    0,                                          /* tp_itemsize */
 
439
    (destructor)structseq_dealloc,              /* tp_dealloc */
 
440
    0,                                          /* tp_print */
 
441
    0,                                          /* tp_getattr */
 
442
    0,                                          /* tp_setattr */
 
443
    0,                                          /* tp_reserved */
 
444
    (reprfunc)structseq_repr,                   /* tp_repr */
 
445
    0,                                          /* tp_as_number */
 
446
    &structseq_as_sequence,                     /* tp_as_sequence */
 
447
    &structseq_as_mapping,                      /* tp_as_mapping */
 
448
    structseq_hash,                             /* tp_hash */
 
449
    0,                                          /* tp_call */
 
450
    0,                                          /* tp_str */
 
451
    0,                                          /* tp_getattro */
 
452
    0,                                          /* tp_setattro */
 
453
    0,                                          /* tp_as_buffer */
 
454
    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
455
    NULL,                                       /* tp_doc */
 
456
    0,                                          /* tp_traverse */
 
457
    0,                                          /* tp_clear */
 
458
    structseq_richcompare,                      /* tp_richcompare */
 
459
    0,                                          /* tp_weaklistoffset */
 
460
    0,                                          /* tp_iter */
 
461
    0,                                          /* tp_iternext */
 
462
    structseq_methods,                          /* tp_methods */
 
463
    NULL,                                       /* tp_members */
 
464
    0,                                          /* tp_getset */
 
465
    0,                                          /* tp_base */
 
466
    0,                                          /* tp_dict */
 
467
    0,                                          /* tp_descr_get */
 
468
    0,                                          /* tp_descr_set */
 
469
    0,                                          /* tp_dictoffset */
 
470
    0,                                          /* tp_init */
 
471
    0,                                          /* tp_alloc */
 
472
    structseq_new,                              /* tp_new */
473
473
};
474
474
 
475
475
void
476
476
PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
477
477
{
478
 
        PyObject *dict;
479
 
        PyMemberDef* members;
480
 
        int n_members, n_unnamed_members, i, k;
 
478
    PyObject *dict;
 
479
    PyMemberDef* members;
 
480
    int n_members, n_unnamed_members, i, k;
481
481
 
482
482
#ifdef Py_TRACE_REFS
483
 
        /* if the type object was chained, unchain it first
484
 
           before overwriting its storage */
485
 
        if (type->ob_base.ob_base._ob_next) {
486
 
                _Py_ForgetReference((PyObject*)type);
487
 
        }
 
483
    /* if the type object was chained, unchain it first
 
484
       before overwriting its storage */
 
485
    if (type->ob_base.ob_base._ob_next) {
 
486
        _Py_ForgetReference((PyObject*)type);
 
487
    }
488
488
#endif
489
489
 
490
 
        n_unnamed_members = 0;
491
 
        for (i = 0; desc->fields[i].name != NULL; ++i)
492
 
                if (desc->fields[i].name == PyStructSequence_UnnamedField)
493
 
                        n_unnamed_members++;
494
 
        n_members = i;
495
 
 
496
 
        memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
497
 
        type->tp_name = desc->name;
498
 
        type->tp_doc = desc->doc;
499
 
        type->tp_basicsize = sizeof(PyStructSequence)+
500
 
                sizeof(PyObject*)*(n_members-1);
501
 
        type->tp_itemsize = 0;
502
 
 
503
 
        members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
504
 
        if (members == NULL)
505
 
                return;
506
 
        
507
 
        for (i = k = 0; i < n_members; ++i) {
508
 
                if (desc->fields[i].name == PyStructSequence_UnnamedField)
509
 
                        continue;
510
 
                members[k].name = desc->fields[i].name;
511
 
                members[k].type = T_OBJECT;
512
 
                members[k].offset = offsetof(PyStructSequence, ob_item)
513
 
                  + i * sizeof(PyObject*);
514
 
                members[k].flags = READONLY;
515
 
                members[k].doc = desc->fields[i].doc;
516
 
                k++;
517
 
        }
518
 
        members[k].name = NULL;
519
 
 
520
 
        type->tp_members = members;
521
 
 
522
 
        if (PyType_Ready(type) < 0)
523
 
                return;
524
 
        Py_INCREF(type);
525
 
 
526
 
        dict = type->tp_dict;
527
 
#define SET_DICT_FROM_INT(key, value)                           \
528
 
        do {                                                    \
529
 
                PyObject *v = PyLong_FromLong((long) value);    \
530
 
                if (v != NULL) {                                \
531
 
                        PyDict_SetItemString(dict, key, v);     \
532
 
                        Py_DECREF(v);                           \
533
 
                }                                               \
534
 
        } while (0)
535
 
 
536
 
        SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);
537
 
        SET_DICT_FROM_INT(real_length_key, n_members);
538
 
        SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
 
490
    n_unnamed_members = 0;
 
491
    for (i = 0; desc->fields[i].name != NULL; ++i)
 
492
        if (desc->fields[i].name == PyStructSequence_UnnamedField)
 
493
            n_unnamed_members++;
 
494
    n_members = i;
 
495
 
 
496
    memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
 
497
    type->tp_name = desc->name;
 
498
    type->tp_doc = desc->doc;
 
499
    type->tp_basicsize = sizeof(PyStructSequence)+
 
500
        sizeof(PyObject*)*(n_members-1);
 
501
    type->tp_itemsize = 0;
 
502
 
 
503
    members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
 
504
    if (members == NULL)
 
505
        return;
 
506
 
 
507
    for (i = k = 0; i < n_members; ++i) {
 
508
        if (desc->fields[i].name == PyStructSequence_UnnamedField)
 
509
            continue;
 
510
        members[k].name = desc->fields[i].name;
 
511
        members[k].type = T_OBJECT;
 
512
        members[k].offset = offsetof(PyStructSequence, ob_item)
 
513
          + i * sizeof(PyObject*);
 
514
        members[k].flags = READONLY;
 
515
        members[k].doc = desc->fields[i].doc;
 
516
        k++;
 
517
    }
 
518
    members[k].name = NULL;
 
519
 
 
520
    type->tp_members = members;
 
521
 
 
522
    if (PyType_Ready(type) < 0)
 
523
        return;
 
524
    Py_INCREF(type);
 
525
 
 
526
    dict = type->tp_dict;
 
527
#define SET_DICT_FROM_INT(key, value)                           \
 
528
    do {                                                        \
 
529
        PyObject *v = PyLong_FromLong((long) value);            \
 
530
        if (v != NULL) {                                        \
 
531
            PyDict_SetItemString(dict, key, v);                 \
 
532
            Py_DECREF(v);                                       \
 
533
        }                                                       \
 
534
    } while (0)
 
535
 
 
536
    SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);
 
537
    SET_DICT_FROM_INT(real_length_key, n_members);
 
538
    SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
539
539
}