blob: f6ae50fa5e6b21cebcabb1cb70da2bcb25fb848a [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;
189 for (i = 0; i < op->ob_size; i++) {
Guido van Rossume6f7d181991-10-20 20:20:40 +0000190 XDECREF(op->ob_item[i]);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 }
192 if (op->ob_item != NULL)
193 free((ANY *)op->ob_item);
194 free((ANY *)op);
195}
196
Guido van Rossum90933611991-06-07 16:10:43 +0000197static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198list_print(op, fp, flags)
199 listobject *op;
200 FILE *fp;
201 int flags;
202{
203 int i;
204 fprintf(fp, "[");
Guido van Rossum90933611991-06-07 16:10:43 +0000205 for (i = 0; i < op->ob_size; i++) {
206 if (i > 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000207 fprintf(fp, ", ");
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000208 if (printobject(op->ob_item[i], fp, 0) != 0)
Guido van Rossum90933611991-06-07 16:10:43 +0000209 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210 }
211 fprintf(fp, "]");
Guido van Rossum90933611991-06-07 16:10:43 +0000212 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213}
214
Guido van Rossum234f9421993-06-17 12:35:49 +0000215static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216list_repr(v)
217 listobject *v;
218{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000219 object *s, *comma;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 int i;
221 s = newstringobject("[");
222 comma = newstringobject(", ");
223 for (i = 0; i < v->ob_size && s != NULL; i++) {
224 if (i > 0)
225 joinstring(&s, comma);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000226 joinstring_decref(&s, reprobject(v->ob_item[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000228 XDECREF(comma);
229 joinstring_decref(&s, newstringobject("]"));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 return s;
231}
232
233static int
234list_compare(v, w)
235 listobject *v, *w;
236{
237 int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
238 int i;
239 for (i = 0; i < len; i++) {
240 int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
241 if (cmp != 0)
242 return cmp;
243 }
244 return v->ob_size - w->ob_size;
245}
246
247static int
248list_length(a)
249 listobject *a;
250{
251 return a->ob_size;
252}
253
254static object *
255list_item(a, i)
256 listobject *a;
257 int i;
258{
259 if (i < 0 || i >= a->ob_size) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000260 err_setstr(IndexError, "list index out of range");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261 return NULL;
262 }
263 INCREF(a->ob_item[i]);
264 return a->ob_item[i];
265}
266
267static object *
268list_slice(a, ilow, ihigh)
269 listobject *a;
270 int ilow, ihigh;
271{
272 listobject *np;
273 int i;
274 if (ilow < 0)
275 ilow = 0;
276 else if (ilow > a->ob_size)
277 ilow = a->ob_size;
278 if (ihigh < 0)
279 ihigh = 0;
280 if (ihigh < ilow)
281 ihigh = ilow;
282 else if (ihigh > a->ob_size)
283 ihigh = a->ob_size;
284 np = (listobject *) newlistobject(ihigh - ilow);
285 if (np == NULL)
286 return NULL;
287 for (i = ilow; i < ihigh; i++) {
288 object *v = a->ob_item[i];
289 INCREF(v);
290 np->ob_item[i - ilow] = v;
291 }
292 return (object *)np;
293}
294
Guido van Rossum234f9421993-06-17 12:35:49 +0000295object *
296getlistslice(a, ilow, ihigh)
297 object *a;
298 int ilow, ihigh;
299{
300 if (!is_listobject(a)) {
301 err_badcall();
302 return NULL;
303 }
304 return list_slice((listobject *)a, ilow, ihigh);
305}
306
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307static object *
308list_concat(a, bb)
309 listobject *a;
310 object *bb;
311{
312 int size;
313 int i;
314 listobject *np;
315 if (!is_listobject(bb)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000316 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 return NULL;
318 }
319#define b ((listobject *)bb)
320 size = a->ob_size + b->ob_size;
321 np = (listobject *) newlistobject(size);
322 if (np == NULL) {
Guido van Rossum90933611991-06-07 16:10:43 +0000323 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 }
325 for (i = 0; i < a->ob_size; i++) {
326 object *v = a->ob_item[i];
327 INCREF(v);
328 np->ob_item[i] = v;
329 }
330 for (i = 0; i < b->ob_size; i++) {
331 object *v = b->ob_item[i];
332 INCREF(v);
333 np->ob_item[i + a->ob_size] = v;
334 }
335 return (object *)np;
336#undef b
337}
338
Guido van Rossumed98d481991-03-06 13:07:53 +0000339static object *
340list_repeat(a, n)
341 listobject *a;
342 int n;
343{
344 int i, j;
345 int size;
346 listobject *np;
347 object **p;
348 if (n < 0)
349 n = 0;
350 size = a->ob_size * n;
351 np = (listobject *) newlistobject(size);
352 if (np == NULL)
353 return NULL;
354 p = np->ob_item;
355 for (i = 0; i < n; i++) {
356 for (j = 0; j < a->ob_size; j++) {
357 *p = a->ob_item[j];
358 INCREF(*p);
359 p++;
360 }
361 }
362 return (object *) np;
363}
364
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000366list_ass_slice(a, ilow, ihigh, v)
367 listobject *a;
368 int ilow, ihigh;
369 object *v;
370{
371 object **item;
372 int n; /* Size of replacement list */
373 int d; /* Change in size */
374 int k; /* Loop index */
375#define b ((listobject *)v)
376 if (v == NULL)
377 n = 0;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000378 else if (is_listobject(v)) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379 n = b->ob_size;
Guido van Rossum32dffaa1991-12-24 13:27:34 +0000380 if (a == b) {
381 /* Special case "a[i:j] = a" -- copy b first */
382 int ret;
383 v = list_slice(b, 0, n);
384 ret = list_ass_slice(a, ilow, ihigh, v);
385 DECREF(v);
386 return ret;
387 }
388 }
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000389 else {
390 err_badarg();
391 return -1;
392 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 if (ilow < 0)
394 ilow = 0;
395 else if (ilow > a->ob_size)
396 ilow = a->ob_size;
397 if (ihigh < 0)
398 ihigh = 0;
399 if (ihigh < ilow)
400 ihigh = ilow;
401 else if (ihigh > a->ob_size)
402 ihigh = a->ob_size;
403 item = a->ob_item;
404 d = n - (ihigh-ilow);
Guido van Rossumdc4b93d1993-10-27 14:56:44 +0000405 if (d <= 0) { /* Delete -d items; XDECREF ihigh-ilow items */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000406 for (k = ilow; k < ihigh; k++)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000407 XDECREF(item[k]); /* bug: reentrant side effects */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000408 if (d < 0) {
409 for (/*k = ihigh*/; k < a->ob_size; k++)
410 item[k+d] = item[k];
411 a->ob_size += d;
412 RESIZE(item, object *, a->ob_size); /* Can't fail */
413 a->ob_item = item;
414 }
415 }
Guido van Rossumdc4b93d1993-10-27 14:56:44 +0000416 else { /* Insert d items; XDECREF ihigh-ilow items */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000417 RESIZE(item, object *, a->ob_size + d);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000418 if (item == NULL) {
419 err_nomem();
420 return -1;
421 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000422 for (k = a->ob_size; --k >= ihigh; )
423 item[k+d] = item[k];
424 for (/*k = ihigh-1*/; k >= ilow; --k)
Guido van Rossumd7047b31995-01-02 19:07:15 +0000425 XDECREF(item[k]); /* bug: side effects :-( */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000426 a->ob_item = item;
427 a->ob_size += d;
428 }
429 for (k = 0; k < n; k++, ilow++) {
430 object *w = b->ob_item[k];
Guido van Rossumdc4b93d1993-10-27 14:56:44 +0000431 XINCREF(w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000432 item[ilow] = w;
433 }
434 return 0;
435#undef b
436}
437
Guido van Rossum234f9421993-06-17 12:35:49 +0000438int
439setlistslice(a, ilow, ihigh, v)
440 object *a;
441 int ilow, ihigh;
442 object *v;
443{
444 if (!is_listobject(a)) {
445 err_badcall();
Guido van Rossum1fc238a1993-07-29 08:25:09 +0000446 return -1;
Guido van Rossum234f9421993-06-17 12:35:49 +0000447 }
448 return list_ass_slice((listobject *)a, ilow, ihigh, v);
449}
450
Guido van Rossum4a450d01991-04-03 19:05:18 +0000451static int
452list_ass_item(a, i, v)
453 listobject *a;
454 int i;
455 object *v;
456{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000457 object *old_value;
Guido van Rossum4a450d01991-04-03 19:05:18 +0000458 if (i < 0 || i >= a->ob_size) {
459 err_setstr(IndexError, "list assignment index out of range");
460 return -1;
461 }
462 if (v == NULL)
463 return list_ass_slice(a, i, i+1, v);
464 INCREF(v);
Guido van Rossumd7047b31995-01-02 19:07:15 +0000465 old_value = a->ob_item[i];
Guido van Rossum4a450d01991-04-03 19:05:18 +0000466 a->ob_item[i] = v;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000467 DECREF(old_value);
Guido van Rossum4a450d01991-04-03 19:05:18 +0000468 return 0;
469}
470
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471static object *
472ins(self, where, v)
473 listobject *self;
474 int where;
475 object *v;
476{
477 if (ins1(self, where, v) != 0)
478 return NULL;
479 INCREF(None);
480 return None;
481}
482
483static object *
484listinsert(self, args)
485 listobject *self;
486 object *args;
487{
488 int i;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000489 object *v;
490 if (!getargs(args, "(iO)", &i, &v))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491 return NULL;
Guido van Rossumbf80e541993-02-08 15:49:17 +0000492 return ins(self, i, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493}
494
495static object *
496listappend(self, args)
497 listobject *self;
498 object *args;
499{
Guido van Rossumbf80e541993-02-08 15:49:17 +0000500 object *v;
501 if (!getargs(args, "O", &v))
502 return NULL;
503 return ins(self, (int) self->ob_size, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000504}
505
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000506static object *comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000507
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508static int
509cmp(v, w)
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000510 const ANY *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511{
Guido van Rossume10a19e1992-08-03 19:05:37 +0000512 object *t, *res;
513 long i;
514
515 if (err_occurred())
516 return 0;
517
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000518 if (comparefunc == NULL)
Guido van Rossume10a19e1992-08-03 19:05:37 +0000519 return cmpobject(* (object **) v, * (object **) w);
520
521 /* Call the user-supplied comparison function */
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000522 t = mkvalue("OO", * (object **) v, * (object **) w);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000523 if (t == NULL)
524 return 0;
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000525 res = call_object(comparefunc, t);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000526 DECREF(t);
527 if (res == NULL)
528 return 0;
529 if (!is_intobject(res)) {
530 err_setstr(TypeError, "comparison function should return int");
531 i = 0;
532 }
533 else {
534 i = getintvalue(res);
535 if (i < 0)
536 i = -1;
537 else if (i > 0)
538 i = 1;
539 }
540 DECREF(res);
541 return (int) i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000542}
543
544static object *
545listsort(self, args)
546 listobject *self;
547 object *args;
548{
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000549 object *save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000550 if (self->ob_size <= 1) {
551 INCREF(None);
552 return None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000553 }
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000554 save_comparefunc = comparefunc;
555 comparefunc = args;
556 if (comparefunc != NULL) {
Guido van Rossume10a19e1992-08-03 19:05:37 +0000557 /* Test the comparison function for obvious errors */
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000558 (void) cmp((ANY *)&self->ob_item[0], (ANY *)&self->ob_item[1]);
Guido van Rossume10a19e1992-08-03 19:05:37 +0000559 if (err_occurred()) {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000560 comparefunc = save_comparefunc;
Guido van Rossume10a19e1992-08-03 19:05:37 +0000561 return NULL;
562 }
563 }
564 qsort((char *)self->ob_item,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565 (int) self->ob_size, sizeof(object *), cmp);
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000566 comparefunc = save_comparefunc;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000567 if (err_occurred())
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000568 return NULL;
569 INCREF(None);
570 return None;
571}
572
Guido van Rossumed98d481991-03-06 13:07:53 +0000573static object *
574listreverse(self, args)
575 listobject *self;
576 object *args;
577{
578 register object **p, **q;
579 register object *tmp;
580
581 if (args != NULL) {
582 err_badarg();
583 return NULL;
584 }
585
586 if (self->ob_size > 1) {
587 for (p = self->ob_item, q = self->ob_item + self->ob_size - 1;
588 p < q; p++, q--) {
589 tmp = *p;
590 *p = *q;
591 *q = tmp;
592 }
593 }
594
595 INCREF(None);
596 return None;
597}
598
Guido van Rossum84c76f51990-10-30 13:32:20 +0000599int
600sortlist(v)
601 object *v;
602{
603 if (v == NULL || !is_listobject(v)) {
604 err_badcall();
605 return -1;
606 }
607 v = listsort((listobject *)v, (object *)NULL);
608 if (v == NULL)
609 return -1;
610 DECREF(v);
611 return 0;
612}
613
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000614object *
615listtuple(v)
616 object *v;
617{
618 object *w;
619 object **p;
620 int n;
621 if (v == NULL || !is_listobject(v)) {
622 err_badcall();
623 return NULL;
624 }
625 n = ((listobject *)v)->ob_size;
626 w = newtupleobject(n);
627 if (w == NULL)
628 return NULL;
629 p = ((tupleobject *)w)->ob_item;
630 memcpy((ANY *)p,
631 (ANY *)((listobject *)v)->ob_item,
632 n*sizeof(object *));
633 while (--n >= 0) {
634 INCREF(*p);
635 p++;
636 }
637 return w;
638}
639
Guido van Rossumed98d481991-03-06 13:07:53 +0000640static object *
641listindex(self, args)
642 listobject *self;
643 object *args;
644{
645 int i;
646
647 if (args == NULL) {
648 err_badarg();
649 return NULL;
650 }
651 for (i = 0; i < self->ob_size; i++) {
652 if (cmpobject(self->ob_item[i], args) == 0)
Guido van Rossum7066dd71992-09-17 17:54:56 +0000653 return newintobject((long)i);
Guido van Rossumed98d481991-03-06 13:07:53 +0000654 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000655 err_setstr(ValueError, "list.index(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000656 return NULL;
657}
658
659static object *
Guido van Rossume6f7d181991-10-20 20:20:40 +0000660listcount(self, args)
661 listobject *self;
662 object *args;
663{
664 int count = 0;
665 int i;
666
667 if (args == NULL) {
668 err_badarg();
669 return NULL;
670 }
671 for (i = 0; i < self->ob_size; i++) {
672 if (cmpobject(self->ob_item[i], args) == 0)
673 count++;
674 }
675 return newintobject((long)count);
676}
677
678static object *
Guido van Rossumed98d481991-03-06 13:07:53 +0000679listremove(self, args)
680 listobject *self;
681 object *args;
682{
683 int i;
684
685 if (args == NULL) {
686 err_badarg();
687 return NULL;
688 }
689 for (i = 0; i < self->ob_size; i++) {
690 if (cmpobject(self->ob_item[i], args) == 0) {
691 if (list_ass_slice(self, i, i+1, (object *)NULL) != 0)
692 return NULL;
693 INCREF(None);
694 return None;
695 }
696
697 }
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000698 err_setstr(ValueError, "list.remove(x): x not in list");
Guido van Rossumed98d481991-03-06 13:07:53 +0000699 return NULL;
700}
701
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000702static struct methodlist list_methods[] = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000703 {"append", (method)listappend},
704 {"count", (method)listcount},
705 {"index", (method)listindex},
706 {"insert", (method)listinsert},
707 {"sort", (method)listsort},
708 {"remove", (method)listremove},
709 {"reverse", (method)listreverse},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000710 {NULL, NULL} /* sentinel */
711};
712
713static object *
714list_getattr(f, name)
715 listobject *f;
716 char *name;
717{
718 return findmethod(list_methods, (object *)f, name);
719}
720
721static sequence_methods list_as_sequence = {
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000722 (inquiry)list_length, /*sq_length*/
723 (binaryfunc)list_concat, /*sq_concat*/
724 (intargfunc)list_repeat, /*sq_repeat*/
725 (intargfunc)list_item, /*sq_item*/
726 (intintargfunc)list_slice, /*sq_slice*/
727 (intobjargproc)list_ass_item, /*sq_ass_item*/
728 (intintobjargproc)list_ass_slice, /*sq_ass_slice*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000729};
730
731typeobject Listtype = {
732 OB_HEAD_INIT(&Typetype)
733 0,
734 "list",
735 sizeof(listobject),
736 0,
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000737 (destructor)list_dealloc, /*tp_dealloc*/
738 (printfunc)list_print, /*tp_print*/
739 (getattrfunc)list_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740 0, /*tp_setattr*/
Guido van Rossum6cd2fe01994-08-29 12:45:32 +0000741 (cmpfunc)list_compare, /*tp_compare*/
742 (reprfunc)list_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000743 0, /*tp_as_number*/
744 &list_as_sequence, /*tp_as_sequence*/
745 0, /*tp_as_mapping*/
746};