blob: f0eab0bb3bdc6e03b53a3efb7935e6bb1c594131 [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
100object *
101getlistitem(op, i)
102 object *op;
103 int i;
104{
105 if (!is_listobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000106 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 return NULL;
108 }
109 if (i < 0 || i >= ((listobject *)op) -> ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000110 err_setstr(IndexError, "list index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 return NULL;
112 }
113 return ((listobject *)op) -> ob_item[i];
114}
115
116int
117setlistitem(op, i, newitem)
118 register object *op;
119 register int i;
120 register object *newitem;
121{
122 register object *olditem;
123 if (!is_listobject(op)) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000124 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000125 err_badcall();
126 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 }
128 if (i < 0 || i >= ((listobject *)op) -> ob_size) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000129 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000130 err_setstr(IndexError, "list assignment index out of range");
131 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000132 }
133 olditem = ((listobject *)op) -> ob_item[i];
134 ((listobject *)op) -> ob_item[i] = newitem;
Guido van Rossume6f7d181991-10-20 20:20:40 +0000135 XDECREF(olditem);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 return 0;
137}
138
139static int
140ins1(self, where, v)
141 listobject *self;
142 int where;
143 object *v;
144{
145 int i;
146 object **items;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000147 if (v == NULL) {
148 err_badcall();
149 return -1;
150 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 items = self->ob_item;
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000152 NRESIZE(items, object *, self->ob_size+1);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000153 if (items == NULL) {
154 err_nomem();
155 return -1;
156 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 if (where < 0)
158 where = 0;
159 if (where > self->ob_size)
160 where = self->ob_size;
161 for (i = self->ob_size; --i >= where; )
162 items[i+1] = items[i];
163 INCREF(v);
164 items[where] = v;
165 self->ob_item = items;
166 self->ob_size++;
167 return 0;
168}
169
170int
171inslistitem(op, where, newitem)
172 object *op;
173 int where;
174 object *newitem;
175{
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000176 if (!is_listobject(op)) {
177 err_badcall();
178 return -1;
179 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 return ins1((listobject *)op, where, newitem);
181}
182
183int
184addlistitem(op, newitem)
185 object *op;
186 object *newitem;
187{
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000188 if (!is_listobject(op)) {
189 err_badcall();
190 return -1;
191 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 return ins1((listobject *)op,
193 (int) ((listobject *)op)->ob_size, newitem);
194}
195
196/* Methods */
197
198static void
199list_dealloc(op)
200 listobject *op;
201{
202 int i;
Jack Jansen7874d1f1995-01-19 12:09:27 +0000203 if (op->ob_item != NULL) {
204 for (i = 0; i < op->ob_size; i++) {
205 XDECREF(op->ob_item[i]);
206 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000207 free((ANY *)op->ob_item);
Jack Jansen7874d1f1995-01-19 12:09:27 +0000208 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209 free((ANY *)op);
210}
211
Guido van Rossum90933611991-06-07 16:10:43 +0000212static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213list_print(op, fp, flags)
214 listobject *op;
215 FILE *fp;
216 int flags;
217{
218 int i;
219 fprintf(fp, "[");
Guido van Rossum90933611991-06-07 16:10:43 +0000220 for (i = 0; i < op->ob_size; i++) {
221 if (i > 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 fprintf(fp, ", ");
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000223 if (printobject(op->ob_item[i], fp, 0) != 0)
Guido van Rossum90933611991-06-07 16:10:43 +0000224 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225 }
226 fprintf(fp, "]");
Guido van Rossum90933611991-06-07 16:10:43 +0000227 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228}
229
Guido van Rossum234f9421993-06-17 12:35:49 +0000230static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231list_repr(v)
232 listobject *v;
233{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000234 object *s, *comma;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 int i;
236 s = newstringobject("[");
237 comma = newstringobject(", ");
238 for (i = 0; i < v->ob_size && s != NULL; i++) {
239 if (i > 0)
240 joinstring(&s, comma);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000241 joinstring_decref(&s, reprobject(v->ob_item[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000243 XDECREF(comma);
244 joinstring_decref(&s, newstringobject("]"));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245 return s;
246}
247
248static int
249list_compare(v, w)
250 listobject *v, *w;
251{
252 int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
253 int i;
254 for (i = 0; i < len; i++) {
255 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
256 if (cmp != 0)
257 return cmp;
258 }
259 return v->ob_size - w->ob_size;
260}
261
262static int
263list_length(a)
264 listobject *a;
265{
266 return a->ob_size;
267}
268
269static object *
270list_item(a, i)
271 listobject *a;
272 int i;
273{
274 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000275 err_setstr(IndexError, "list index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276 return NULL;
277 }
278 INCREF(a->ob_item[i]);
279 return a->ob_item[i];
280}
281
282static object *
283list_slice(a, ilow, ihigh)
284 listobject *a;
285 int ilow, ihigh;
286{
287 listobject *np;
288 int i;
289 if (ilow < 0)
290 ilow = 0;
291 else if (ilow > a->ob_size)
292 ilow = a->ob_size;
293 if (ihigh < 0)
294 ihigh = 0;
295 if (ihigh < ilow)
296 ihigh = ilow;
297 else if (ihigh > a->ob_size)
298 ihigh = a->ob_size;
299 np = (listobject *) newlistobject(ihigh - ilow);
300 if (np == NULL)
301 return NULL;
302 for (i = ilow; i < ihigh; i++) {
303 object *v = a->ob_item[i];
304 INCREF(v);
305 np->ob_item[i - ilow] = v;
306 }
307 return (object *)np;
308}
309
Guido van Rossum234f9421993-06-17 12:35:49 +0000310object *
311getlistslice(a, ilow, ihigh)
312 object *a;
313 int ilow, ihigh;
314{
315 if (!is_listobject(a)) {
316 err_badcall();
317 return NULL;
318 }
319 return list_slice((listobject *)a, ilow, ihigh);
320}
321
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322static object *
323list_concat(a, bb)
324 listobject *a;
325 object *bb;
326{
327 int size;
328 int i;
329 listobject *np;
330 if (!is_listobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000331 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332 return NULL;
333 }
334#define b ((listobject *)bb)
335 size = a->ob_size + b->ob_size;
336 np = (listobject *) newlistobject(size);
337 if (np == NULL) {
Guido van Rossum90933611991-06-07 16:10:43 +0000338 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339 }
340 for (i = 0; i < a->ob_size; i++) {
341 object *v = a->ob_item[i];
342 INCREF(v);
343 np->ob_item[i] = v;
344 }
345 for (i = 0; i < b->ob_size; i++) {
346 object *v = b->ob_item[i];
347 INCREF(v);
348 np->ob_item[i + a->ob_size] = v;
349 }
350 return (object *)np;
351#undef b
352}
353
Guido van Rossumed98d481991-03-06 13:07:53 +0000354static object *
355list_repeat(a, n)
356 listobject *a;
357 int n;
358{
359 int i, j;
360 int size;
361 listobject *np;
362 object **p;
363 if (n < 0)
364 n = 0;
365 size = a->ob_size * n;
366 np = (listobject *) newlistobject(size);
367 if (np == NULL)
368 return NULL;
369 p = np->ob_item;
370 for (i = 0; i < n; i++) {
371 for (j = 0; j < a->ob_size; j++) {
372 *p = a->ob_item[j];
373 INCREF(*p);
374 p++;
375 }
376 }
377 return (object *) np;
378}
379
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000380static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381list_ass_slice(a, ilow, ihigh, v)
382 listobject *a;
383 int ilow, ihigh;
384 object *v;
385{
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000386 /* Because [X]DECREF can recursively invoke list operations on
387 this list, we must postpone all [X]DECREF activity until
388 after the list is back in its canonical shape. Therefore
389 we must allocate an additional array, 'recycle', into which
390 we temporarily copy the items that are deleted from the
391 list. :-( */
392 object **recycle, **p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 object **item;
394 int n; /* Size of replacement list */
395 int d; /* Change in size */
396 int k; /* Loop index */
397#define b ((listobject *)v)
398 if (v == NULL)
399 n = 0;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000400 else if (is_listobject(v)) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 n = b->ob_size;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000402 if (a == b) {
403 /* Special case "a[i:j] = a" -- copy b first */
404 int ret;
405 v = list_slice(b, 0, n);
406 ret = list_ass_slice(a, ilow, ihigh, v);
407 DECREF(v);
408 return ret;
409 }
410 }
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000411 else {
412 err_badarg();
413 return -1;
414 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000415 if (ilow < 0)
416 ilow = 0;
417 else if (ilow > a->ob_size)
418 ilow = a->ob_size;
419 if (ihigh < 0)
420 ihigh = 0;
421 if (ihigh < ilow)
422 ihigh = ilow;
423 else if (ihigh > a->ob_size)
424 ihigh = a->ob_size;
425 item = a->ob_item;
426 d = n - (ihigh-ilow);
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000427 if (ihigh > ilow)
428 p = recycle = NEW(object *, (ihigh-ilow));
429 else
430 p = recycle = NULL;
431 if (d <= 0) { /* Delete -d items; recycle ihigh-ilow items */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000432 for (k = ilow; k < ihigh; k++)
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000433 *p++ = item[k];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000434 if (d < 0) {
435 for (/*k = ihigh*/; k < a->ob_size; k++)
436 item[k+d] = item[k];
437 a->ob_size += d;
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000438 NRESIZE(item, object *, a->ob_size); /* Can't fail */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000439 a->ob_item = item;
440 }
441 }
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000442 else { /* Insert d items; recycle ihigh-ilow items */
Guido van Rossuma46d51d1995-01-26 22:59:43 +0000443 NRESIZE(item, object *, a->ob_size + d);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000444 if (item == NULL) {
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000445 XDEL(recycle);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000446 err_nomem();
447 return -1;
448 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449 for (k = a->ob_size; --k >= ihigh; )
450 item[k+d] = item[k];
451 for (/*k = ihigh-1*/; k >= ilow; --k)
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000452 *p++ = item[k];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453 a->ob_item = item;
454 a->ob_size += d;
455 }
456 for (k = 0; k < n; k++, ilow++) {
457 object *w = b->ob_item[k];
Guido van Rossumdc4b93d1993-10-27 14:56:44 +0000458 XINCREF(w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459 item[ilow] = w;
460 }
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000461 if (recycle) {
462 while (--p >= recycle)
463 XDECREF(*p);
464 DEL(recycle);
465 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466 return 0;
467#undef b
468}
469
Guido van Rossum234f9421993-06-17 12:35:49 +0000470int
471setlistslice(a, ilow, ihigh, v)
472 object *a;
473 int ilow, ihigh;
474 object *v;
475{
476 if (!is_listobject(a)) {
477 err_badcall();
Guido van Rossum1fc238a1993-07-29 08:25:09 +0000478 return -1;
Guido van Rossum234f9421993-06-17 12:35:49 +0000479 }
480 return list_ass_slice((listobject *)a, ilow, ihigh, v);
481}
482
Guido van Rossum4a450d01991-04-03 19:05:18 +0000483static int
484list_ass_item(a, i, v)
485 listobject *a;
486 int i;
487 object *v;
488{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000489 object *old_value;
Guido van Rossum4a450d01991-04-03 19:05:18 +0000490 if (i < 0 || i >= a->ob_size) {
491 err_setstr(IndexError, "list assignment index out of range");
492 return -1;
493 }
494 if (v == NULL)
495 return list_ass_slice(a, i, i+1, v);
496 INCREF(v);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000497 old_value = a->ob_item[i];
Guido van Rossum4a450d01991-04-03 19:05:18 +0000498 a->ob_item[i] = v;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000499 DECREF(old_value);
Guido van Rossum4a450d01991-04-03 19:05:18 +0000500 return 0;
501}
502
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000503static object *
504ins(self, where, v)
505 listobject *self;
506 int where;
507 object *v;
508{
509 if (ins1(self, where, v) != 0)
510 return NULL;
511 INCREF(None);
512 return None;
513}
514
515static object *
516listinsert(self, args)
517 listobject *self;
518 object *args;
519{
520 int i;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000521 object *v;
522 if (!getargs(args, "(iO)", &i, &v))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000523 return NULL;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000524 return ins(self, i, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525}
526
527static object *
528listappend(self, args)
529 listobject *self;
530 object *args;
531{
Guido van Rossumbf80e541993-02-08 15:49:17 +0000532 object *v;
533 if (!getargs(args, "O", &v))
534 return NULL;
535 return ins(self, (int) self->ob_size, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536}
537
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000538static object *comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000539
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000540static int
541cmp(v, w)
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000542 const ANY *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000543{
Guido van Rossume10a19e1992-08-03 19:05:37 +0000544 object *t, *res;
545 long i;
546
547 if (err_occurred())
548 return 0;
549
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000550 if (comparefunc == NULL)
Guido van Rossume10a19e1992-08-03 19:05:37 +0000551 return cmpobject(* (object **) v, * (object **) w);
552
553 /* Call the user-supplied comparison function */
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000554 t = mkvalue("OO", * (object **) v, * (object **) w);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000555 if (t == NULL)
556 return 0;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000557 res = call_object(comparefunc, t);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000558 DECREF(t);
559 if (res == NULL)
560 return 0;
561 if (!is_intobject(res)) {
562 err_setstr(TypeError, "comparison function should return int");
563 i = 0;
564 }
565 else {
566 i = getintvalue(res);
567 if (i < 0)
568 i = -1;
569 else if (i > 0)
570 i = 1;
571 }
572 DECREF(res);
573 return (int) i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000574}
575
576static object *
577listsort(self, args)
578 listobject *self;
579 object *args;
580{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000581 object *save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000582 if (self->ob_size <= 1) {
583 INCREF(None);
584 return None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000585 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000586 save_comparefunc = comparefunc;
587 comparefunc = args;
588 if (comparefunc != NULL) {
Guido van Rossume10a19e1992-08-03 19:05:37 +0000589 /* Test the comparison function for obvious errors */
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000590 (void) cmp((ANY *)&self->ob_item[0], (ANY *)&self->ob_item[1]);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000591 if (err_occurred()) {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000592 comparefunc = save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000593 return NULL;
594 }
595 }
596 qsort((char *)self->ob_item,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000597 (int) self->ob_size, sizeof(object *), cmp);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000598 comparefunc = save_comparefunc;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000599 if (err_occurred())
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000600 return NULL;
601 INCREF(None);
602 return None;
603}
604
Guido van Rossumed98d481991-03-06 13:07:53 +0000605static object *
606listreverse(self, args)
607 listobject *self;
608 object *args;
609{
610 register object **p, **q;
611 register object *tmp;
612
613 if (args != NULL) {
614 err_badarg();
615 return NULL;
616 }
617
618 if (self->ob_size > 1) {
619 for (p = self->ob_item, q = self->ob_item + self->ob_size - 1;
620 p < q; p++, q--) {
621 tmp = *p;
622 *p = *q;
623 *q = tmp;
624 }
625 }
626
627 INCREF(None);
628 return None;
629}
630
Guido van Rossum84c76f51990-10-30 13:32:20 +0000631int
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000632reverselist(v)
633 object *v;
634{
635 if (v == NULL || !is_listobject(v)) {
636 err_badcall();
637 return -1;
638 }
639 v = listreverse((listobject *)v, (object *)NULL);
640 if (v == NULL)
641 return -1;
642 DECREF(v);
643 return 0;
644}
645
646int
Guido van Rossum84c76f51990-10-30 13:32:20 +0000647sortlist(v)
648 object *v;
649{
650 if (v == NULL || !is_listobject(v)) {
651 err_badcall();
652 return -1;
653 }
654 v = listsort((listobject *)v, (object *)NULL);
655 if (v == NULL)
656 return -1;
657 DECREF(v);
658 return 0;
659}
660
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000661object *
662listtuple(v)
663 object *v;
664{
665 object *w;
666 object **p;
667 int n;
668 if (v == NULL || !is_listobject(v)) {
669 err_badcall();
670 return NULL;
671 }
672 n = ((listobject *)v)->ob_size;
673 w = newtupleobject(n);
674 if (w == NULL)
675 return NULL;
676 p = ((tupleobject *)w)->ob_item;
677 memcpy((ANY *)p,
678 (ANY *)((listobject *)v)->ob_item,
679 n*sizeof(object *));
680 while (--n >= 0) {
681 INCREF(*p);
682 p++;
683 }
684 return w;
685}
686
Guido van Rossumed98d481991-03-06 13:07:53 +0000687static object *
688listindex(self, args)
689 listobject *self;
690 object *args;
691{
692 int i;
693
694 if (args == NULL) {
695 err_badarg();
696 return NULL;
697 }
698 for (i = 0; i < self->ob_size; i++) {
699 if (cmpobject(self->ob_item[i], args) == 0)
Guido van Rossum7066dd71992-09-17 17:54:56 +0000700 return newintobject((long)i);
Guido van Rossumed98d481991-03-06 13:07:53 +0000701 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000702 err_setstr(ValueError, "list.index(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000703 return NULL;
704}
705
706static object *
Guido van Rossume6f7d181991-10-20 20:20:40 +0000707listcount(self, args)
708 listobject *self;
709 object *args;
710{
711 int count = 0;
712 int i;
713
714 if (args == NULL) {
715 err_badarg();
716 return NULL;
717 }
718 for (i = 0; i < self->ob_size; i++) {
719 if (cmpobject(self->ob_item[i], args) == 0)
720 count++;
721 }
722 return newintobject((long)count);
723}
724
725static object *
Guido van Rossumed98d481991-03-06 13:07:53 +0000726listremove(self, args)
727 listobject *self;
728 object *args;
729{
730 int i;
731
732 if (args == NULL) {
733 err_badarg();
734 return NULL;
735 }
736 for (i = 0; i < self->ob_size; i++) {
737 if (cmpobject(self->ob_item[i], args) == 0) {
738 if (list_ass_slice(self, i, i+1, (object *)NULL) != 0)
739 return NULL;
740 INCREF(None);
741 return None;
742 }
743
744 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000745 err_setstr(ValueError, "list.remove(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000746 return NULL;
747}
748
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000749static struct methodlist list_methods[] = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000750 {"append", (method)listappend},
751 {"count", (method)listcount},
752 {"index", (method)listindex},
753 {"insert", (method)listinsert},
754 {"sort", (method)listsort},
755 {"remove", (method)listremove},
756 {"reverse", (method)listreverse},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000757 {NULL, NULL} /* sentinel */
758};
759
760static object *
761list_getattr(f, name)
762 listobject *f;
763 char *name;
764{
765 return findmethod(list_methods, (object *)f, name);
766}
767
768static sequence_methods list_as_sequence = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000769 (inquiry)list_length, /*sq_length*/
770 (binaryfunc)list_concat, /*sq_concat*/
771 (intargfunc)list_repeat, /*sq_repeat*/
772 (intargfunc)list_item, /*sq_item*/
773 (intintargfunc)list_slice, /*sq_slice*/
774 (intobjargproc)list_ass_item, /*sq_ass_item*/
775 (intintobjargproc)list_ass_slice, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776};
777
778typeobject Listtype = {
779 OB_HEAD_INIT(&Typetype)
780 0,
781 "list",
782 sizeof(listobject),
783 0,
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000784 (destructor)list_dealloc, /*tp_dealloc*/
785 (printfunc)list_print, /*tp_print*/
786 (getattrfunc)list_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787 0, /*tp_setattr*/
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000788 (cmpfunc)list_compare, /*tp_compare*/
789 (reprfunc)list_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000790 0, /*tp_as_number*/
791 &list_as_sequence, /*tp_as_sequence*/
792 0, /*tp_as_mapping*/
793};