blob: 17307f7e17f18261e5af4bae806c48368d9c40fe [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
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/* List object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossumfa3da8a1992-01-27 16:53:23 +000028#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000029#include "ceval.h"
Guido van Rossum6cd2fe01994-08-29 12:45:32 +000030#ifdef STDC_HEADERS
31#include <stddef.h>
32#else
33#include <sys/types.h> /* For size_t */
34#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035
Guido van Rossuma46d51d1995-01-26 22:59:43 +000036#define ROUNDUP(n, block) ((((n)+(block)-1)/(block))*(block))
37
38static int
39roundup(n)
40 int n;
41{
42 if (n < 500)
43 return ROUNDUP(n, 10);
44 else
45 return ROUNDUP(n, 100);
46}
47
48#define NRESIZE(var, type, nitems) RESIZE(var, type, roundup(nitems))
49
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050object *
51newlistobject(size)
52 int size;
53{
54 int i;
55 listobject *op;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +000056 size_t nbytes;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057 if (size < 0) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000058 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059 return NULL;
60 }
Guido van Rossum1e28e5e1992-08-19 16:46:30 +000061 nbytes = size * sizeof(object *);
62 /* Check for overflow */
63 if (nbytes / sizeof(object *) != size) {
64 return err_nomem();
65 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066 op = (listobject *) malloc(sizeof(listobject));
67 if (op == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000068 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 }
70 if (size <= 0) {
71 op->ob_item = NULL;
72 }
73 else {
Guido van Rossum1e28e5e1992-08-19 16:46:30 +000074 op->ob_item = (object **) malloc(nbytes);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 if (op->ob_item == NULL) {
76 free((ANY *)op);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000077 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078 }
79 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 op->ob_type = &Listtype;
81 op->ob_size = size;
82 for (i = 0; i < size; i++)
83 op->ob_item[i] = NULL;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000084 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 return (object *) op;
86}
87
88int
89getlistsize(op)
90 object *op;
91{
92 if (!is_listobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000093 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094 return -1;
95 }
96 else
97 return ((listobject *)op) -> ob_size;
98}
99
Guido van Rossum929f1b81996-08-09 20:51:27 +0000100static object *indexerr;
101
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102object *
103getlistitem(op, i)
104 object *op;
105 int i;
106{
107 if (!is_listobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000108 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109 return NULL;
110 }
111 if (i < 0 || i >= ((listobject *)op) -> ob_size) {
Guido van Rossum929f1b81996-08-09 20:51:27 +0000112 if (indexerr == NULL)
113 indexerr = newstringobject("list index out of range");
114 err_setval(IndexError, indexerr);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 return NULL;
116 }
117 return ((listobject *)op) -> ob_item[i];
118}
119
120int
121setlistitem(op, i, newitem)
122 register object *op;
123 register int i;
124 register object *newitem;
125{
126 register object *olditem;
Guido van Rossum5fe60581995-03-09 12:12:50 +0000127 register object **p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000128 if (!is_listobject(op)) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000129 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000130 err_badcall();
131 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000132 }
133 if (i < 0 || i >= ((listobject *)op) -> ob_size) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000134 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000135 err_setstr(IndexError, "list assignment index out of range");
136 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 }
Guido van Rossum5fe60581995-03-09 12:12:50 +0000138 p = ((listobject *)op) -> ob_item + i;
139 olditem = *p;
140 *p = newitem;
Guido van Rossume6f7d181991-10-20 20:20:40 +0000141 XDECREF(olditem);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000142 return 0;
143}
144
145static int
146ins1(self, where, v)
147 listobject *self;
148 int where;
149 object *v;
150{
151 int i;
152 object **items;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000153 if (v == NULL) {
154 err_badcall();
155 return -1;
156 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 items = self->ob_item;
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000158 NRESIZE(items, object *, self->ob_size+1);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000159 if (items == NULL) {
160 err_nomem();
161 return -1;
162 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163 if (where < 0)
164 where = 0;
165 if (where > self->ob_size)
166 where = self->ob_size;
167 for (i = self->ob_size; --i >= where; )
168 items[i+1] = items[i];
169 INCREF(v);
170 items[where] = v;
171 self->ob_item = items;
172 self->ob_size++;
173 return 0;
174}
175
176int
177inslistitem(op, where, newitem)
178 object *op;
179 int where;
180 object *newitem;
181{
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000182 if (!is_listobject(op)) {
183 err_badcall();
184 return -1;
185 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 return ins1((listobject *)op, where, newitem);
187}
188
189int
190addlistitem(op, newitem)
191 object *op;
192 object *newitem;
193{
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000194 if (!is_listobject(op)) {
195 err_badcall();
196 return -1;
197 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 return ins1((listobject *)op,
199 (int) ((listobject *)op)->ob_size, newitem);
200}
201
202/* Methods */
203
204static void
205list_dealloc(op)
206 listobject *op;
207{
208 int i;
Jack Jansen7874d1f1995-01-19 12:09:27 +0000209 if (op->ob_item != NULL) {
210 for (i = 0; i < op->ob_size; i++) {
211 XDECREF(op->ob_item[i]);
212 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213 free((ANY *)op->ob_item);
Jack Jansen7874d1f1995-01-19 12:09:27 +0000214 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215 free((ANY *)op);
216}
217
Guido van Rossum90933611991-06-07 16:10:43 +0000218static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219list_print(op, fp, flags)
220 listobject *op;
221 FILE *fp;
222 int flags;
223{
224 int i;
225 fprintf(fp, "[");
Guido van Rossum90933611991-06-07 16:10:43 +0000226 for (i = 0; i < op->ob_size; i++) {
227 if (i > 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 fprintf(fp, ", ");
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000229 if (printobject(op->ob_item[i], fp, 0) != 0)
Guido van Rossum90933611991-06-07 16:10:43 +0000230 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 }
232 fprintf(fp, "]");
Guido van Rossum90933611991-06-07 16:10:43 +0000233 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234}
235
Guido van Rossum234f9421993-06-17 12:35:49 +0000236static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237list_repr(v)
238 listobject *v;
239{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000240 object *s, *comma;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241 int i;
242 s = newstringobject("[");
243 comma = newstringobject(", ");
244 for (i = 0; i < v->ob_size && s != NULL; i++) {
245 if (i > 0)
246 joinstring(&s, comma);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000247 joinstring_decref(&s, reprobject(v->ob_item[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000249 XDECREF(comma);
250 joinstring_decref(&s, newstringobject("]"));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 return s;
252}
253
254static int
255list_compare(v, w)
256 listobject *v, *w;
257{
258 int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
259 int i;
260 for (i = 0; i < len; i++) {
261 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
262 if (cmp != 0)
263 return cmp;
264 }
265 return v->ob_size - w->ob_size;
266}
267
268static int
269list_length(a)
270 listobject *a;
271{
272 return a->ob_size;
273}
274
275static object *
276list_item(a, i)
277 listobject *a;
278 int i;
279{
280 if (i < 0 || i >= a->ob_size) {
Guido van Rossum929f1b81996-08-09 20:51:27 +0000281 if (indexerr == NULL)
282 indexerr = newstringobject("list index out of range");
283 err_setval(IndexError, indexerr);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284 return NULL;
285 }
286 INCREF(a->ob_item[i]);
287 return a->ob_item[i];
288}
289
290static object *
291list_slice(a, ilow, ihigh)
292 listobject *a;
293 int ilow, ihigh;
294{
295 listobject *np;
296 int i;
297 if (ilow < 0)
298 ilow = 0;
299 else if (ilow > a->ob_size)
300 ilow = a->ob_size;
301 if (ihigh < 0)
302 ihigh = 0;
303 if (ihigh < ilow)
304 ihigh = ilow;
305 else if (ihigh > a->ob_size)
306 ihigh = a->ob_size;
307 np = (listobject *) newlistobject(ihigh - ilow);
308 if (np == NULL)
309 return NULL;
310 for (i = ilow; i < ihigh; i++) {
311 object *v = a->ob_item[i];
312 INCREF(v);
313 np->ob_item[i - ilow] = v;
314 }
315 return (object *)np;
316}
317
Guido van Rossum234f9421993-06-17 12:35:49 +0000318object *
319getlistslice(a, ilow, ihigh)
320 object *a;
321 int ilow, ihigh;
322{
323 if (!is_listobject(a)) {
324 err_badcall();
325 return NULL;
326 }
327 return list_slice((listobject *)a, ilow, ihigh);
328}
329
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330static object *
331list_concat(a, bb)
332 listobject *a;
333 object *bb;
334{
335 int size;
336 int i;
337 listobject *np;
338 if (!is_listobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000339 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000340 return NULL;
341 }
342#define b ((listobject *)bb)
343 size = a->ob_size + b->ob_size;
344 np = (listobject *) newlistobject(size);
345 if (np == NULL) {
Guido van Rossum90933611991-06-07 16:10:43 +0000346 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347 }
348 for (i = 0; i < a->ob_size; i++) {
349 object *v = a->ob_item[i];
350 INCREF(v);
351 np->ob_item[i] = v;
352 }
353 for (i = 0; i < b->ob_size; i++) {
354 object *v = b->ob_item[i];
355 INCREF(v);
356 np->ob_item[i + a->ob_size] = v;
357 }
358 return (object *)np;
359#undef b
360}
361
Guido van Rossumed98d481991-03-06 13:07:53 +0000362static object *
363list_repeat(a, n)
364 listobject *a;
365 int n;
366{
367 int i, j;
368 int size;
369 listobject *np;
370 object **p;
371 if (n < 0)
372 n = 0;
373 size = a->ob_size * n;
374 np = (listobject *) newlistobject(size);
375 if (np == NULL)
376 return NULL;
377 p = np->ob_item;
378 for (i = 0; i < n; i++) {
379 for (j = 0; j < a->ob_size; j++) {
380 *p = a->ob_item[j];
381 INCREF(*p);
382 p++;
383 }
384 }
385 return (object *) np;
386}
387
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000388static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389list_ass_slice(a, ilow, ihigh, v)
390 listobject *a;
391 int ilow, ihigh;
392 object *v;
393{
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000394 /* Because [X]DECREF can recursively invoke list operations on
395 this list, we must postpone all [X]DECREF activity until
396 after the list is back in its canonical shape. Therefore
397 we must allocate an additional array, 'recycle', into which
398 we temporarily copy the items that are deleted from the
399 list. :-( */
400 object **recycle, **p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 object **item;
402 int n; /* Size of replacement list */
403 int d; /* Change in size */
404 int k; /* Loop index */
405#define b ((listobject *)v)
406 if (v == NULL)
407 n = 0;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000408 else if (is_listobject(v)) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000409 n = b->ob_size;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000410 if (a == b) {
411 /* Special case "a[i:j] = a" -- copy b first */
412 int ret;
413 v = list_slice(b, 0, n);
414 ret = list_ass_slice(a, ilow, ihigh, v);
415 DECREF(v);
416 return ret;
417 }
418 }
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000419 else {
420 err_badarg();
421 return -1;
422 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000423 if (ilow < 0)
424 ilow = 0;
425 else if (ilow > a->ob_size)
426 ilow = a->ob_size;
427 if (ihigh < 0)
428 ihigh = 0;
429 if (ihigh < ilow)
430 ihigh = ilow;
431 else if (ihigh > a->ob_size)
432 ihigh = a->ob_size;
433 item = a->ob_item;
434 d = n - (ihigh-ilow);
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000435 if (ihigh > ilow)
436 p = recycle = NEW(object *, (ihigh-ilow));
437 else
438 p = recycle = NULL;
439 if (d <= 0) { /* Delete -d items; recycle ihigh-ilow items */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000440 for (k = ilow; k < ihigh; k++)
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000441 *p++ = item[k];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000442 if (d < 0) {
443 for (/*k = ihigh*/; k < a->ob_size; k++)
444 item[k+d] = item[k];
445 a->ob_size += d;
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000446 NRESIZE(item, object *, a->ob_size); /* Can't fail */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447 a->ob_item = item;
448 }
449 }
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000450 else { /* Insert d items; recycle ihigh-ilow items */
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000451 NRESIZE(item, object *, a->ob_size + d);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000452 if (item == NULL) {
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000453 XDEL(recycle);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000454 err_nomem();
455 return -1;
456 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457 for (k = a->ob_size; --k >= ihigh; )
458 item[k+d] = item[k];
459 for (/*k = ihigh-1*/; k >= ilow; --k)
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000460 *p++ = item[k];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461 a->ob_item = item;
462 a->ob_size += d;
463 }
464 for (k = 0; k < n; k++, ilow++) {
465 object *w = b->ob_item[k];
Guido van Rossumdc4b93d1993-10-27 14:56:44 +0000466 XINCREF(w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000467 item[ilow] = w;
468 }
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000469 if (recycle) {
470 while (--p >= recycle)
471 XDECREF(*p);
472 DEL(recycle);
473 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 return 0;
475#undef b
476}
477
Guido van Rossum234f9421993-06-17 12:35:49 +0000478int
479setlistslice(a, ilow, ihigh, v)
480 object *a;
481 int ilow, ihigh;
482 object *v;
483{
484 if (!is_listobject(a)) {
485 err_badcall();
Guido van Rossum1fc238a1993-07-29 08:25:09 +0000486 return -1;
Guido van Rossum234f9421993-06-17 12:35:49 +0000487 }
488 return list_ass_slice((listobject *)a, ilow, ihigh, v);
489}
490
Guido van Rossum4a450d01991-04-03 19:05:18 +0000491static int
492list_ass_item(a, i, v)
493 listobject *a;
494 int i;
495 object *v;
496{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000497 object *old_value;
Guido van Rossum4a450d01991-04-03 19:05:18 +0000498 if (i < 0 || i >= a->ob_size) {
499 err_setstr(IndexError, "list assignment index out of range");
500 return -1;
501 }
502 if (v == NULL)
503 return list_ass_slice(a, i, i+1, v);
504 INCREF(v);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000505 old_value = a->ob_item[i];
Guido van Rossum4a450d01991-04-03 19:05:18 +0000506 a->ob_item[i] = v;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000507 DECREF(old_value);
Guido van Rossum4a450d01991-04-03 19:05:18 +0000508 return 0;
509}
510
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511static object *
512ins(self, where, v)
513 listobject *self;
514 int where;
515 object *v;
516{
517 if (ins1(self, where, v) != 0)
518 return NULL;
519 INCREF(None);
520 return None;
521}
522
523static object *
524listinsert(self, args)
525 listobject *self;
526 object *args;
527{
528 int i;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000529 object *v;
530 if (!getargs(args, "(iO)", &i, &v))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000531 return NULL;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000532 return ins(self, i, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000533}
534
535static object *
536listappend(self, args)
537 listobject *self;
538 object *args;
539{
Guido van Rossumbf80e541993-02-08 15:49:17 +0000540 object *v;
541 if (!getargs(args, "O", &v))
542 return NULL;
543 return ins(self, (int) self->ob_size, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000544}
545
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000546static object *comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000547
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548static int
549cmp(v, w)
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000550 const ANY *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000551{
Guido van Rossume10a19e1992-08-03 19:05:37 +0000552 object *t, *res;
553 long i;
554
555 if (err_occurred())
556 return 0;
557
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000558 if (comparefunc == NULL)
Guido van Rossume10a19e1992-08-03 19:05:37 +0000559 return cmpobject(* (object **) v, * (object **) w);
560
561 /* Call the user-supplied comparison function */
Guido van Rossum1311e3c1995-07-12 02:22:06 +0000562 t = mkvalue("(OO)", * (object **) v, * (object **) w);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000563 if (t == NULL)
564 return 0;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000565 res = call_object(comparefunc, t);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000566 DECREF(t);
567 if (res == NULL)
568 return 0;
569 if (!is_intobject(res)) {
570 err_setstr(TypeError, "comparison function should return int");
571 i = 0;
572 }
573 else {
574 i = getintvalue(res);
575 if (i < 0)
576 i = -1;
577 else if (i > 0)
578 i = 1;
579 }
580 DECREF(res);
581 return (int) i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000582}
583
584static object *
585listsort(self, args)
586 listobject *self;
587 object *args;
588{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000589 object *save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000590 if (self->ob_size <= 1) {
591 INCREF(None);
592 return None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000593 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000594 save_comparefunc = comparefunc;
595 comparefunc = args;
596 if (comparefunc != NULL) {
Guido van Rossume10a19e1992-08-03 19:05:37 +0000597 /* Test the comparison function for obvious errors */
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000598 (void) cmp((ANY *)&self->ob_item[0], (ANY *)&self->ob_item[1]);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000599 if (err_occurred()) {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000600 comparefunc = save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000601 return NULL;
602 }
603 }
604 qsort((char *)self->ob_item,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000605 (int) self->ob_size, sizeof(object *), cmp);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000606 comparefunc = save_comparefunc;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000607 if (err_occurred())
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608 return NULL;
609 INCREF(None);
610 return None;
611}
612
Guido van Rossumed98d481991-03-06 13:07:53 +0000613static object *
614listreverse(self, args)
615 listobject *self;
616 object *args;
617{
618 register object **p, **q;
619 register object *tmp;
620
621 if (args != NULL) {
622 err_badarg();
623 return NULL;
624 }
625
626 if (self->ob_size > 1) {
627 for (p = self->ob_item, q = self->ob_item + self->ob_size - 1;
628 p < q; p++, q--) {
629 tmp = *p;
630 *p = *q;
631 *q = tmp;
632 }
633 }
634
635 INCREF(None);
636 return None;
637}
638
Guido van Rossum84c76f51990-10-30 13:32:20 +0000639int
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000640reverselist(v)
641 object *v;
642{
643 if (v == NULL || !is_listobject(v)) {
644 err_badcall();
645 return -1;
646 }
647 v = listreverse((listobject *)v, (object *)NULL);
648 if (v == NULL)
649 return -1;
650 DECREF(v);
651 return 0;
652}
653
654int
Guido van Rossum84c76f51990-10-30 13:32:20 +0000655sortlist(v)
656 object *v;
657{
658 if (v == NULL || !is_listobject(v)) {
659 err_badcall();
660 return -1;
661 }
662 v = listsort((listobject *)v, (object *)NULL);
663 if (v == NULL)
664 return -1;
665 DECREF(v);
666 return 0;
667}
668
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000669object *
670listtuple(v)
671 object *v;
672{
673 object *w;
674 object **p;
675 int n;
676 if (v == NULL || !is_listobject(v)) {
677 err_badcall();
678 return NULL;
679 }
680 n = ((listobject *)v)->ob_size;
681 w = newtupleobject(n);
682 if (w == NULL)
683 return NULL;
684 p = ((tupleobject *)w)->ob_item;
685 memcpy((ANY *)p,
686 (ANY *)((listobject *)v)->ob_item,
687 n*sizeof(object *));
688 while (--n >= 0) {
689 INCREF(*p);
690 p++;
691 }
692 return w;
693}
694
Guido van Rossumed98d481991-03-06 13:07:53 +0000695static object *
696listindex(self, args)
697 listobject *self;
698 object *args;
699{
700 int i;
701
702 if (args == NULL) {
703 err_badarg();
704 return NULL;
705 }
706 for (i = 0; i < self->ob_size; i++) {
707 if (cmpobject(self->ob_item[i], args) == 0)
Guido van Rossum7066dd71992-09-17 17:54:56 +0000708 return newintobject((long)i);
Guido van Rossumed98d481991-03-06 13:07:53 +0000709 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000710 err_setstr(ValueError, "list.index(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000711 return NULL;
712}
713
714static object *
Guido van Rossume6f7d181991-10-20 20:20:40 +0000715listcount(self, args)
716 listobject *self;
717 object *args;
718{
719 int count = 0;
720 int i;
721
722 if (args == NULL) {
723 err_badarg();
724 return NULL;
725 }
726 for (i = 0; i < self->ob_size; i++) {
727 if (cmpobject(self->ob_item[i], args) == 0)
728 count++;
729 }
730 return newintobject((long)count);
731}
732
733static object *
Guido van Rossumed98d481991-03-06 13:07:53 +0000734listremove(self, args)
735 listobject *self;
736 object *args;
737{
738 int i;
739
740 if (args == NULL) {
741 err_badarg();
742 return NULL;
743 }
744 for (i = 0; i < self->ob_size; i++) {
745 if (cmpobject(self->ob_item[i], args) == 0) {
746 if (list_ass_slice(self, i, i+1, (object *)NULL) != 0)
747 return NULL;
748 INCREF(None);
749 return None;
750 }
751
752 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000753 err_setstr(ValueError, "list.remove(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000754 return NULL;
755}
756
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000757static struct methodlist list_methods[] = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000758 {"append", (method)listappend},
759 {"count", (method)listcount},
760 {"index", (method)listindex},
761 {"insert", (method)listinsert},
Guido van Rossum295d1711995-02-19 15:55:19 +0000762 {"sort", (method)listsort, 0},
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000763 {"remove", (method)listremove},
764 {"reverse", (method)listreverse},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765 {NULL, NULL} /* sentinel */
766};
767
768static object *
769list_getattr(f, name)
770 listobject *f;
771 char *name;
772{
773 return findmethod(list_methods, (object *)f, name);
774}
775
776static sequence_methods list_as_sequence = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000777 (inquiry)list_length, /*sq_length*/
778 (binaryfunc)list_concat, /*sq_concat*/
779 (intargfunc)list_repeat, /*sq_repeat*/
780 (intargfunc)list_item, /*sq_item*/
781 (intintargfunc)list_slice, /*sq_slice*/
782 (intobjargproc)list_ass_item, /*sq_ass_item*/
783 (intintobjargproc)list_ass_slice, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000784};
785
786typeobject Listtype = {
787 OB_HEAD_INIT(&Typetype)
788 0,
789 "list",
790 sizeof(listobject),
791 0,
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000792 (destructor)list_dealloc, /*tp_dealloc*/
793 (printfunc)list_print, /*tp_print*/
794 (getattrfunc)list_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795 0, /*tp_setattr*/
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000796 (cmpfunc)list_compare, /*tp_compare*/
797 (reprfunc)list_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000798 0, /*tp_as_number*/
799 &list_as_sequence, /*tp_as_sequence*/
800 0, /*tp_as_mapping*/
801};