/***********************************************************
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 or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI 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);
}
