blob: 21d0166808911a16798bb873300449d646ca784d [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
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* List object implementation */
33
Guido van Rossum3f5da241990-12-20 15:06:42 +000034#include "allobjects.h"
Guido van Rossumfa3da8a1992-01-27 16:53:23 +000035#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000036#include "ceval.h"
Guido van Rossum6cd2fe01994-08-29 12:45:32 +000037#ifdef STDC_HEADERS
38#include <stddef.h>
39#else
40#include <sys/types.h> /* For size_t */
41#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000042
Guido van Rossuma46d51d1995-01-26 22:59:43 +000043#define ROUNDUP(n, block) ((((n)+(block)-1)/(block))*(block))
44
45static int
46roundup(n)
47 int n;
48{
49 if (n < 500)
50 return ROUNDUP(n, 10);
51 else
52 return ROUNDUP(n, 100);
53}
54
55#define NRESIZE(var, type, nitems) RESIZE(var, type, roundup(nitems))
56
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057object *
58newlistobject(size)
59 int size;
60{
61 int i;
62 listobject *op;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +000063 size_t nbytes;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064 if (size < 0) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000065 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066 return NULL;
67 }
Guido van Rossum1e28e5e1992-08-19 16:46:30 +000068 nbytes = size * sizeof(object *);
69 /* Check for overflow */
70 if (nbytes / sizeof(object *) != size) {
71 return err_nomem();
72 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 op = (listobject *) malloc(sizeof(listobject));
74 if (op == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000075 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 }
77 if (size <= 0) {
78 op->ob_item = NULL;
79 }
80 else {
Guido van Rossum1e28e5e1992-08-19 16:46:30 +000081 op->ob_item = (object **) malloc(nbytes);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 if (op->ob_item == NULL) {
83 free((ANY *)op);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000084 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 }
86 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 op->ob_type = &Listtype;
88 op->ob_size = size;
89 for (i = 0; i < size; i++)
90 op->ob_item[i] = NULL;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000091 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 return (object *) op;
93}
94
95int
96getlistsize(op)
97 object *op;
98{
99 if (!is_listobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000100 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101 return -1;
102 }
103 else
104 return ((listobject *)op) -> ob_size;
105}
106
Guido van Rossum929f1b81996-08-09 20:51:27 +0000107static object *indexerr;
108
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109object *
110getlistitem(op, i)
111 object *op;
112 int i;
113{
114 if (!is_listobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000115 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116 return NULL;
117 }
118 if (i < 0 || i >= ((listobject *)op) -> ob_size) {
Guido van Rossum929f1b81996-08-09 20:51:27 +0000119 if (indexerr == NULL)
120 indexerr = newstringobject("list index out of range");
121 err_setval(IndexError, indexerr);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122 return NULL;
123 }
124 return ((listobject *)op) -> ob_item[i];
125}
126
127int
128setlistitem(op, i, newitem)
129 register object *op;
130 register int i;
131 register object *newitem;
132{
133 register object *olditem;
Guido van Rossum5fe60581995-03-09 12:12:50 +0000134 register object **p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 if (!is_listobject(op)) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000136 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000137 err_badcall();
138 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139 }
140 if (i < 0 || i >= ((listobject *)op) -> ob_size) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000141 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000142 err_setstr(IndexError, "list assignment index out of range");
143 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144 }
Guido van Rossum5fe60581995-03-09 12:12:50 +0000145 p = ((listobject *)op) -> ob_item + i;
146 olditem = *p;
147 *p = newitem;
Guido van Rossume6f7d181991-10-20 20:20:40 +0000148 XDECREF(olditem);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149 return 0;
150}
151
152static int
153ins1(self, where, v)
154 listobject *self;
155 int where;
156 object *v;
157{
158 int i;
159 object **items;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000160 if (v == NULL) {
161 err_badcall();
162 return -1;
163 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164 items = self->ob_item;
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000165 NRESIZE(items, object *, self->ob_size+1);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000166 if (items == NULL) {
167 err_nomem();
168 return -1;
169 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170 if (where < 0)
171 where = 0;
172 if (where > self->ob_size)
173 where = self->ob_size;
174 for (i = self->ob_size; --i >= where; )
175 items[i+1] = items[i];
176 INCREF(v);
177 items[where] = v;
178 self->ob_item = items;
179 self->ob_size++;
180 return 0;
181}
182
183int
184inslistitem(op, where, newitem)
185 object *op;
186 int where;
187 object *newitem;
188{
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000189 if (!is_listobject(op)) {
190 err_badcall();
191 return -1;
192 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 return ins1((listobject *)op, where, newitem);
194}
195
196int
197addlistitem(op, newitem)
198 object *op;
199 object *newitem;
200{
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000201 if (!is_listobject(op)) {
202 err_badcall();
203 return -1;
204 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205 return ins1((listobject *)op,
206 (int) ((listobject *)op)->ob_size, newitem);
207}
208
209/* Methods */
210
211static void
212list_dealloc(op)
213 listobject *op;
214{
215 int i;
Jack Jansen7874d1f1995-01-19 12:09:27 +0000216 if (op->ob_item != NULL) {
217 for (i = 0; i < op->ob_size; i++) {
218 XDECREF(op->ob_item[i]);
219 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 free((ANY *)op->ob_item);
Jack Jansen7874d1f1995-01-19 12:09:27 +0000221 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 free((ANY *)op);
223}
224
Guido van Rossum90933611991-06-07 16:10:43 +0000225static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226list_print(op, fp, flags)
227 listobject *op;
228 FILE *fp;
229 int flags;
230{
231 int i;
232 fprintf(fp, "[");
Guido van Rossum90933611991-06-07 16:10:43 +0000233 for (i = 0; i < op->ob_size; i++) {
234 if (i > 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 fprintf(fp, ", ");
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000236 if (printobject(op->ob_item[i], fp, 0) != 0)
Guido van Rossum90933611991-06-07 16:10:43 +0000237 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238 }
239 fprintf(fp, "]");
Guido van Rossum90933611991-06-07 16:10:43 +0000240 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241}
242
Guido van Rossum234f9421993-06-17 12:35:49 +0000243static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244list_repr(v)
245 listobject *v;
246{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000247 object *s, *comma;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248 int i;
249 s = newstringobject("[");
250 comma = newstringobject(", ");
251 for (i = 0; i < v->ob_size && s != NULL; i++) {
252 if (i > 0)
253 joinstring(&s, comma);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000254 joinstring_decref(&s, reprobject(v->ob_item[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000255 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000256 XDECREF(comma);
257 joinstring_decref(&s, newstringobject("]"));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258 return s;
259}
260
261static int
262list_compare(v, w)
263 listobject *v, *w;
264{
265 int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
266 int i;
267 for (i = 0; i < len; i++) {
268 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
269 if (cmp != 0)
270 return cmp;
271 }
272 return v->ob_size - w->ob_size;
273}
274
275static int
276list_length(a)
277 listobject *a;
278{
279 return a->ob_size;
280}
281
282static object *
283list_item(a, i)
284 listobject *a;
285 int i;
286{
287 if (i < 0 || i >= a->ob_size) {
Guido van Rossum929f1b81996-08-09 20:51:27 +0000288 if (indexerr == NULL)
289 indexerr = newstringobject("list index out of range");
290 err_setval(IndexError, indexerr);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291 return NULL;
292 }
293 INCREF(a->ob_item[i]);
294 return a->ob_item[i];
295}
296
297static object *
298list_slice(a, ilow, ihigh)
299 listobject *a;
300 int ilow, ihigh;
301{
302 listobject *np;
303 int i;
304 if (ilow < 0)
305 ilow = 0;
306 else if (ilow > a->ob_size)
307 ilow = a->ob_size;
308 if (ihigh < 0)
309 ihigh = 0;
310 if (ihigh < ilow)
311 ihigh = ilow;
312 else if (ihigh > a->ob_size)
313 ihigh = a->ob_size;
314 np = (listobject *) newlistobject(ihigh - ilow);
315 if (np == NULL)
316 return NULL;
317 for (i = ilow; i < ihigh; i++) {
318 object *v = a->ob_item[i];
319 INCREF(v);
320 np->ob_item[i - ilow] = v;
321 }
322 return (object *)np;
323}
324
Guido van Rossum234f9421993-06-17 12:35:49 +0000325object *
326getlistslice(a, ilow, ihigh)
327 object *a;
328 int ilow, ihigh;
329{
330 if (!is_listobject(a)) {
331 err_badcall();
332 return NULL;
333 }
334 return list_slice((listobject *)a, ilow, ihigh);
335}
336
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337static object *
338list_concat(a, bb)
339 listobject *a;
340 object *bb;
341{
342 int size;
343 int i;
344 listobject *np;
345 if (!is_listobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000346 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347 return NULL;
348 }
349#define b ((listobject *)bb)
350 size = a->ob_size + b->ob_size;
351 np = (listobject *) newlistobject(size);
352 if (np == NULL) {
Guido van Rossum90933611991-06-07 16:10:43 +0000353 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354 }
355 for (i = 0; i < a->ob_size; i++) {
356 object *v = a->ob_item[i];
357 INCREF(v);
358 np->ob_item[i] = v;
359 }
360 for (i = 0; i < b->ob_size; i++) {
361 object *v = b->ob_item[i];
362 INCREF(v);
363 np->ob_item[i + a->ob_size] = v;
364 }
365 return (object *)np;
366#undef b
367}
368
Guido van Rossumed98d481991-03-06 13:07:53 +0000369static object *
370list_repeat(a, n)
371 listobject *a;
372 int n;
373{
374 int i, j;
375 int size;
376 listobject *np;
377 object **p;
378 if (n < 0)
379 n = 0;
380 size = a->ob_size * n;
381 np = (listobject *) newlistobject(size);
382 if (np == NULL)
383 return NULL;
384 p = np->ob_item;
385 for (i = 0; i < n; i++) {
386 for (j = 0; j < a->ob_size; j++) {
387 *p = a->ob_item[j];
388 INCREF(*p);
389 p++;
390 }
391 }
392 return (object *) np;
393}
394
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000396list_ass_slice(a, ilow, ihigh, v)
397 listobject *a;
398 int ilow, ihigh;
399 object *v;
400{
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000401 /* Because [X]DECREF can recursively invoke list operations on
402 this list, we must postpone all [X]DECREF activity until
403 after the list is back in its canonical shape. Therefore
404 we must allocate an additional array, 'recycle', into which
405 we temporarily copy the items that are deleted from the
406 list. :-( */
407 object **recycle, **p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000408 object **item;
409 int n; /* Size of replacement list */
410 int d; /* Change in size */
411 int k; /* Loop index */
412#define b ((listobject *)v)
413 if (v == NULL)
414 n = 0;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000415 else if (is_listobject(v)) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000416 n = b->ob_size;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000417 if (a == b) {
418 /* Special case "a[i:j] = a" -- copy b first */
419 int ret;
420 v = list_slice(b, 0, n);
421 ret = list_ass_slice(a, ilow, ihigh, v);
422 DECREF(v);
423 return ret;
424 }
425 }
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000426 else {
427 err_badarg();
428 return -1;
429 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000430 if (ilow < 0)
431 ilow = 0;
432 else if (ilow > a->ob_size)
433 ilow = a->ob_size;
434 if (ihigh < 0)
435 ihigh = 0;
436 if (ihigh < ilow)
437 ihigh = ilow;
438 else if (ihigh > a->ob_size)
439 ihigh = a->ob_size;
440 item = a->ob_item;
441 d = n - (ihigh-ilow);
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000442 if (ihigh > ilow)
443 p = recycle = NEW(object *, (ihigh-ilow));
444 else
445 p = recycle = NULL;
446 if (d <= 0) { /* Delete -d items; recycle ihigh-ilow items */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447 for (k = ilow; k < ihigh; k++)
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000448 *p++ = item[k];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449 if (d < 0) {
450 for (/*k = ihigh*/; k < a->ob_size; k++)
451 item[k+d] = item[k];
452 a->ob_size += d;
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000453 NRESIZE(item, object *, a->ob_size); /* Can't fail */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000454 a->ob_item = item;
455 }
456 }
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000457 else { /* Insert d items; recycle ihigh-ilow items */
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000458 NRESIZE(item, object *, a->ob_size + d);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000459 if (item == NULL) {
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000460 XDEL(recycle);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000461 err_nomem();
462 return -1;
463 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000464 for (k = a->ob_size; --k >= ihigh; )
465 item[k+d] = item[k];
466 for (/*k = ihigh-1*/; k >= ilow; --k)
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000467 *p++ = item[k];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000468 a->ob_item = item;
469 a->ob_size += d;
470 }
471 for (k = 0; k < n; k++, ilow++) {
472 object *w = b->ob_item[k];
Guido van Rossumdc4b93d1993-10-27 14:56:44 +0000473 XINCREF(w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 item[ilow] = w;
475 }
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000476 if (recycle) {
477 while (--p >= recycle)
478 XDECREF(*p);
479 DEL(recycle);
480 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481 return 0;
482#undef b
483}
484
Guido van Rossum234f9421993-06-17 12:35:49 +0000485int
486setlistslice(a, ilow, ihigh, v)
487 object *a;
488 int ilow, ihigh;
489 object *v;
490{
491 if (!is_listobject(a)) {
492 err_badcall();
Guido van Rossum1fc238a1993-07-29 08:25:09 +0000493 return -1;
Guido van Rossum234f9421993-06-17 12:35:49 +0000494 }
495 return list_ass_slice((listobject *)a, ilow, ihigh, v);
496}
497
Guido van Rossum4a450d01991-04-03 19:05:18 +0000498static int
499list_ass_item(a, i, v)
500 listobject *a;
501 int i;
502 object *v;
503{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000504 object *old_value;
Guido van Rossum4a450d01991-04-03 19:05:18 +0000505 if (i < 0 || i >= a->ob_size) {
506 err_setstr(IndexError, "list assignment index out of range");
507 return -1;
508 }
509 if (v == NULL)
510 return list_ass_slice(a, i, i+1, v);
511 INCREF(v);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000512 old_value = a->ob_item[i];
Guido van Rossum4a450d01991-04-03 19:05:18 +0000513 a->ob_item[i] = v;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000514 DECREF(old_value);
Guido van Rossum4a450d01991-04-03 19:05:18 +0000515 return 0;
516}
517
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000518static object *
519ins(self, where, v)
520 listobject *self;
521 int where;
522 object *v;
523{
524 if (ins1(self, where, v) != 0)
525 return NULL;
526 INCREF(None);
527 return None;
528}
529
530static object *
531listinsert(self, args)
532 listobject *self;
533 object *args;
534{
535 int i;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000536 object *v;
537 if (!getargs(args, "(iO)", &i, &v))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538 return NULL;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000539 return ins(self, i, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000540}
541
542static object *
543listappend(self, args)
544 listobject *self;
545 object *args;
546{
Guido van Rossumbf80e541993-02-08 15:49:17 +0000547 object *v;
548 if (!getargs(args, "O", &v))
549 return NULL;
550 return ins(self, (int) self->ob_size, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000551}
552
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000553static object *comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000554
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000555static int
556cmp(v, w)
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000557 const ANY *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000558{
Guido van Rossume10a19e1992-08-03 19:05:37 +0000559 object *t, *res;
560 long i;
561
562 if (err_occurred())
563 return 0;
564
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000565 if (comparefunc == NULL)
Guido van Rossume10a19e1992-08-03 19:05:37 +0000566 return cmpobject(* (object **) v, * (object **) w);
567
568 /* Call the user-supplied comparison function */
Guido van Rossum1311e3c1995-07-12 02:22:06 +0000569 t = mkvalue("(OO)", * (object **) v, * (object **) w);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000570 if (t == NULL)
571 return 0;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000572 res = call_object(comparefunc, t);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000573 DECREF(t);
574 if (res == NULL)
575 return 0;
576 if (!is_intobject(res)) {
577 err_setstr(TypeError, "comparison function should return int");
578 i = 0;
579 }
580 else {
581 i = getintvalue(res);
582 if (i < 0)
583 i = -1;
584 else if (i > 0)
585 i = 1;
586 }
587 DECREF(res);
588 return (int) i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000589}
590
591static object *
592listsort(self, args)
593 listobject *self;
594 object *args;
595{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000596 object *save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000597 if (self->ob_size <= 1) {
598 INCREF(None);
599 return None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000600 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000601 save_comparefunc = comparefunc;
602 comparefunc = args;
603 if (comparefunc != NULL) {
Guido van Rossume10a19e1992-08-03 19:05:37 +0000604 /* Test the comparison function for obvious errors */
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000605 (void) cmp((ANY *)&self->ob_item[0], (ANY *)&self->ob_item[1]);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000606 if (err_occurred()) {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000607 comparefunc = save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000608 return NULL;
609 }
610 }
611 qsort((char *)self->ob_item,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612 (int) self->ob_size, sizeof(object *), cmp);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000613 comparefunc = save_comparefunc;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000614 if (err_occurred())
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000615 return NULL;
616 INCREF(None);
617 return None;
618}
619
Guido van Rossumed98d481991-03-06 13:07:53 +0000620static object *
621listreverse(self, args)
622 listobject *self;
623 object *args;
624{
625 register object **p, **q;
626 register object *tmp;
627
628 if (args != NULL) {
629 err_badarg();
630 return NULL;
631 }
632
633 if (self->ob_size > 1) {
634 for (p = self->ob_item, q = self->ob_item + self->ob_size - 1;
635 p < q; p++, q--) {
636 tmp = *p;
637 *p = *q;
638 *q = tmp;
639 }
640 }
641
642 INCREF(None);
643 return None;
644}
645
Guido van Rossum84c76f51990-10-30 13:32:20 +0000646int
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000647reverselist(v)
648 object *v;
649{
650 if (v == NULL || !is_listobject(v)) {
651 err_badcall();
652 return -1;
653 }
654 v = listreverse((listobject *)v, (object *)NULL);
655 if (v == NULL)
656 return -1;
657 DECREF(v);
658 return 0;
659}
660
661int
Guido van Rossum84c76f51990-10-30 13:32:20 +0000662sortlist(v)
663 object *v;
664{
665 if (v == NULL || !is_listobject(v)) {
666 err_badcall();
667 return -1;
668 }
669 v = listsort((listobject *)v, (object *)NULL);
670 if (v == NULL)
671 return -1;
672 DECREF(v);
673 return 0;
674}
675
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000676object *
677listtuple(v)
678 object *v;
679{
680 object *w;
681 object **p;
682 int n;
683 if (v == NULL || !is_listobject(v)) {
684 err_badcall();
685 return NULL;
686 }
687 n = ((listobject *)v)->ob_size;
688 w = newtupleobject(n);
689 if (w == NULL)
690 return NULL;
691 p = ((tupleobject *)w)->ob_item;
692 memcpy((ANY *)p,
693 (ANY *)((listobject *)v)->ob_item,
694 n*sizeof(object *));
695 while (--n >= 0) {
696 INCREF(*p);
697 p++;
698 }
699 return w;
700}
701
Guido van Rossumed98d481991-03-06 13:07:53 +0000702static object *
703listindex(self, args)
704 listobject *self;
705 object *args;
706{
707 int i;
708
709 if (args == NULL) {
710 err_badarg();
711 return NULL;
712 }
713 for (i = 0; i < self->ob_size; i++) {
714 if (cmpobject(self->ob_item[i], args) == 0)
Guido van Rossum7066dd71992-09-17 17:54:56 +0000715 return newintobject((long)i);
Guido van Rossumed98d481991-03-06 13:07:53 +0000716 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000717 err_setstr(ValueError, "list.index(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000718 return NULL;
719}
720
721static object *
Guido van Rossume6f7d181991-10-20 20:20:40 +0000722listcount(self, args)
723 listobject *self;
724 object *args;
725{
726 int count = 0;
727 int i;
728
729 if (args == NULL) {
730 err_badarg();
731 return NULL;
732 }
733 for (i = 0; i < self->ob_size; i++) {
734 if (cmpobject(self->ob_item[i], args) == 0)
735 count++;
736 }
737 return newintobject((long)count);
738}
739
740static object *
Guido van Rossumed98d481991-03-06 13:07:53 +0000741listremove(self, args)
742 listobject *self;
743 object *args;
744{
745 int i;
746
747 if (args == NULL) {
748 err_badarg();
749 return NULL;
750 }
751 for (i = 0; i < self->ob_size; i++) {
752 if (cmpobject(self->ob_item[i], args) == 0) {
753 if (list_ass_slice(self, i, i+1, (object *)NULL) != 0)
754 return NULL;
755 INCREF(None);
756 return None;
757 }
758
759 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000760 err_setstr(ValueError, "list.remove(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000761 return NULL;
762}
763
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000764static struct methodlist list_methods[] = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000765 {"append", (method)listappend},
766 {"count", (method)listcount},
767 {"index", (method)listindex},
768 {"insert", (method)listinsert},
Guido van Rossum295d1711995-02-19 15:55:19 +0000769 {"sort", (method)listsort, 0},
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000770 {"remove", (method)listremove},
771 {"reverse", (method)listreverse},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000772 {NULL, NULL} /* sentinel */
773};
774
775static object *
776list_getattr(f, name)
777 listobject *f;
778 char *name;
779{
780 return findmethod(list_methods, (object *)f, name);
781}
782
783static sequence_methods list_as_sequence = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000784 (inquiry)list_length, /*sq_length*/
785 (binaryfunc)list_concat, /*sq_concat*/
786 (intargfunc)list_repeat, /*sq_repeat*/
787 (intargfunc)list_item, /*sq_item*/
788 (intintargfunc)list_slice, /*sq_slice*/
789 (intobjargproc)list_ass_item, /*sq_ass_item*/
790 (intintobjargproc)list_ass_slice, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000791};
792
793typeobject Listtype = {
794 OB_HEAD_INIT(&Typetype)
795 0,
796 "list",
797 sizeof(listobject),
798 0,
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000799 (destructor)list_dealloc, /*tp_dealloc*/
800 (printfunc)list_print, /*tp_print*/
801 (getattrfunc)list_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000802 0, /*tp_setattr*/
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000803 (cmpfunc)list_compare, /*tp_compare*/
804 (reprfunc)list_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805 0, /*tp_as_number*/
806 &list_as_sequence, /*tp_as_sequence*/
807 0, /*tp_as_mapping*/
808};