blob: 02d77a254973e8d757c5275ba78174d70c68f271 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Tuple object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
29object *
30newtupleobject(size)
31 register int size;
32{
33 register int i;
34 register tupleobject *op;
35 if (size < 0) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000036 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037 return NULL;
38 }
39 op = (tupleobject *)
40 malloc(sizeof(tupleobject) + size * sizeof(object *));
Guido van Rossum2a9096b1990-10-21 22:15:08 +000041 if (op == NULL)
42 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043 NEWREF(op);
44 op->ob_type = &Tupletype;
45 op->ob_size = size;
46 for (i = 0; i < size; i++)
47 op->ob_item[i] = NULL;
48 return (object *) op;
49}
50
51int
52gettuplesize(op)
53 register object *op;
54{
55 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000056 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057 return -1;
58 }
59 else
60 return ((tupleobject *)op)->ob_size;
61}
62
63object *
64gettupleitem(op, i)
65 register object *op;
66 register int i;
67{
68 if (!is_tupleobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000069 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070 return NULL;
71 }
72 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000073 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 return NULL;
75 }
76 return ((tupleobject *)op) -> ob_item[i];
77}
78
79int
80settupleitem(op, i, newitem)
81 register object *op;
82 register int i;
83 register object *newitem;
84{
85 register object *olditem;
86 if (!is_tupleobject(op)) {
87 if (newitem != NULL)
88 DECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000089 err_badcall();
90 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 }
92 if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
93 if (newitem != NULL)
94 DECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000095 err_setstr(IndexError, "tuple assignment index out of range");
96 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 }
98 olditem = ((tupleobject *)op) -> ob_item[i];
99 ((tupleobject *)op) -> ob_item[i] = newitem;
100 if (olditem != NULL)
101 DECREF(olditem);
102 return 0;
103}
104
105/* Methods */
106
107static void
108tupledealloc(op)
109 register tupleobject *op;
110{
111 register int i;
112 for (i = 0; i < op->ob_size; i++) {
113 if (op->ob_item[i] != NULL)
114 DECREF(op->ob_item[i]);
115 }
116 free((ANY *)op);
117}
118
119static void
120tupleprint(op, fp, flags)
121 tupleobject *op;
122 FILE *fp;
123 int flags;
124{
125 int i;
126 fprintf(fp, "(");
127 for (i = 0; i < op->ob_size && !StopPrint; i++) {
128 if (i > 0) {
129 fprintf(fp, ", ");
130 }
131 printobject(op->ob_item[i], fp, flags);
132 }
133 if (op->ob_size == 1)
134 fprintf(fp, ",");
135 fprintf(fp, ")");
136}
137
138object *
139tuplerepr(v)
140 tupleobject *v;
141{
142 object *s, *t, *comma;
143 int i;
144 s = newstringobject("(");
145 comma = newstringobject(", ");
146 for (i = 0; i < v->ob_size && s != NULL; i++) {
147 if (i > 0)
148 joinstring(&s, comma);
149 t = reprobject(v->ob_item[i]);
150 joinstring(&s, t);
151 if (t != NULL)
152 DECREF(t);
153 }
154 DECREF(comma);
155 if (v->ob_size == 1) {
156 t = newstringobject(",");
157 joinstring(&s, t);
158 DECREF(t);
159 }
160 t = newstringobject(")");
161 joinstring(&s, t);
162 DECREF(t);
163 return s;
164}
165
166static int
167tuplecompare(v, w)
168 register tupleobject *v, *w;
169{
170 register int len =
171 (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
172 register int i;
173 for (i = 0; i < len; i++) {
174 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
175 if (cmp != 0)
176 return cmp;
177 }
178 return v->ob_size - w->ob_size;
179}
180
181static int
182tuplelength(a)
183 tupleobject *a;
184{
185 return a->ob_size;
186}
187
188static object *
189tupleitem(a, i)
190 register tupleobject *a;
191 register int i;
192{
193 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000194 err_setstr(IndexError, "tuple index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 return NULL;
196 }
197 INCREF(a->ob_item[i]);
198 return a->ob_item[i];
199}
200
201static object *
202tupleslice(a, ilow, ihigh)
203 register tupleobject *a;
204 register int ilow, ihigh;
205{
206 register tupleobject *np;
207 register int i;
208 if (ilow < 0)
209 ilow = 0;
210 if (ihigh > a->ob_size)
211 ihigh = a->ob_size;
212 if (ihigh < ilow)
213 ihigh = ilow;
214 if (ilow == 0 && ihigh == a->ob_size) {
215 /* XXX can only do this if tuples are immutable! */
216 INCREF(a);
217 return (object *)a;
218 }
219 np = (tupleobject *)newtupleobject(ihigh - ilow);
220 if (np == NULL)
221 return NULL;
222 for (i = ilow; i < ihigh; i++) {
223 object *v = a->ob_item[i];
224 INCREF(v);
225 np->ob_item[i - ilow] = v;
226 }
227 return (object *)np;
228}
229
230static object *
231tupleconcat(a, bb)
232 register tupleobject *a;
233 register object *bb;
234{
235 register int size;
236 register int i;
237 tupleobject *np;
238 if (!is_tupleobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000239 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000240 return NULL;
241 }
242#define b ((tupleobject *)bb)
243 size = a->ob_size + b->ob_size;
244 np = (tupleobject *) newtupleobject(size);
245 if (np == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000246 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247 }
248 for (i = 0; i < a->ob_size; i++) {
249 object *v = a->ob_item[i];
250 INCREF(v);
251 np->ob_item[i] = v;
252 }
253 for (i = 0; i < b->ob_size; i++) {
254 object *v = b->ob_item[i];
255 INCREF(v);
256 np->ob_item[i + a->ob_size] = v;
257 }
258 return (object *)np;
259#undef b
260}
261
262static sequence_methods tuple_as_sequence = {
263 tuplelength, /*sq_length*/
264 tupleconcat, /*sq_concat*/
265 0, /*sq_repeat*/
266 tupleitem, /*sq_item*/
267 tupleslice, /*sq_slice*/
268 0, /*sq_ass_item*/
269 0, /*sq_ass_slice*/
270};
271
272typeobject Tupletype = {
273 OB_HEAD_INIT(&Typetype)
274 0,
275 "tuple",
276 sizeof(tupleobject) - sizeof(object *),
277 sizeof(object *),
278 tupledealloc, /*tp_dealloc*/
279 tupleprint, /*tp_print*/
280 0, /*tp_getattr*/
281 0, /*tp_setattr*/
282 tuplecompare, /*tp_compare*/
283 tuplerepr, /*tp_repr*/
284 0, /*tp_as_number*/
285 &tuple_as_sequence, /*tp_as_sequence*/
286 0, /*tp_as_mapping*/
287};