blob: a985aa33ce4d56851bfcff60996b1bbaebe7dc7d [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 Rossum3f236de1996-12-10 23:55:39 +0000553#define NEWSORT
554
555#ifdef NEWSORT
556
557/* New quicksort implementation for arrays of object pointers.
558 Thanks to discussions with Tim Peters. */
559
560/* CMPERROR is returned by our comparison function when an error
561 occurred. This is the largest negative integer (0x80000000 on a
562 32-bit system). */
563#define CMPERROR (1 << (8*sizeof(int) - 1))
564
565/* Comparison function. Takes care of calling a user-supplied
566 comparison function (any callable Python object). Calls the
567 standard comparison function, cmpobject(), if the user-supplied
568 function is NULL. */
569
570static int
571docompare(x, y, compare)
572 object *x;
573 object *y;
574 object *compare;
575{
576 object *args, *res;
577 int i;
578
579 if (compare == NULL)
580 return cmpobject(x, y);
581
582 args = mkvalue("(OO)", x, y);
583 if (args == NULL)
584 return CMPERROR;
585 res = call_object(compare, args);
586 DECREF(args);
587 if (res == NULL)
588 return CMPERROR;
589 if (!is_intobject(res)) {
590 DECREF(res);
591 err_setstr(TypeError, "comparison function should return int");
592 return CMPERROR;
593 }
594 i = getintvalue(res);
595 DECREF(res);
596 if (i < 0)
597 return -1;
598 if (i > 0)
599 return 1;
600 return 0;
601}
602
603/* Straight insertion sort. More efficient for sorting small arrays. */
604
605static int
606insertionsort(array, size, compare)
607 object **array; /* Start of array to sort */
608 int size; /* Number of elements to sort */
609 object *compare;/* Comparison function object, or NULL for default */
610{
611 register object **a = array;
Guido van Rossum3176bb11996-12-11 23:57:39 +0000612 register object **end = array+size;
613 register object **p;
Guido van Rossum3f236de1996-12-10 23:55:39 +0000614
Guido van Rossum3176bb11996-12-11 23:57:39 +0000615 for (p = a+1; p < end; p++) {
616 register object *key = *p;
617 register object **q = p;
618 while (--q >= a) {
619 register int k = docompare(*q, key, compare);
Guido van Rossum3f236de1996-12-10 23:55:39 +0000620 if (k == CMPERROR)
621 return -1;
622 if (k <= 0)
623 break;
Guido van Rossum3176bb11996-12-11 23:57:39 +0000624 *(q+1) = *q;
625 *q = key; /* For consistency */
Guido van Rossum3f236de1996-12-10 23:55:39 +0000626 }
627 }
628
629 return 0;
630}
631
632/* MINSIZE is the smallest array we care to partition; smaller arrays
Guido van Rossum3176bb11996-12-11 23:57:39 +0000633 are sorted using a straight insertion sort (above). You may want
634 to play with this to tune it for your system. It must be at least
635 2; more than 20 probably doesn't make sense. */
Guido van Rossum3f236de1996-12-10 23:55:39 +0000636#define MINSIZE 10
637
638/* STACKSIZE is the size of our work stack. A rough estimate is that
639 this allows us to sort arrays of MINSIZE * 2**STACKSIZE, or large
640 enough. (Because of the way we push the biggest partition first,
641 the worst case occurs when all subarrays are always partitioned
642 exactly in two.) */
643#define STACKSIZE 64
644
645/* Quicksort algorithm. Return -1 if an exception occurred; in this
646 case we leave the array partly sorted but otherwise in good health
647 (i.e. no items have been removed or duplicated). */
648
649static int
650quicksort(array, size, compare)
651 object **array; /* Start of array to sort */
652 int size; /* Number of elements to sort */
653 object *compare;/* Comparison function object, or NULL for default */
654{
Guido van Rossum3176bb11996-12-11 23:57:39 +0000655 register object *tmp, *pivot;
656 register object **lo, **hi, **l, **r;
657 int top, k, n, n2;
658 object **lostack[STACKSIZE];
659 object **histack[STACKSIZE];
Guido van Rossum3f236de1996-12-10 23:55:39 +0000660
661 /* Start out with the whole array on the work stack */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000662 lostack[0] = array;
663 histack[0] = array+size;
Guido van Rossum3f236de1996-12-10 23:55:39 +0000664 top = 1;
665
666 /* Repeat until the work stack is empty */
667 while (--top >= 0) {
Guido van Rossum3176bb11996-12-11 23:57:39 +0000668 lo = lostack[top];
669 hi = histack[top];
Guido van Rossum3f236de1996-12-10 23:55:39 +0000670
671 /* If it's a small one, use straight insertion sort */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000672 n = hi - lo;
Guido van Rossum3f236de1996-12-10 23:55:39 +0000673 if (n < MINSIZE) {
Guido van Rossum3176bb11996-12-11 23:57:39 +0000674 if (insertionsort(lo, n, compare) < 0)
Guido van Rossum3f236de1996-12-10 23:55:39 +0000675 return -1;
676 continue;
677 }
678
Guido van Rossum3176bb11996-12-11 23:57:39 +0000679 /* Choose median of first, middle and last item as pivot */
680
681 l = lo + (n>>1); /* Middle */
682 r = hi - 1; /* Last */
683 k = docompare(*lo, *l, compare);
Guido van Rossum3f236de1996-12-10 23:55:39 +0000684 if (k == CMPERROR)
685 return -1;
686 if (k < 0)
Guido van Rossum3176bb11996-12-11 23:57:39 +0000687 { tmp = *lo; *lo = *l; *l = tmp; }
688 k = docompare(*r, *l, compare);
Guido van Rossum3f236de1996-12-10 23:55:39 +0000689 if (k == CMPERROR)
690 return -1;
691 if (k < 0)
Guido van Rossum3176bb11996-12-11 23:57:39 +0000692 { tmp = *r; *r = *l; *l = tmp; }
693 k = docompare(*r, *lo, compare);
Guido van Rossum3f236de1996-12-10 23:55:39 +0000694 if (k == CMPERROR)
695 return -1;
696 if (k < 0)
Guido van Rossum3176bb11996-12-11 23:57:39 +0000697 { tmp = *r; *r = *lo; *lo = tmp; }
698 pivot = *lo;
Guido van Rossum3f236de1996-12-10 23:55:39 +0000699
700 /* Partition the array */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000701 l = lo;
702 r = hi;
Guido van Rossum3f236de1996-12-10 23:55:39 +0000703 for (;;) {
704 /* Move left index to element > pivot */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000705 while (++l < hi) {
706 k = docompare(*l, pivot, compare);
Guido van Rossum3f236de1996-12-10 23:55:39 +0000707 if (k == CMPERROR)
708 return -1;
709 if (k > 0)
710 break;
711 }
712 /* Move right index to element < pivot */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000713 while (--r > lo) {
714 k = docompare(*r, pivot, compare);
Guido van Rossum3f236de1996-12-10 23:55:39 +0000715 if (k == CMPERROR)
716 return -1;
717 if (k < 0)
718 break;
719 }
720 /* If they met, we're through */
721 if (r < l)
722 break;
723 /* Swap elements and continue */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000724 { tmp = *l; *l = *r; *r = tmp; }
Guido van Rossum3f236de1996-12-10 23:55:39 +0000725 }
726
727 /* Move the pivot into the middle */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000728 { tmp = *lo; *lo = *r; *r = tmp; }
Guido van Rossum3f236de1996-12-10 23:55:39 +0000729
730 /* We have now reached the following conditions:
Guido van Rossum3176bb11996-12-11 23:57:39 +0000731 lo <= r < l <= hi
732 all x in [lo,r) are <= pivot
733 all x in [r,l) are == pivot
734 all x in [l,hi) are >= pivot
735 The partitions are [lo,r) and [l,hi)
Guido van Rossum3f236de1996-12-10 23:55:39 +0000736 */
737
738 /* Push biggest partition first */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000739 n = r - lo;
740 n2 = hi - l;
741 if (n > n2) {
Guido van Rossum3f236de1996-12-10 23:55:39 +0000742 /* First one is bigger */
Guido van Rossum3176bb11996-12-11 23:57:39 +0000743 if (n > 1) {
744 lostack[top] = lo;
745 histack[top++] = r;
Guido van Rossum3f236de1996-12-10 23:55:39 +0000746 if (n2 > 1) {
Guido van Rossum3176bb11996-12-11 23:57:39 +0000747 lostack[top] = l;
748 histack[top++] = hi;
Guido van Rossum3f236de1996-12-10 23:55:39 +0000749 }
750 }
751 } else {
752 /* Second one is bigger */
753 if (n2 > 1) {
Guido van Rossum3176bb11996-12-11 23:57:39 +0000754 lostack[top] = l;
755 histack[top++] = hi;
756 if (n > 1) {
757 lostack[top] = lo;
758 histack[top++] = r;
Guido van Rossum3f236de1996-12-10 23:55:39 +0000759 }
760 }
761 }
762
763 /* Should assert top < STACKSIZE-1 */
764 }
765
766 /* Succes */
767 return 0;
768}
769
770static object *
771listsort(self, compare)
772 listobject *self;
773 object *compare;
774{
775 /* XXX Don't you *dare* changing the list's length in compare()! */
776 if (quicksort(self->ob_item, self->ob_size, compare) < 0)
777 return NULL;
778 INCREF(None);
779 return None;
780}
781
782#else /* !NEWSORT */
783
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000784static object *comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000785
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786static int
787cmp(v, w)
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000788 const ANY *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000789{
Guido van Rossume10a19e1992-08-03 19:05:37 +0000790 object *t, *res;
791 long i;
792
793 if (err_occurred())
794 return 0;
795
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000796 if (comparefunc == NULL)
Guido van Rossume10a19e1992-08-03 19:05:37 +0000797 return cmpobject(* (object **) v, * (object **) w);
798
799 /* Call the user-supplied comparison function */
Guido van Rossum1311e3c1995-07-12 02:22:06 +0000800 t = mkvalue("(OO)", * (object **) v, * (object **) w);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000801 if (t == NULL)
802 return 0;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000803 res = call_object(comparefunc, t);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000804 DECREF(t);
805 if (res == NULL)
806 return 0;
807 if (!is_intobject(res)) {
808 err_setstr(TypeError, "comparison function should return int");
809 i = 0;
810 }
811 else {
812 i = getintvalue(res);
813 if (i < 0)
814 i = -1;
815 else if (i > 0)
816 i = 1;
817 }
818 DECREF(res);
819 return (int) i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000820}
821
822static object *
823listsort(self, args)
824 listobject *self;
825 object *args;
826{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000827 object *save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000828 if (self->ob_size <= 1) {
829 INCREF(None);
830 return None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000831 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000832 save_comparefunc = comparefunc;
833 comparefunc = args;
834 if (comparefunc != NULL) {
Guido van Rossume10a19e1992-08-03 19:05:37 +0000835 /* Test the comparison function for obvious errors */
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000836 (void) cmp((ANY *)&self->ob_item[0], (ANY *)&self->ob_item[1]);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000837 if (err_occurred()) {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000838 comparefunc = save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000839 return NULL;
840 }
841 }
842 qsort((char *)self->ob_item,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000843 (int) self->ob_size, sizeof(object *), cmp);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000844 comparefunc = save_comparefunc;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000845 if (err_occurred())
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846 return NULL;
847 INCREF(None);
848 return None;
849}
850
Guido van Rossum3f236de1996-12-10 23:55:39 +0000851#endif
852
Guido van Rossumed98d481991-03-06 13:07:53 +0000853static object *
854listreverse(self, args)
855 listobject *self;
856 object *args;
857{
858 register object **p, **q;
859 register object *tmp;
860
861 if (args != NULL) {
862 err_badarg();
863 return NULL;
864 }
865
866 if (self->ob_size > 1) {
867 for (p = self->ob_item, q = self->ob_item + self->ob_size - 1;
868 p < q; p++, q--) {
869 tmp = *p;
870 *p = *q;
871 *q = tmp;
872 }
873 }
874
875 INCREF(None);
876 return None;
877}
878
Guido van Rossum84c76f51990-10-30 13:32:20 +0000879int
Guido van Rossumb0fe3a91995-01-17 16:34:45 +0000880reverselist(v)
881 object *v;
882{
883 if (v == NULL || !is_listobject(v)) {
884 err_badcall();
885 return -1;
886 }
887 v = listreverse((listobject *)v, (object *)NULL);
888 if (v == NULL)
889 return -1;
890 DECREF(v);
891 return 0;
892}
893
894int
Guido van Rossum84c76f51990-10-30 13:32:20 +0000895sortlist(v)
896 object *v;
897{
898 if (v == NULL || !is_listobject(v)) {
899 err_badcall();
900 return -1;
901 }
902 v = listsort((listobject *)v, (object *)NULL);
903 if (v == NULL)
904 return -1;
905 DECREF(v);
906 return 0;
907}
908
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000909object *
910listtuple(v)
911 object *v;
912{
913 object *w;
914 object **p;
915 int n;
916 if (v == NULL || !is_listobject(v)) {
917 err_badcall();
918 return NULL;
919 }
920 n = ((listobject *)v)->ob_size;
921 w = newtupleobject(n);
922 if (w == NULL)
923 return NULL;
924 p = ((tupleobject *)w)->ob_item;
925 memcpy((ANY *)p,
926 (ANY *)((listobject *)v)->ob_item,
927 n*sizeof(object *));
928 while (--n >= 0) {
929 INCREF(*p);
930 p++;
931 }
932 return w;
933}
934
Guido van Rossumed98d481991-03-06 13:07:53 +0000935static object *
936listindex(self, args)
937 listobject *self;
938 object *args;
939{
940 int i;
941
942 if (args == NULL) {
943 err_badarg();
944 return NULL;
945 }
946 for (i = 0; i < self->ob_size; i++) {
947 if (cmpobject(self->ob_item[i], args) == 0)
Guido van Rossum7066dd71992-09-17 17:54:56 +0000948 return newintobject((long)i);
Guido van Rossumed98d481991-03-06 13:07:53 +0000949 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000950 err_setstr(ValueError, "list.index(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000951 return NULL;
952}
953
954static object *
Guido van Rossume6f7d181991-10-20 20:20:40 +0000955listcount(self, args)
956 listobject *self;
957 object *args;
958{
959 int count = 0;
960 int i;
961
962 if (args == NULL) {
963 err_badarg();
964 return NULL;
965 }
966 for (i = 0; i < self->ob_size; i++) {
967 if (cmpobject(self->ob_item[i], args) == 0)
968 count++;
969 }
970 return newintobject((long)count);
971}
972
973static object *
Guido van Rossumed98d481991-03-06 13:07:53 +0000974listremove(self, args)
975 listobject *self;
976 object *args;
977{
978 int i;
979
980 if (args == NULL) {
981 err_badarg();
982 return NULL;
983 }
984 for (i = 0; i < self->ob_size; i++) {
985 if (cmpobject(self->ob_item[i], args) == 0) {
986 if (list_ass_slice(self, i, i+1, (object *)NULL) != 0)
987 return NULL;
988 INCREF(None);
989 return None;
990 }
991
992 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000993 err_setstr(ValueError, "list.remove(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000994 return NULL;
995}
996
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000997static struct methodlist list_methods[] = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000998 {"append", (method)listappend},
999 {"count", (method)listcount},
1000 {"index", (method)listindex},
1001 {"insert", (method)listinsert},
Guido van Rossum295d1711995-02-19 15:55:19 +00001002 {"sort", (method)listsort, 0},
Guido van Rossum6cd2fe01994-08-29 12:45:32 +00001003 {"remove", (method)listremove},
1004 {"reverse", (method)listreverse},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001005 {NULL, NULL} /* sentinel */
1006};
1007
1008static object *
1009list_getattr(f, name)
1010 listobject *f;
1011 char *name;
1012{
1013 return findmethod(list_methods, (object *)f, name);
1014}
1015
1016static sequence_methods list_as_sequence = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +00001017 (inquiry)list_length, /*sq_length*/
1018 (binaryfunc)list_concat, /*sq_concat*/
1019 (intargfunc)list_repeat, /*sq_repeat*/
1020 (intargfunc)list_item, /*sq_item*/
1021 (intintargfunc)list_slice, /*sq_slice*/
1022 (intobjargproc)list_ass_item, /*sq_ass_item*/
1023 (intintobjargproc)list_ass_slice, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001024};
1025
1026typeobject Listtype = {
1027 OB_HEAD_INIT(&Typetype)
1028 0,
1029 "list",
1030 sizeof(listobject),
1031 0,
Guido van Rossum6cd2fe01994-08-29 12:45:32 +00001032 (destructor)list_dealloc, /*tp_dealloc*/
1033 (printfunc)list_print, /*tp_print*/
1034 (getattrfunc)list_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001035 0, /*tp_setattr*/
Guido van Rossum6cd2fe01994-08-29 12:45:32 +00001036 (cmpfunc)list_compare, /*tp_compare*/
1037 (reprfunc)list_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001038 0, /*tp_as_number*/
1039 &list_as_sequence, /*tp_as_sequence*/
1040 0, /*tp_as_mapping*/
1041};