/***********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* Array object implementation */

/* An array is a uniform list -- all items have the same type.
   The item type is restricted to simple C types like int or float */

#include "allobjects.h"
#include "modsupport.h"
#include "ceval.h"
#ifdef STDC_HEADERS
#include <stddef.h>
#else
#include <sys/types.h>		/* For size_t */
#endif

struct arrayobject; /* Forward */

struct arraydescr {
	int typecode;
	int itemsize;
	object * (*getitem) FPROTO((struct arrayobject *, int));
	int (*setitem) FPROTO((struct arrayobject *, int, object *));
};

typedef struct arrayobject {
	OB_VARHEAD
	char *ob_item;
	struct arraydescr *ob_descr;
} arrayobject;

staticforward typeobject Arraytype;

#define is_arrayobject(op) ((op)->ob_type == &Arraytype)

/* Forward */
static object *newarrayobject PROTO((int, struct arraydescr *));
static int getarraysize PROTO((object *));
static object *getarrayitem PROTO((object *, int));
static int setarrayitem PROTO((object *, int, object *));
static int insarrayitem PROTO((object *, int, object *));
static int addarrayitem PROTO((object *, object *));

static object *
c_getitem(ap, i)
	arrayobject *ap;
	int i;
{
	return newsizedstringobject(&((char *)ap->ob_item)[i], 1);
}

static int
c_setitem(ap, i, v)
	arrayobject *ap;
	int i;
	object *v;
{
	char x;
	if (!getargs(v, "c;array item must be char", &x))
		return -1;
	if (i >= 0)
		     ((char *)ap->ob_item)[i] = x;
	return 0;
}

static object *
b_getitem(ap, i)
	arrayobject *ap;
	int i;
{
	long x = ((char *)ap->ob_item)[i];
	if (x >= 128)
		x -= 256;
	return newintobject(x);
}

static int
b_setitem(ap, i, v)
	arrayobject *ap;
	int i;
	object *v;
{
	char x;
	if (!getargs(v, "b;array item must be integer", &x))
		return -1;
	if (i >= 0)
		     ((char *)ap->ob_item)[i] = x;
	return 0;
}

static object *
h_getitem(ap, i)
	arrayobject *ap;
	int i;
{
	return newintobject((long) ((short *)ap->ob_item)[i]);
}

static int
h_setitem(ap, i, v)
	arrayobject *ap;
	int i;
	object *v;
{
	short x;
	if (!getargs(v, "h;array item must be integer", &x))
		return -1;
	if (i >= 0)
		     ((short *)ap->ob_item)[i] = x;
	return 0;
}

static object *
i_getitem(ap, i)
	arrayobject *ap;
	int i;
{
	return newintobject((long) ((int *)ap->ob_item)[i]);
}

static int
i_setitem(ap, i, v)
	arrayobject *ap;
	int i;
	object *v;
{
	int x;
	if (!getargs(v, "i;array item must be integer", &x))
		return -1;
	if (i >= 0)
		     ((int *)ap->ob_item)[i] = x;
	return 0;
}

static object *
l_getitem(ap, i)
	arrayobject *ap;
	int i;
{
	return newintobject(((long *)ap->ob_item)[i]);
}

static int
l_setitem(ap, i, v)
	arrayobject *ap;
	int i;
	object *v;
{
	long x;
	if (!getargs(v, "l;array item must be integer", &x))
		return -1;
	if (i >= 0)
		     ((long *)ap->ob_item)[i] = x;
	return 0;
}

static object *
f_getitem(ap, i)
	arrayobject *ap;
	int i;
{
	return newfloatobject((double) ((float *)ap->ob_item)[i]);
}

static int
f_setitem(ap, i, v)
	arrayobject *ap;
	int i;
	object *v;
{
	float x;
	if (!getargs(v, "f;array item must be float", &x))
		return -1;
	if (i >= 0)
		     ((float *)ap->ob_item)[i] = x;
	return 0;
}

static object *
d_getitem(ap, i)
	arrayobject *ap;
	int i;
{
	return newfloatobject(((double *)ap->ob_item)[i]);
}

static int
d_setitem(ap, i, v)
	arrayobject *ap;
	int i;
	object *v;
{
	double x;
	if (!getargs(v, "d;array item must be float", &x))
		return -1;
	if (i >= 0)
		     ((double *)ap->ob_item)[i] = x;
	return 0;
}

/* Description of types */
static struct arraydescr descriptors[] = {
	{'c', sizeof(char), c_getitem, c_setitem},
	{'b', sizeof(char), b_getitem, b_setitem},
	{'h', sizeof(short), h_getitem, h_setitem},
	{'i', sizeof(int), i_getitem, i_setitem},
	{'l', sizeof(long), l_getitem, l_setitem},
	{'f', sizeof(float), f_getitem, f_setitem},
	{'d', sizeof(double), d_getitem, d_setitem},
	{'\0', 0, 0, 0} /* Sentinel */
};
/* If we ever allow items larger than double, we must change reverse()! */
	

static object *
newarrayobject(size, descr)
	int size;
	struct arraydescr *descr;
{
	arrayobject *op;
	size_t nbytes;
	if (size < 0) {
		err_badcall();
		return NULL;
	}
	nbytes = size * descr->itemsize;
	/* Check for overflow */
	if (nbytes / descr->itemsize != size) {
		return err_nomem();
	}
	op = NEW(arrayobject, 1);
	if (op == NULL) {
		return err_nomem();
	}
	if (size <= 0) {
		op->ob_item = NULL;
	}
	else {
		op->ob_item = NEW(char, nbytes);
		if (op->ob_item == NULL) {
			DEL(op);
			return err_nomem();
		}
	}
	op->ob_type = &Arraytype;
	op->ob_size = size;
	op->ob_descr = descr;
	NEWREF(op);
	return (object *) op;
}

static int
getarraysize(op)
	object *op;
{
	if (!is_arrayobject(op)) {
		err_badcall();
		return -1;
	}
	return ((arrayobject *)op) -> ob_size;
}

static object *
getarrayitem(op, i)
	object *op;
	int i;
{
	register arrayobject *ap;
	if (!is_arrayobject(op)) {
		err_badcall();
		return NULL;
	}
	ap = (arrayobject *)op;
	if (i < 0 || i >= ap->ob_size) {
		err_setstr(IndexError, "array index out of range");
		return NULL;
	}
	return (*ap->ob_descr->getitem)(ap, i);
}

static int
ins1(self, where, v)
	arrayobject *self;
	int where;
	object *v;
{
	char *items;
	if (v == NULL) {
		err_badcall();
		return -1;
	}
	if ((*self->ob_descr->setitem)(self, -1, v) < 0)
		return -1;
	items = self->ob_item;
	RESIZE(items, char, (self->ob_size+1) * self->ob_descr->itemsize);
	if (items == NULL) {
		err_nomem();
		return -1;
	}
	if (where < 0)
		where = 0;
	if (where > self->ob_size)
		where = self->ob_size;
	memmove(items + (where+1)*self->ob_descr->itemsize,
		items + where*self->ob_descr->itemsize,
		(self->ob_size-where)*self->ob_descr->itemsize);
	self->ob_item = items;
	self->ob_size++;
	return (*self->ob_descr->setitem)(self, where, v);
}

static int
insarrayitem(op, where, newitem)
	object *op;
	int where;
	object *newitem;
{
	if (!is_arrayobject(op)) {
		err_badcall();
		return -1;
	}
	return ins1((arrayobject *)op, where, newitem);
}

static int
addarrayitem(op, newitem)
	object *op;
	object *newitem;
{
	if (!is_arrayobject(op)) {
		err_badcall();
		return -1;
	}
	return ins1((arrayobject *)op,
		(int) ((arrayobject *)op)->ob_size, newitem);
}

/* Methods */

static void
array_dealloc(op)
	arrayobject *op;
{
	if (op->ob_item != NULL)
		DEL(op->ob_item);
	DEL(op);
}

static int
array_compare(v, w)
	arrayobject *v, *w;
{
	int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
	int i;
	for (i = 0; i < len; i++) {
		object *ai, *bi;
		int cmp;
		ai = getarrayitem((object *)v, i);
		bi = getarrayitem((object *)w, i);
		if (ai && bi)
			cmp = cmpobject(ai, bi);
		else
			cmp = -1;
		XDECREF(ai);
		XDECREF(bi);
		if (cmp != 0) {
			err_clear(); /* XXX Can't report errors here */
			return cmp;
		}
	}
	return v->ob_size - w->ob_size;
}

static int
array_length(a)
	arrayobject *a;
{
	return a->ob_size;
}

static object *
array_item(a, i)
	arrayobject *a;
	int i;
{
	if (i < 0 || i >= a->ob_size) {
		err_setstr(IndexError, "array index out of range");
		return NULL;
	}
	return getarrayitem((object *)a, i);
}

static object *
array_slice(a, ilow, ihigh)
	arrayobject *a;
	int ilow, ihigh;
{
	arrayobject *np;
	if (ilow < 0)
		ilow = 0;
	else if (ilow > a->ob_size)
		ilow = a->ob_size;
	if (ihigh < 0)
		ihigh = 0;
	if (ihigh < ilow)
		ihigh = ilow;
	else if (ihigh > a->ob_size)
		ihigh = a->ob_size;
	np = (arrayobject *) newarrayobject(ihigh - ilow, a->ob_descr);
	if (np == NULL)
		return NULL;
	memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
	       (ihigh-ilow) * a->ob_descr->itemsize);
	return (object *)np;
}

static object *
array_concat(a, bb)
	arrayobject *a;
	object *bb;
{
	int size;
	arrayobject *np;
	if (!is_arrayobject(bb)) {
		err_badarg();
		return NULL;
	}
#define b ((arrayobject *)bb)
	if (a->ob_descr != b->ob_descr) {
		err_badarg();
		return NULL;
	}
	size = a->ob_size + b->ob_size;
	np = (arrayobject *) newarrayobject(size, a->ob_descr);
	if (np == NULL) {
		return NULL;
	}
	memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
	memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
	       b->ob_item, b->ob_size*b->ob_descr->itemsize);
	return (object *)np;
#undef b
}

static object *
array_repeat(a, n)
	arrayobject *a;
	int n;
{
	int i;
	int size;
	arrayobject *np;
	char *p;
	int nbytes;
	if (n < 0)
		n = 0;
	size = a->ob_size * n;
	np = (arrayobject *) newarrayobject(size, a->ob_descr);
	if (np == NULL)
		return NULL;
	p = np->ob_item;
	nbytes = a->ob_size * a->ob_descr->itemsize;
	for (i = 0; i < n; i++) {
		memcpy(p, a->ob_item, nbytes);
		p += nbytes;
	}
	return (object *) np;
}

static int
array_ass_slice(a, ilow, ihigh, v)
	arrayobject *a;
	int ilow, ihigh;
	object *v;
{
	char *item;
	int n; /* Size of replacement array */
	int d; /* Change in size */
#define b ((arrayobject *)v)
	if (v == NULL)
		n = 0;
	else if (is_arrayobject(v)) {
		n = b->ob_size;
		if (a == b) {
			/* Special case "a[i:j] = a" -- copy b first */
			int ret;
			v = array_slice(b, 0, n);
			ret = array_ass_slice(a, ilow, ihigh, v);
			DECREF(v);
			return ret;
		}
		if (b->ob_descr != a->ob_descr) {
			err_badarg();
			return -1;
		}
	}
	else {
		err_badarg();
		return -1;
	}
	if (ilow < 0)
		ilow = 0;
	else if (ilow > a->ob_size)
		ilow = a->ob_size;
	if (ihigh < 0)
		ihigh = 0;
	if (ihigh < ilow)
		ihigh = ilow;
	else if (ihigh > a->ob_size)
		ihigh = a->ob_size;
	item = a->ob_item;
	d = n - (ihigh-ilow);
	if (d < 0) { /* Delete -d items */
		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
			item + ihigh*a->ob_descr->itemsize,
			(a->ob_size-ihigh)*a->ob_descr->itemsize);
		a->ob_size += d;
		RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
						/* Can't fail */
		a->ob_item = item;
	}
	else if (d > 0) { /* Insert d items */
		RESIZE(item, char, (a->ob_size + d)*a->ob_descr->itemsize);
		if (item == NULL) {
			err_nomem();
			return -1;
		}
		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
			item + ihigh*a->ob_descr->itemsize,
			(a->ob_size-ihigh)*a->ob_descr->itemsize);
		a->ob_item = item;
		a->ob_size += d;
	}
	if (n > 0)
		memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
		       n*b->ob_descr->itemsize);
	return 0;
#undef b
}

static int
array_ass_item(a, i, v)
	arrayobject *a;
	int i;
	object *v;
{
	if (i < 0 || i >= a->ob_size) {
		err_setstr(IndexError, "array assignment index out of range");
		return -1;
	}
	if (v == NULL)
		return array_ass_slice(a, i, i+1, v);
	return (*a->ob_descr->setitem)(a, i, v);
}

static int
setarrayitem(a, i, v)
	object *a;
	int i;
	object *v;
{
	if (!is_arrayobject(a)) {
		err_badcall();
		return -1;
	}
	return array_ass_item((arrayobject *)a, i, v);
}

static object *
ins(self, where, v)
	arrayobject *self;
	int where;
	object *v;
{
	if (ins1(self, where, v) != 0)
		return NULL;
	INCREF(None);
	return None;
}

static object *
array_insert(self, args)
	arrayobject *self;
	object *args;
{
	int i;
	object *v;
	if (!getargs(args, "(iO)", &i, &v))
		return NULL;
	return ins(self, i, v);
}

static object *
array_append(self, args)
	arrayobject *self;
	object *args;
{
	object *v;
	if (!getargs(args, "O", &v))
		return NULL;
	return ins(self, (int) self->ob_size, v);
}

static object *
array_byteswap(self, args)
	arrayobject *self;
	object *args;
{
	char *p;
	int i;
	switch (self->ob_descr->itemsize) {
	case 1:
		break;
	case 2:
		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
			char p0 = p[0];
			p[0] = p[1];
			p[1] = p0;
		}
		break;
	case 4:
		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 4) {
			char p0 = p[0];
			char p1 = p[1];
			p[0] = p[3];
			p[1] = p[2];
			p[2] = p1;
			p[3] = p0;
		}
		break;
	case 8:
		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 8) {
			char p0 = p[0];
			char p1 = p[1];
			char p2 = p[2];
			char p3 = p[3];
			p[0] = p[7];
			p[1] = p[6];
			p[2] = p[5];
			p[3] = p[4];
			p[4] = p3;
			p[5] = p2;
			p[6] = p1;
			p[7] = p0;
		}
		break;
	default:
		err_setstr(RuntimeError,
			   "don't know how to byteswap this array type");
		return NULL;
	}
	INCREF(None);
	return None;
}

static object *
array_reverse(self, args)
	arrayobject *self;
	object *args;
{
	register int itemsize = self->ob_descr->itemsize;
	register char *p, *q;
	char tmp[sizeof(double)]; /* Assume that's the max item size */

	if (args != NULL) {
		err_badarg();
		return NULL;
	}

	if (self->ob_size > 1) {
		for (p = self->ob_item,
		     q = self->ob_item + (self->ob_size - 1)*itemsize;
		     p < q;
		     p += itemsize, q -= itemsize) {
			memmove(tmp, p, itemsize);
			memmove(p, q, itemsize);
			memmove(q, tmp, itemsize);
		}
	}
	
	INCREF(None);
	return None;
}

/* The following routines were adapted from listobject.c but not converted.
   To make them work you will have to work! */

#if 0
static object *
array_index(self, args)
	arrayobject *self;
	object *args;
{
	int i;
	
	if (args == NULL) {
		err_badarg();
		return NULL;
	}
	for (i = 0; i < self->ob_size; i++) {
		if (cmpobject(self->ob_item[i], args) == 0)
			return newintobject((long)i);
	}
	err_setstr(ValueError, "array.index(x): x not in array");
	return NULL;
}
#endif

#if 0
static object *
array_count(self, args)
	arrayobject *self;
	object *args;
{
	int count = 0;
	int i;
	
	if (args == NULL) {
		err_badarg();
		return NULL;
	}
	for (i = 0; i < self->ob_size; i++) {
		if (cmpobject(self->ob_item[i], args) == 0)
			count++;
	}
	return newintobject((long)count);
}
#endif

#if 0
static object *
array_remove(self, args)
	arrayobject *self;
	object *args;
{
	int i;
	
	if (args == NULL) {
		err_badarg();
		return NULL;
	}
	for (i = 0; i < self->ob_size; i++) {
		if (cmpobject(self->ob_item[i], args) == 0) {
			if (array_ass_slice(self, i, i+1, (object *)NULL) != 0)
				return NULL;
			INCREF(None);
			return None;
		}
			
	}
	err_setstr(ValueError, "array.remove(x): x not in array");
	return NULL;
}
#endif

static object *
array_fromfile(self, args)
	arrayobject *self;
	object *args;
{
	object *f;
	int n;
	FILE *fp;
	if (!getargs(args, "(Oi)", &f, &n))
		return NULL;
	fp = getfilefile(f);
	if (fp == NULL) {
		err_setstr(TypeError, "arg1 must be open file");
		return NULL;
	}
	if (n > 0) {
		char *item = self->ob_item;
		int itemsize = self->ob_descr->itemsize;
		int nread;
		RESIZE(item, char, (self->ob_size + n) * itemsize);
		if (item == NULL) {
			err_nomem();
			return NULL;
		}
		self->ob_item = item;
		self->ob_size += n;
		nread = fread(item + (self->ob_size - n) * itemsize,
			      itemsize, n, fp);
		if (nread < n) {
			self->ob_size -= (n - nread);
			RESIZE(item, char, self->ob_size*itemsize);
			self->ob_item = item;
			err_setstr(EOFError, "not enough items in file");
			return NULL;
		}
	}
	INCREF(None);
	return None;
}

static object *
array_tofile(self, args)
	arrayobject *self;
	object *args;
{
	object *f;
	FILE *fp;
	if (!getargs(args, "O", &f))
		return NULL;
	fp = getfilefile(f);
	if (fp == NULL) {
		err_setstr(TypeError, "arg must be open file");
		return NULL;
	}
	if (self->ob_size > 0) {
		if (fwrite(self->ob_item, self->ob_descr->itemsize,
			   self->ob_size, fp) != self->ob_size) {
			err_errno(IOError);
			clearerr(fp);
			return NULL;
		}
	}
	INCREF(None);
	return None;
}

static object *
array_fromlist(self, args)
	arrayobject *self;
	object *args;
{
	int n;
	object *list;
	int itemsize = self->ob_descr->itemsize;
	if (!getargs(args, "O", &list))
		return NULL;
	if (!is_listobject(list)) {
		err_setstr(TypeError, "arg must be list");
		return NULL;
	}
	n = getlistsize(list);
	if (n > 0) {
		char *item = self->ob_item;
		int i;
		RESIZE(item, char, (self->ob_size + n) * itemsize);
		if (item == NULL) {
			err_nomem();
			return NULL;
		}
		self->ob_item = item;
		self->ob_size += n;
		for (i = 0; i < n; i++) {
			object *v = getlistitem(list, i);
			if ((*self->ob_descr->setitem)(self,
					self->ob_size - n + i, v) != 0) {
				self->ob_size -= n;
				RESIZE(item, char, self->ob_size * itemsize);
				self->ob_item = item;
				return NULL;
			}
		}
	}
	INCREF(None);
	return None;
}

static object *
array_tolist(self, args)
	arrayobject *self;
	object *args;
{
	object *list = newlistobject(self->ob_size);
	int i;
	if (list == NULL)
		return NULL;
	for (i = 0; i < self->ob_size; i++) {
		object *v = getarrayitem((object *)self, i);
		if (v == NULL) {
			DECREF(list);
			return NULL;
		}
		setlistitem(list, i, v);
	}
	return list;
}

static object *
array_fromstring(self, args)
	arrayobject *self;
	object *args;
{
	char *str;
	int n;
	int itemsize = self->ob_descr->itemsize;
	if (!getargs(args, "s#", &str, &n))
		return NULL;
	if (n % itemsize != 0) {
		err_setstr(ValueError,
			   "string length not a multiple of item size");
		return NULL;
	}
	n = n / itemsize;
	if (n > 0) {
		char *item = self->ob_item;
		RESIZE(item, char, (self->ob_size + n) * itemsize);
		if (item == NULL) {
			err_nomem();
			return NULL;
		}
		self->ob_item = item;
		self->ob_size += n;
		memcpy(item + (self->ob_size - n) * itemsize, str, itemsize*n);
	}
	INCREF(None);
	return None;
}

static object *
array_tostring(self, args)
	arrayobject *self;
	object *args;
{
	if (!getargs(args, ""))
		return NULL;
	return newsizedstringobject(self->ob_item,
				    self->ob_size * self->ob_descr->itemsize);
}

static struct methodlist array_methods[] = {
	{"append",	(method)array_append},
	{"byteswap",	(method)array_byteswap},
/*	{"count",	(method)array_count},*/
	{"fromfile",	(method)array_fromfile},
	{"fromlist",	(method)array_fromlist},
	{"fromstring",	(method)array_fromstring},
/*	{"index",	(method)array_index},*/
	{"insert",	(method)array_insert},
	{"read",	(method)array_fromfile},
/*	{"remove",	(method)array_remove},*/
	{"reverse",	(method)array_reverse},
/*	{"sort",	(method)array_sort},*/
	{"tofile",	(method)array_tofile},
	{"tolist",	(method)array_tolist},
	{"tostring",	(method)array_tostring},
	{"write",	(method)array_tofile},
	{NULL,		NULL}		/* sentinel */
};

static object *
array_getattr(a, name)
	arrayobject *a;
	char *name;
{
	if (strcmp(name, "typecode") == 0) {
		char tc = a->ob_descr->typecode;
		return newsizedstringobject(&tc, 1);
	}
	if (strcmp(name, "itemsize") == 0) {
		return newintobject((long)a->ob_descr->itemsize);
	}
	if (strcmp(name, "__members__") == 0) {
		object *list = newlistobject(2);
		if (list) {
			setlistitem(list, 0, newstringobject("typecode"));
			setlistitem(list, 1, newstringobject("itemsize"));
			if (err_occurred()) {
				DECREF(list);
				list = NULL;
			}
		}
		return list;
	}
	return findmethod(array_methods, (object *)a, name);
}

static int
array_print(a, fp, flags)
	arrayobject *a;
	FILE *fp;
	int flags;
{
	int ok = 0;
	int i, len;
	object *v;
	len = a->ob_size;
	if (len == 0) {
		fprintf(fp, "array('%c')", a->ob_descr->typecode);
		return ok;
	}
	if (a->ob_descr->typecode == 'c') {
		fprintf(fp, "array('c', ");
		v = array_tostring(a, (object *)NULL);
		ok = printobject(v, fp, 0);
		XDECREF(v);
		fprintf(fp, ")");
		return ok;
	}
	fprintf(fp, "array('%c', [", a->ob_descr->typecode);
	for (i = 0; i < len && ok == 0; i++) {
		if (i > 0)
			fprintf(fp, ", ");
		v = (a->ob_descr->getitem)(a, i);
		ok = printobject(v, fp, 0);
		XDECREF(v);
	}
	fprintf(fp, "])");
	return ok;
}

static object *
array_repr(a)
	arrayobject *a;
{
	char buf[256];
	object *s, *t, *comma, *v;
	int i, len;
	len = a->ob_size;
	if (len == 0) {
		sprintf(buf, "array('%c')", a->ob_descr->typecode);
		return newstringobject(buf);
	}
	if (a->ob_descr->typecode == 'c') {
		sprintf(buf, "array('c', ");
		s = newstringobject(buf);
		v = array_tostring(a, (object *)NULL);
		t = reprobject(v);
		XDECREF(v);
		joinstring_decref(&s, t);
		joinstring_decref(&s, newstringobject(")"));
		return s;
	}
	sprintf(buf, "array('%c', [", a->ob_descr->typecode);
	s = newstringobject(buf);
	comma = newstringobject(", ");
	for (i = 0; i < len && !err_occurred(); i++) {
		if (i > 0)
			joinstring(&s, comma);
		v = (a->ob_descr->getitem)(a, i);
		t = reprobject(v);
		XDECREF(v);
		joinstring_decref(&s, t);
	}
	XDECREF(comma);
	joinstring_decref(&s, newstringobject("])"));
	return s;
}

static sequence_methods array_as_sequence = {
	(inquiry)array_length,			/*sq_length*/
	(binaryfunc)array_concat,		/*sq_concat*/
	(intargfunc)array_repeat,		/*sq_repeat*/
	(intargfunc)array_item,			/*sq_item*/
	(intintargfunc)array_slice,		/*sq_slice*/
	(intobjargproc)array_ass_item,		/*sq_ass_item*/
	(intintobjargproc)array_ass_slice,	/*sq_ass_slice*/
};

statichere typeobject Arraytype = {
	OB_HEAD_INIT(&Typetype)
	0,
	"array",
	sizeof(arrayobject),
	0,
	(destructor)array_dealloc,	/*tp_dealloc*/
	(printfunc)array_print,		/*tp_print*/
	(getattrfunc)array_getattr,	/*tp_getattr*/
	0,				/*tp_setattr*/
	(cmpfunc)array_compare,		/*tp_compare*/
	(reprfunc)array_repr,		/*tp_repr*/
	0,				/*tp_as_number*/
	&array_as_sequence,		/*tp_as_sequence*/
	0,				/*tp_as_mapping*/
};


static object *
a_array(self, args)
	object *self;
	object *args;
{
	char c;
	object *initial = NULL;
	struct arraydescr *descr;
	if (!getargs(args, "c", &c)) {
		err_clear();
		if (!getargs(args, "(cO)", &c, &initial))
			return NULL;
		if (!is_listobject(initial) && !is_stringobject(initial)) {
			err_setstr(TypeError,
				   "array initializer must be list or string");
			return NULL;
		}
	}
	for (descr = descriptors; descr->typecode != '\0'; descr++) {
		if (descr->typecode == c) {
			object *a;
			int len;
			if (initial == NULL || !is_listobject(initial))
				len = 0;
			else
				len = getlistsize(initial);
			a = newarrayobject(len, descr);
			if (a == NULL)
				return NULL;
			if (len > 0) {
				int i;
				for (i = 0; i < len; i++) {
					object *v = getlistitem(initial, i);
					if (setarrayitem(a, i, v) != 0) {
						DECREF(a);
						return NULL;
					}
				}
			}
			if (initial != NULL && is_stringobject(initial)) {
				object *v =
				  array_fromstring((arrayobject *)a, initial);
				if (v == NULL) {
					DECREF(a);
					return NULL;
				}
				DECREF(v);
			}
			return a;
		}
	}
	err_setstr(ValueError, "bad typecode (must be c, b, h, l, f or d)");
	return NULL;
}

static struct methodlist a_methods[] = {
	{"array",	a_array},
	{NULL,		NULL}		/* sentinel */
};

void
initarray()
{
	initmodule("array", a_methods);
}
