blob: ecf46457d9ef1478ff3ecf028ff2b644ff21e9dd [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
36object *
37newlistobject(size)
38 int size;
39{
40 int i;
41 listobject *op;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +000042 size_t nbytes;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043 if (size < 0) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000044 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045 return NULL;
46 }
Guido van Rossum1e28e5e1992-08-19 16:46:30 +000047 nbytes = size * sizeof(object *);
48 /* Check for overflow */
49 if (nbytes / sizeof(object *) != size) {
50 return err_nomem();
51 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052 op = (listobject *) malloc(sizeof(listobject));
53 if (op == NULL) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000054 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000055 }
56 if (size <= 0) {
57 op->ob_item = NULL;
58 }
59 else {
Guido van Rossum1e28e5e1992-08-19 16:46:30 +000060 op->ob_item = (object **) malloc(nbytes);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061 if (op->ob_item == NULL) {
62 free((ANY *)op);
Guido van Rossum2a9096b1990-10-21 22:15:08 +000063 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064 }
65 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066 op->ob_type = &Listtype;
67 op->ob_size = size;
68 for (i = 0; i < size; i++)
69 op->ob_item[i] = NULL;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000070 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071 return (object *) op;
72}
73
74int
75getlistsize(op)
76 object *op;
77{
78 if (!is_listobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000079 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 return -1;
81 }
82 else
83 return ((listobject *)op) -> ob_size;
84}
85
86object *
87getlistitem(op, i)
88 object *op;
89 int i;
90{
91 if (!is_listobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000092 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000093 return NULL;
94 }
95 if (i < 0 || i >= ((listobject *)op) -> ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000096 err_setstr(IndexError, "list index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 return NULL;
98 }
99 return ((listobject *)op) -> ob_item[i];
100}
101
102int
103setlistitem(op, i, newitem)
104 register object *op;
105 register int i;
106 register object *newitem;
107{
108 register object *olditem;
109 if (!is_listobject(op)) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000110 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000111 err_badcall();
112 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 }
114 if (i < 0 || i >= ((listobject *)op) -> ob_size) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000115 XDECREF(newitem);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000116 err_setstr(IndexError, "list assignment index out of range");
117 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 }
119 olditem = ((listobject *)op) -> ob_item[i];
120 ((listobject *)op) -> ob_item[i] = newitem;
Guido van Rossume6f7d181991-10-20 20:20:40 +0000121 XDECREF(olditem);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122 return 0;
123}
124
125static int
126ins1(self, where, v)
127 listobject *self;
128 int where;
129 object *v;
130{
131 int i;
132 object **items;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000133 if (v == NULL) {
134 err_badcall();
135 return -1;
136 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 items = self->ob_item;
138 RESIZE(items, object *, self->ob_size+1);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000139 if (items == NULL) {
140 err_nomem();
141 return -1;
142 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 if (where < 0)
144 where = 0;
145 if (where > self->ob_size)
146 where = self->ob_size;
147 for (i = self->ob_size; --i >= where; )
148 items[i+1] = items[i];
149 INCREF(v);
150 items[where] = v;
151 self->ob_item = items;
152 self->ob_size++;
153 return 0;
154}
155
156int
157inslistitem(op, where, newitem)
158 object *op;
159 int where;
160 object *newitem;
161{
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000162 if (!is_listobject(op)) {
163 err_badcall();
164 return -1;
165 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 return ins1((listobject *)op, where, newitem);
167}
168
169int
170addlistitem(op, newitem)
171 object *op;
172 object *newitem;
173{
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000174 if (!is_listobject(op)) {
175 err_badcall();
176 return -1;
177 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 return ins1((listobject *)op,
179 (int) ((listobject *)op)->ob_size, newitem);
180}
181
182/* Methods */
183
184static void
185list_dealloc(op)
186 listobject *op;
187{
188 int i;
Jack Jansen7874d1f1995-01-19 12:09:27 +0000189 if (op->ob_item != NULL) {
190 for (i = 0; i < op->ob_size; i++) {
191 XDECREF(op->ob_item[i]);
192 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 free((ANY *)op->ob_item);
Jack Jansen7874d1f1995-01-19 12:09:27 +0000194 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 free((ANY *)op);
196}
197
Guido van Rossum90933611991-06-07 16:10:43 +0000198static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000199list_print(op, fp, flags)
200 listobject *op;
201 FILE *fp;
202 int flags;
203{
204 int i;
205 fprintf(fp, "[");
Guido van Rossum90933611991-06-07 16:10:43 +0000206 for (i = 0; i < op->ob_size; i++) {
207 if (i > 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208 fprintf(fp, ", ");
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000209 if (printobject(op->ob_item[i], fp, 0) != 0)
Guido van Rossum90933611991-06-07 16:10:43 +0000210 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211 }
212 fprintf(fp, "]");
Guido van Rossum90933611991-06-07 16:10:43 +0000213 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214}
215
Guido van Rossum234f9421993-06-17 12:35:49 +0000216static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217list_repr(v)
218 listobject *v;
219{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000220 object *s, *comma;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221 int i;
222 s = newstringobject("[");
223 comma = newstringobject(", ");
224 for (i = 0; i < v->ob_size && s != NULL; i++) {
225 if (i > 0)
226 joinstring(&s, comma);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000227 joinstring_decref(&s, reprobject(v->ob_item[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000229 XDECREF(comma);
230 joinstring_decref(&s, newstringobject("]"));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 return s;
232}
233
234static int
235list_compare(v, w)
236 listobject *v, *w;
237{
238 int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
239 int i;
240 for (i = 0; i < len; i++) {
241 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
242 if (cmp != 0)
243 return cmp;
244 }
245 return v->ob_size - w->ob_size;
246}
247
248static int
249list_length(a)
250 listobject *a;
251{
252 return a->ob_size;
253}
254
255static object *
256list_item(a, i)
257 listobject *a;
258 int i;
259{
260 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000261 err_setstr(IndexError, "list index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000262 return NULL;
263 }
264 INCREF(a->ob_item[i]);
265 return a->ob_item[i];
266}
267
268static object *
269list_slice(a, ilow, ihigh)
270 listobject *a;
271 int ilow, ihigh;
272{
273 listobject *np;
274 int i;
275 if (ilow < 0)
276 ilow = 0;
277 else if (ilow > a->ob_size)
278 ilow = a->ob_size;
279 if (ihigh < 0)
280 ihigh = 0;
281 if (ihigh < ilow)
282 ihigh = ilow;
283 else if (ihigh > a->ob_size)
284 ihigh = a->ob_size;
285 np = (listobject *) newlistobject(ihigh - ilow);
286 if (np == NULL)
287 return NULL;
288 for (i = ilow; i < ihigh; i++) {
289 object *v = a->ob_item[i];
290 INCREF(v);
291 np->ob_item[i - ilow] = v;
292 }
293 return (object *)np;
294}
295
Guido van Rossum234f9421993-06-17 12:35:49 +0000296object *
297getlistslice(a, ilow, ihigh)
298 object *a;
299 int ilow, ihigh;
300{
301 if (!is_listobject(a)) {
302 err_badcall();
303 return NULL;
304 }
305 return list_slice((listobject *)a, ilow, ihigh);
306}
307
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308static object *
309list_concat(a, bb)
310 listobject *a;
311 object *bb;
312{
313 int size;
314 int i;
315 listobject *np;
316 if (!is_listobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000317 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318 return NULL;
319 }
320#define b ((listobject *)bb)
321 size = a->ob_size + b->ob_size;
322 np = (listobject *) newlistobject(size);
323 if (np == NULL) {
Guido van Rossum90933611991-06-07 16:10:43 +0000324 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 }
326 for (i = 0; i < a->ob_size; i++) {
327 object *v = a->ob_item[i];
328 INCREF(v);
329 np->ob_item[i] = v;
330 }
331 for (i = 0; i < b->ob_size; i++) {
332 object *v = b->ob_item[i];
333 INCREF(v);
334 np->ob_item[i + a->ob_size] = v;
335 }
336 return (object *)np;
337#undef b
338}
339
Guido van Rossumed98d481991-03-06 13:07:53 +0000340static object *
341list_repeat(a, n)
342 listobject *a;
343 int n;
344{
345 int i, j;
346 int size;
347 listobject *np;
348 object **p;
349 if (n < 0)
350 n = 0;
351 size = a->ob_size * n;
352 np = (listobject *) newlistobject(size);
353 if (np == NULL)
354 return NULL;
355 p = np->ob_item;
356 for (i = 0; i < n; i++) {
357 for (j = 0; j < a->ob_size; j++) {
358 *p = a->ob_item[j];
359 INCREF(*p);
360 p++;
361 }
362 }
363 return (object *) np;
364}
365
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000366static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367list_ass_slice(a, ilow, ihigh, v)
368 listobject *a;
369 int ilow, ihigh;
370 object *v;
371{
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000372 /* Because [X]DECREF can recursively invoke list operations on
373 this list, we must postpone all [X]DECREF activity until
374 after the list is back in its canonical shape. Therefore
375 we must allocate an additional array, 'recycle', into which
376 we temporarily copy the items that are deleted from the
377 list. :-( */
378 object **recycle, **p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379 object **item;
380 int n; /* Size of replacement list */
381 int d; /* Change in size */
382 int k; /* Loop index */
383#define b ((listobject *)v)
384 if (v == NULL)
385 n = 0;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000386 else if (is_listobject(v)) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387 n = b->ob_size;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000388 if (a == b) {
389 /* Special case "a[i:j] = a" -- copy b first */
390 int ret;
391 v = list_slice(b, 0, n);
392 ret = list_ass_slice(a, ilow, ihigh, v);
393 DECREF(v);
394 return ret;
395 }
396 }
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000397 else {
398 err_badarg();
399 return -1;
400 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 if (ilow < 0)
402 ilow = 0;
403 else if (ilow > a->ob_size)
404 ilow = a->ob_size;
405 if (ihigh < 0)
406 ihigh = 0;
407 if (ihigh < ilow)
408 ihigh = ilow;
409 else if (ihigh > a->ob_size)
410 ihigh = a->ob_size;
411 item = a->ob_item;
412 d = n - (ihigh-ilow);
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000413 if (ihigh > ilow)
414 p = recycle = NEW(object *, (ihigh-ilow));
415 else
416 p = recycle = NULL;
417 if (d <= 0) { /* Delete -d items; recycle ihigh-ilow items */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000418 for (k = ilow; k < ihigh; k++)
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000419 *p++ = item[k];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000420 if (d < 0) {
421 for (/*k = ihigh*/; k < a->ob_size; k++)
422 item[k+d] = item[k];
423 a->ob_size += d;
424 RESIZE(item, object *, a->ob_size); /* Can't fail */
425 a->ob_item = item;
426 }
427 }
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000428 else { /* Insert d items; recycle ihigh-ilow items */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000429 RESIZE(item, object *, a->ob_size + d);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000430 if (item == NULL) {
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000431 XDEL(recycle);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000432 err_nomem();
433 return -1;
434 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000435 for (k = a->ob_size; --k >= ihigh; )
436 item[k+d] = item[k];
437 for (/*k = ihigh-1*/; k >= ilow; --k)
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000438 *p++ = item[k];
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000439 a->ob_item = item;
440 a->ob_size += d;
441 }
442 for (k = 0; k < n; k++, ilow++) {
443 object *w = b->ob_item[k];
Guido van Rossumdc4b93d1993-10-27 14:56:44 +0000444 XINCREF(w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445 item[ilow] = w;
446 }
Guido van Rossumae7bf1a1995-01-17 10:21:11 +0000447 if (recycle) {
448 while (--p >= recycle)
449 XDECREF(*p);
450 DEL(recycle);
451 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000452 return 0;
453#undef b
454}
455
Guido van Rossum234f9421993-06-17 12:35:49 +0000456int
457setlistslice(a, ilow, ihigh, v)
458 object *a;
459 int ilow, ihigh;
460 object *v;
461{
462 if (!is_listobject(a)) {
463 err_badcall();
Guido van Rossum1fc238a1993-07-29 08:25:09 +0000464 return -1;
Guido van Rossum234f9421993-06-17 12:35:49 +0000465 }
466 return list_ass_slice((listobject *)a, ilow, ihigh, v);
467}
468
Guido van Rossum4a450d01991-04-03 19:05:18 +0000469static int
470list_ass_item(a, i, v)
471 listobject *a;
472 int i;
473 object *v;
474{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000475 object *old_value;
Guido van Rossum4a450d01991-04-03 19:05:18 +0000476 if (i < 0 || i >= a->ob_size) {
477 err_setstr(IndexError, "list assignment index out of range");
478 return -1;
479 }
480 if (v == NULL)
481 return list_ass_slice(a, i, i+1, v);
482 INCREF(v);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000483 old_value = a->ob_item[i];
Guido van Rossum4a450d01991-04-03 19:05:18 +0000484 a->ob_item[i] = v;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000485 DECREF(old_value);
Guido van Rossum4a450d01991-04-03 19:05:18 +0000486 return 0;
487}
488
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489static object *
490ins(self, where, v)
491 listobject *self;
492 int where;
493 object *v;
494{
495 if (ins1(self, where, v) != 0)
496 return NULL;
497 INCREF(None);
498 return None;
499}
500
501static object *
502listinsert(self, args)
503 listobject *self;
504 object *args;
505{
506 int i;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000507 object *v;
508 if (!getargs(args, "(iO)", &i, &v))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return NULL;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000510 return ins(self, i, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511}
512
513static object *
514listappend(self, args)
515 listobject *self;
516 object *args;
517{
Guido van Rossumbf80e541993-02-08 15:49:17 +0000518 object *v;
519 if (!getargs(args, "O", &v))
520 return NULL;
521 return ins(self, (int) self->ob_size, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522}
523
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000524static object *comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000525
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000526static int
527cmp(v, w)
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000528 const ANY *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529{
Guido van Rossume10a19e1992-08-03 19:05:37 +0000530 object *t, *res;
531 long i;
532
533 if (err_occurred())
534 return 0;
535
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000536 if (comparefunc == NULL)
Guido van Rossume10a19e1992-08-03 19:05:37 +0000537 return cmpobject(* (object **) v, * (object **) w);
538
539 /* Call the user-supplied comparison function */
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000540 t = mkvalue("OO", * (object **) v, * (object **) w);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000541 if (t == NULL)
542 return 0;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000543 res = call_object(comparefunc, t);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000544 DECREF(t);
545 if (res == NULL)
546 return 0;
547 if (!is_intobject(res)) {
548 err_setstr(TypeError, "comparison function should return int");
549 i = 0;
550 }
551 else {
552 i = getintvalue(res);
553 if (i < 0)
554 i = -1;
555 else if (i > 0)
556 i = 1;
557 }
558 DECREF(res);
559 return (int) i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000560}
561
562static object *
563listsort(self, args)
564 listobject *self;
565 object *args;
566{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000567 object *save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000568 if (self->ob_size <= 1) {
569 INCREF(None);
570 return None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000571 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000572 save_comparefunc = comparefunc;
573 comparefunc = args;
574 if (comparefunc != NULL) {
Guido van Rossume10a19e1992-08-03 19:05:37 +0000575 /* Test the comparison function for obvious errors */
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000576 (void) cmp((ANY *)&self->ob_item[0], (ANY *)&self->ob_item[1]);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000577 if (err_occurred()) {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000578 comparefunc = save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000579 return NULL;
580 }
581 }
582 qsort((char *)self->ob_item,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000583 (int) self->ob_size, sizeof(object *), cmp);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000584 comparefunc = save_comparefunc;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000585 if (err_occurred())
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000586 return NULL;
587 INCREF(None);
588 return None;
589}
590
Guido van Rossumed98d481991-03-06 13:07:53 +0000591static object *
592listreverse(self, args)
593 listobject *self;
594 object *args;
595{
596 register object **p, **q;
597 register object *tmp;
598
599 if (args != NULL) {
600 err_badarg();
601 return NULL;
602 }
603
604 if (self->ob_size > 1) {
605 for (p = self->ob_item, q = self->ob_item + self->ob_size - 1;
606 p < q; p++, q--) {
607 tmp = *p;
608 *p = *q;
609 *q = tmp;
610 }
611 }
612
613 INCREF(None);
614 return None;
615}
616
Guido van Rossum84c76f51990-10-30 13:32:20 +0000617int
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000618reverselist(v)
619 object *v;
620{
621 if (v == NULL || !is_listobject(v)) {
622 err_badcall();
623 return -1;
624 }
625 v = listreverse((listobject *)v, (object *)NULL);
626 if (v == NULL)
627 return -1;
628 DECREF(v);
629 return 0;
630}
631
632int
Guido van Rossum84c76f51990-10-30 13:32:20 +0000633sortlist(v)
634 object *v;
635{
636 if (v == NULL || !is_listobject(v)) {
637 err_badcall();
638 return -1;
639 }
640 v = listsort((listobject *)v, (object *)NULL);
641 if (v == NULL)
642 return -1;
643 DECREF(v);
644 return 0;
645}
646
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000647object *
648listtuple(v)
649 object *v;
650{
651 object *w;
652 object **p;
653 int n;
654 if (v == NULL || !is_listobject(v)) {
655 err_badcall();
656 return NULL;
657 }
658 n = ((listobject *)v)->ob_size;
659 w = newtupleobject(n);
660 if (w == NULL)
661 return NULL;
662 p = ((tupleobject *)w)->ob_item;
663 memcpy((ANY *)p,
664 (ANY *)((listobject *)v)->ob_item,
665 n*sizeof(object *));
666 while (--n >= 0) {
667 INCREF(*p);
668 p++;
669 }
670 return w;
671}
672
Guido van Rossumed98d481991-03-06 13:07:53 +0000673static object *
674listindex(self, args)
675 listobject *self;
676 object *args;
677{
678 int i;
679
680 if (args == NULL) {
681 err_badarg();
682 return NULL;
683 }
684 for (i = 0; i < self->ob_size; i++) {
685 if (cmpobject(self->ob_item[i], args) == 0)
Guido van Rossum7066dd71992-09-17 17:54:56 +0000686 return newintobject((long)i);
Guido van Rossumed98d481991-03-06 13:07:53 +0000687 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000688 err_setstr(ValueError, "list.index(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000689 return NULL;
690}
691
692static object *
Guido van Rossume6f7d181991-10-20 20:20:40 +0000693listcount(self, args)
694 listobject *self;
695 object *args;
696{
697 int count = 0;
698 int i;
699
700 if (args == NULL) {
701 err_badarg();
702 return NULL;
703 }
704 for (i = 0; i < self->ob_size; i++) {
705 if (cmpobject(self->ob_item[i], args) == 0)
706 count++;
707 }
708 return newintobject((long)count);
709}
710
711static object *
Guido van Rossumed98d481991-03-06 13:07:53 +0000712listremove(self, args)
713 listobject *self;
714 object *args;
715{
716 int i;
717
718 if (args == NULL) {
719 err_badarg();
720 return NULL;
721 }
722 for (i = 0; i < self->ob_size; i++) {
723 if (cmpobject(self->ob_item[i], args) == 0) {
724 if (list_ass_slice(self, i, i+1, (object *)NULL) != 0)
725 return NULL;
726 INCREF(None);
727 return None;
728 }
729
730 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000731 err_setstr(ValueError, "list.remove(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000732 return NULL;
733}
734
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000735static struct methodlist list_methods[] = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000736 {"append", (method)listappend},
737 {"count", (method)listcount},
738 {"index", (method)listindex},
739 {"insert", (method)listinsert},
740 {"sort", (method)listsort},
741 {"remove", (method)listremove},
742 {"reverse", (method)listreverse},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000743 {NULL, NULL} /* sentinel */
744};
745
746static object *
747list_getattr(f, name)
748 listobject *f;
749 char *name;
750{
751 return findmethod(list_methods, (object *)f, name);
752}
753
754static sequence_methods list_as_sequence = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000755 (inquiry)list_length, /*sq_length*/
756 (binaryfunc)list_concat, /*sq_concat*/
757 (intargfunc)list_repeat, /*sq_repeat*/
758 (intargfunc)list_item, /*sq_item*/
759 (intintargfunc)list_slice, /*sq_slice*/
760 (intobjargproc)list_ass_item, /*sq_ass_item*/
761 (intintobjargproc)list_ass_slice, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000762};
763
764typeobject Listtype = {
765 OB_HEAD_INIT(&Typetype)
766 0,
767 "list",
768 sizeof(listobject),
769 0,
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000770 (destructor)list_dealloc, /*tp_dealloc*/
771 (printfunc)list_print, /*tp_print*/
772 (getattrfunc)list_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773 0, /*tp_setattr*/
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000774 (cmpfunc)list_compare, /*tp_compare*/
775 (reprfunc)list_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776 0, /*tp_as_number*/
777 &list_as_sequence, /*tp_as_sequence*/
778 0, /*tp_as_mapping*/
779};