blob: 960d78af05c5012aca92a9fa7d6b31581ed8df73 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Tuple object implementation */
2
3#include <stdio.h>
4
5#include "PROTO.h"
6#include "object.h"
7#include "stringobject.h"
8#include "tupleobject.h"
9#include "intobject.h"
10#include "objimpl.h"
Guido van Rossum2a9096b1990-10-21 22:15:08 +000011#include "errors.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012
13typedef struct {
14 OB_VARHEAD
15 object *ob_item[1];
16} tupleobject;
17
18object *
19newtupleobject(size)
20 register int size;
21{
22 register int i;
23 register tupleobject *op;
24 if (size < 0) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000025 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000026 return NULL;
27 }
28 op = (tupleobject *)
29 malloc(sizeof(tupleobject) + size * sizeof(object *));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000030 if (op == NULL)
31 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032 NEWREF(op);
33 op->ob_type = &Tupletype;
34 op->ob_size = size;
35 for (i = 0; i < size; i++)
36 op->ob_item[i] = NULL;
37 return (object *) op;
38}
39
40int
41gettuplesize(op)
42 register object *op;
43{
44 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000045 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046 return -1;
47 }
48 else
49 return ((tupleobject *)op)->ob_size;
50}
51
52object *
53gettupleitem(op, i)
54 register object *op;
55 register int i;
56{
57 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000058 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059 return NULL;
60 }
61 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000062 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000063 return NULL;
64 }
65 return ((tupleobject *)op) -> ob_item[i];
66}
67
68int
69settupleitem(op, i, newitem)
70 register object *op;
71 register int i;
72 register object *newitem;
73{
74 register object *olditem;
75 if (!is_tupleobject(op)) {
76 if (newitem != NULL)
77 DECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000078 err_badcall();
79 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 }
81 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
82 if (newitem != NULL)
83 DECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000084 err_setstr(IndexError, "tuple assignment index out of range");
85 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086 }
87 olditem = ((tupleobject *)op) -> ob_item[i];
88 ((tupleobject *)op) -> ob_item[i] = newitem;
89 if (olditem != NULL)
90 DECREF(olditem);
91 return 0;
92}
93
94/* Methods */
95
96static void
97tupledealloc(op)
98 register tupleobject *op;
99{
100 register int i;
101 for (i = 0; i < op->ob_size; i++) {
102 if (op->ob_item[i] != NULL)
103 DECREF(op->ob_item[i]);
104 }
105 free((ANY *)op);
106}
107
108static void
109tupleprint(op, fp, flags)
110 tupleobject *op;
111 FILE *fp;
112 int flags;
113{
114 int i;
115 fprintf(fp, "(");
116 for (i = 0; i < op->ob_size && !StopPrint; i++) {
117 if (i > 0) {
118 fprintf(fp, ", ");
119 }
120 printobject(op->ob_item[i], fp, flags);
121 }
122 if (op->ob_size == 1)
123 fprintf(fp, ",");
124 fprintf(fp, ")");
125}
126
127object *
128tuplerepr(v)
129 tupleobject *v;
130{
131 object *s, *t, *comma;
132 int i;
133 s = newstringobject("(");
134 comma = newstringobject(", ");
135 for (i = 0; i < v->ob_size && s != NULL; i++) {
136 if (i > 0)
137 joinstring(&s, comma);
138 t = reprobject(v->ob_item[i]);
139 joinstring(&s, t);
140 if (t != NULL)
141 DECREF(t);
142 }
143 DECREF(comma);
144 if (v->ob_size == 1) {
145 t = newstringobject(",");
146 joinstring(&s, t);
147 DECREF(t);
148 }
149 t = newstringobject(")");
150 joinstring(&s, t);
151 DECREF(t);
152 return s;
153}
154
155static int
156tuplecompare(v, w)
157 register tupleobject *v, *w;
158{
159 register int len =
160 (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
161 register int i;
162 for (i = 0; i < len; i++) {
163 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
164 if (cmp != 0)
165 return cmp;
166 }
167 return v->ob_size - w->ob_size;
168}
169
170static int
171tuplelength(a)
172 tupleobject *a;
173{
174 return a->ob_size;
175}
176
177static object *
178tupleitem(a, i)
179 register tupleobject *a;
180 register int i;
181{
182 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000183 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 return NULL;
185 }
186 INCREF(a->ob_item[i]);
187 return a->ob_item[i];
188}
189
190static object *
191tupleslice(a, ilow, ihigh)
192 register tupleobject *a;
193 register int ilow, ihigh;
194{
195 register tupleobject *np;
196 register int i;
197 if (ilow < 0)
198 ilow = 0;
199 if (ihigh > a->ob_size)
200 ihigh = a->ob_size;
201 if (ihigh < ilow)
202 ihigh = ilow;
203 if (ilow == 0 && ihigh == a->ob_size) {
204 /* XXX can only do this if tuples are immutable! */
205 INCREF(a);
206 return (object *)a;
207 }
208 np = (tupleobject *)newtupleobject(ihigh - ilow);
209 if (np == NULL)
210 return NULL;
211 for (i = ilow; i < ihigh; i++) {
212 object *v = a->ob_item[i];
213 INCREF(v);
214 np->ob_item[i - ilow] = v;
215 }
216 return (object *)np;
217}
218
219static object *
220tupleconcat(a, bb)
221 register tupleobject *a;
222 register object *bb;
223{
224 register int size;
225 register int i;
226 tupleobject *np;
227 if (!is_tupleobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000228 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 return NULL;
230 }
231#define b ((tupleobject *)bb)
232 size = a->ob_size + b->ob_size;
233 np = (tupleobject *) newtupleobject(size);
234 if (np == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000235 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236 }
237 for (i = 0; i < a->ob_size; i++) {
238 object *v = a->ob_item[i];
239 INCREF(v);
240 np->ob_item[i] = v;
241 }
242 for (i = 0; i < b->ob_size; i++) {
243 object *v = b->ob_item[i];
244 INCREF(v);
245 np->ob_item[i + a->ob_size] = v;
246 }
247 return (object *)np;
248#undef b
249}
250
251static sequence_methods tuple_as_sequence = {
252 tuplelength, /*sq_length*/
253 tupleconcat, /*sq_concat*/
254 0, /*sq_repeat*/
255 tupleitem, /*sq_item*/
256 tupleslice, /*sq_slice*/
257 0, /*sq_ass_item*/
258 0, /*sq_ass_slice*/
259};
260
261typeobject Tupletype = {
262 OB_HEAD_INIT(&Typetype)
263 0,
264 "tuple",
265 sizeof(tupleobject) - sizeof(object *),
266 sizeof(object *),
267 tupledealloc, /*tp_dealloc*/
268 tupleprint, /*tp_print*/
269 0, /*tp_getattr*/
270 0, /*tp_setattr*/
271 tuplecompare, /*tp_compare*/
272 tuplerepr, /*tp_repr*/
273 0, /*tp_as_number*/
274 &tuple_as_sequence, /*tp_as_sequence*/
275 0, /*tp_as_mapping*/
276};