blob: 89ba4e9147b3b56e45073136bef11eb1a9bad9ac [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Tuple object implementation */
2
Guido van Rossum3f5da241990-12-20 15:06:42 +00003#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004
5object *
6newtupleobject(size)
7 register int size;
8{
9 register int i;
10 register tupleobject *op;
11 if (size < 0) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000012 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013 return NULL;
14 }
15 op = (tupleobject *)
16 malloc(sizeof(tupleobject) + size * sizeof(object *));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000017 if (op == NULL)
18 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000019 NEWREF(op);
20 op->ob_type = &Tupletype;
21 op->ob_size = size;
22 for (i = 0; i < size; i++)
23 op->ob_item[i] = NULL;
24 return (object *) op;
25}
26
27int
28gettuplesize(op)
29 register object *op;
30{
31 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000032 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000033 return -1;
34 }
35 else
36 return ((tupleobject *)op)->ob_size;
37}
38
39object *
40gettupleitem(op, i)
41 register object *op;
42 register int i;
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 NULL;
47 }
48 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000049 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050 return NULL;
51 }
52 return ((tupleobject *)op) -> ob_item[i];
53}
54
55int
56settupleitem(op, i, newitem)
57 register object *op;
58 register int i;
59 register object *newitem;
60{
61 register object *olditem;
62 if (!is_tupleobject(op)) {
63 if (newitem != NULL)
64 DECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000065 err_badcall();
66 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067 }
68 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
69 if (newitem != NULL)
70 DECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000071 err_setstr(IndexError, "tuple assignment index out of range");
72 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 }
74 olditem = ((tupleobject *)op) -> ob_item[i];
75 ((tupleobject *)op) -> ob_item[i] = newitem;
76 if (olditem != NULL)
77 DECREF(olditem);
78 return 0;
79}
80
81/* Methods */
82
83static void
84tupledealloc(op)
85 register tupleobject *op;
86{
87 register int i;
88 for (i = 0; i < op->ob_size; i++) {
89 if (op->ob_item[i] != NULL)
90 DECREF(op->ob_item[i]);
91 }
92 free((ANY *)op);
93}
94
95static void
96tupleprint(op, fp, flags)
97 tupleobject *op;
98 FILE *fp;
99 int flags;
100{
101 int i;
102 fprintf(fp, "(");
103 for (i = 0; i < op->ob_size && !StopPrint; i++) {
104 if (i > 0) {
105 fprintf(fp, ", ");
106 }
107 printobject(op->ob_item[i], fp, flags);
108 }
109 if (op->ob_size == 1)
110 fprintf(fp, ",");
111 fprintf(fp, ")");
112}
113
114object *
115tuplerepr(v)
116 tupleobject *v;
117{
118 object *s, *t, *comma;
119 int i;
120 s = newstringobject("(");
121 comma = newstringobject(", ");
122 for (i = 0; i < v->ob_size && s != NULL; i++) {
123 if (i > 0)
124 joinstring(&s, comma);
125 t = reprobject(v->ob_item[i]);
126 joinstring(&s, t);
127 if (t != NULL)
128 DECREF(t);
129 }
130 DECREF(comma);
131 if (v->ob_size == 1) {
132 t = newstringobject(",");
133 joinstring(&s, t);
134 DECREF(t);
135 }
136 t = newstringobject(")");
137 joinstring(&s, t);
138 DECREF(t);
139 return s;
140}
141
142static int
143tuplecompare(v, w)
144 register tupleobject *v, *w;
145{
146 register int len =
147 (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
148 register int i;
149 for (i = 0; i < len; i++) {
150 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
151 if (cmp != 0)
152 return cmp;
153 }
154 return v->ob_size - w->ob_size;
155}
156
157static int
158tuplelength(a)
159 tupleobject *a;
160{
161 return a->ob_size;
162}
163
164static object *
165tupleitem(a, i)
166 register tupleobject *a;
167 register int i;
168{
169 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000170 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171 return NULL;
172 }
173 INCREF(a->ob_item[i]);
174 return a->ob_item[i];
175}
176
177static object *
178tupleslice(a, ilow, ihigh)
179 register tupleobject *a;
180 register int ilow, ihigh;
181{
182 register tupleobject *np;
183 register int i;
184 if (ilow < 0)
185 ilow = 0;
186 if (ihigh > a->ob_size)
187 ihigh = a->ob_size;
188 if (ihigh < ilow)
189 ihigh = ilow;
190 if (ilow == 0 && ihigh == a->ob_size) {
191 /* XXX can only do this if tuples are immutable! */
192 INCREF(a);
193 return (object *)a;
194 }
195 np = (tupleobject *)newtupleobject(ihigh - ilow);
196 if (np == NULL)
197 return NULL;
198 for (i = ilow; i < ihigh; i++) {
199 object *v = a->ob_item[i];
200 INCREF(v);
201 np->ob_item[i - ilow] = v;
202 }
203 return (object *)np;
204}
205
206static object *
207tupleconcat(a, bb)
208 register tupleobject *a;
209 register object *bb;
210{
211 register int size;
212 register int i;
213 tupleobject *np;
214 if (!is_tupleobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000215 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216 return NULL;
217 }
218#define b ((tupleobject *)bb)
219 size = a->ob_size + b->ob_size;
220 np = (tupleobject *) newtupleobject(size);
221 if (np == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000222 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223 }
224 for (i = 0; i < a->ob_size; i++) {
225 object *v = a->ob_item[i];
226 INCREF(v);
227 np->ob_item[i] = v;
228 }
229 for (i = 0; i < b->ob_size; i++) {
230 object *v = b->ob_item[i];
231 INCREF(v);
232 np->ob_item[i + a->ob_size] = v;
233 }
234 return (object *)np;
235#undef b
236}
237
238static sequence_methods tuple_as_sequence = {
239 tuplelength, /*sq_length*/
240 tupleconcat, /*sq_concat*/
241 0, /*sq_repeat*/
242 tupleitem, /*sq_item*/
243 tupleslice, /*sq_slice*/
244 0, /*sq_ass_item*/
245 0, /*sq_ass_slice*/
246};
247
248typeobject Tupletype = {
249 OB_HEAD_INIT(&Typetype)
250 0,
251 "tuple",
252 sizeof(tupleobject) - sizeof(object *),
253 sizeof(object *),
254 tupledealloc, /*tp_dealloc*/
255 tupleprint, /*tp_print*/
256 0, /*tp_getattr*/
257 0, /*tp_setattr*/
258 tuplecompare, /*tp_compare*/
259 tuplerepr, /*tp_repr*/
260 0, /*tp_as_number*/
261 &tuple_as_sequence, /*tp_as_sequence*/
262 0, /*tp_as_mapping*/
263};