/* Tuple object implementation */

#include <stdio.h>

#include "PROTO.h"
#include "object.h"
#include "stringobject.h"
#include "tupleobject.h"
#include "intobject.h"
#include "objimpl.h"

typedef struct {
	OB_VARHEAD
	object *ob_item[1];
} tupleobject;

object *
newtupleobject(size)
	register int size;
{
	register int i;
	register tupleobject *op;
	if (size < 0) {
		errno = EINVAL;
		return NULL;
	}
	op = (tupleobject *)
		malloc(sizeof(tupleobject) + size * sizeof(object *));
	if (op == NULL) {
		errno = ENOMEM;
		return NULL;
	}
	NEWREF(op);
	op->ob_type = &Tupletype;
	op->ob_size = size;
	for (i = 0; i < size; i++)
		op->ob_item[i] = NULL;
	return (object *) op;
}

int
gettuplesize(op)
	register object *op;
{
	if (!is_tupleobject(op)) {
		errno = EBADF;
		return -1;
	}
	else
		return ((tupleobject *)op)->ob_size;
}

object *
gettupleitem(op, i)
	register object *op;
	register int i;
{
	if (!is_tupleobject(op)) {
		errno = EBADF;
		return NULL;
	}
	if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
		errno = EDOM;
		return NULL;
	}
	return ((tupleobject *)op) -> ob_item[i];
}

int
settupleitem(op, i, newitem)
	register object *op;
	register int i;
	register object *newitem;
{
	register object *olditem;
	if (!is_tupleobject(op)) {
		if (newitem != NULL)
			DECREF(newitem);
		return errno = EBADF;
	}
	if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
		if (newitem != NULL)
			DECREF(newitem);
		return errno = EDOM;
	}
	olditem = ((tupleobject *)op) -> ob_item[i];
	((tupleobject *)op) -> ob_item[i] = newitem;
	if (olditem != NULL)
		DECREF(olditem);
	return 0;
}

/* Methods */

static void
tupledealloc(op)
	register tupleobject *op;
{
	register int i;
	for (i = 0; i < op->ob_size; i++) {
		if (op->ob_item[i] != NULL)
			DECREF(op->ob_item[i]);
	}
	free((ANY *)op);
}

static void
tupleprint(op, fp, flags)
	tupleobject *op;
	FILE *fp;
	int flags;
{
	int i;
	fprintf(fp, "(");
	for (i = 0; i < op->ob_size && !StopPrint; i++) {
		if (i > 0) {
			fprintf(fp, ", ");
		}
		printobject(op->ob_item[i], fp, flags);
	}
	if (op->ob_size == 1)
		fprintf(fp, ",");
	fprintf(fp, ")");
}

object *
tuplerepr(v)
	tupleobject *v;
{
	object *s, *t, *comma;
	int i;
	s = newstringobject("(");
	comma = newstringobject(", ");
	for (i = 0; i < v->ob_size && s != NULL; i++) {
		if (i > 0)
			joinstring(&s, comma);
		t = reprobject(v->ob_item[i]);
		joinstring(&s, t);
		if (t != NULL)
			DECREF(t);
	}
	DECREF(comma);
	if (v->ob_size == 1) {
		t = newstringobject(",");
		joinstring(&s, t);
		DECREF(t);
	}
	t = newstringobject(")");
	joinstring(&s, t);
	DECREF(t);
	return s;
}

static int
tuplecompare(v, w)
	register tupleobject *v, *w;
{
	register int len =
		(v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
	register int i;
	for (i = 0; i < len; i++) {
		int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
		if (cmp != 0)
			return cmp;
	}
	return v->ob_size - w->ob_size;
}

static int
tuplelength(a)
	tupleobject *a;
{
	return a->ob_size;
}

static object *
tupleitem(a, i)
	register tupleobject *a;
	register int i;
{
	if (i < 0 || i >= a->ob_size) {
		errno = EDOM;
		return NULL;
	}
	INCREF(a->ob_item[i]);
	return a->ob_item[i];
}

static object *
tupleslice(a, ilow, ihigh)
	register tupleobject *a;
	register int ilow, ihigh;
{
	register tupleobject *np;
	register int i;
	if (ilow < 0)
		ilow = 0;
	if (ihigh > a->ob_size)
		ihigh = a->ob_size;
	if (ihigh < ilow)
		ihigh = ilow;
	if (ilow == 0 && ihigh == a->ob_size) {
		/* XXX can only do this if tuples are immutable! */
		INCREF(a);
		return (object *)a;
	}
	np = (tupleobject *)newtupleobject(ihigh - ilow);
	if (np == NULL)
		return NULL;
	for (i = ilow; i < ihigh; i++) {
		object *v = a->ob_item[i];
		INCREF(v);
		np->ob_item[i - ilow] = v;
	}
	return (object *)np;
}

static object *
tupleconcat(a, bb)
	register tupleobject *a;
	register object *bb;
{
	register int size;
	register int i;
	tupleobject *np;
	if (!is_tupleobject(bb)) {
		errno = EINVAL;
		return NULL;
	}
#define b ((tupleobject *)bb)
	size = a->ob_size + b->ob_size;
	np = (tupleobject *) newtupleobject(size);
	if (np == NULL) {
		errno = ENOMEM;
		return NULL;
	}
	for (i = 0; i < a->ob_size; i++) {
		object *v = a->ob_item[i];
		INCREF(v);
		np->ob_item[i] = v;
	}
	for (i = 0; i < b->ob_size; i++) {
		object *v = b->ob_item[i];
		INCREF(v);
		np->ob_item[i + a->ob_size] = v;
	}
	return (object *)np;
#undef b
}

static sequence_methods tuple_as_sequence = {
	tuplelength,	/*sq_length*/
	tupleconcat,	/*sq_concat*/
	0,		/*sq_repeat*/
	tupleitem,	/*sq_item*/
	tupleslice,	/*sq_slice*/
	0,		/*sq_ass_item*/
	0,		/*sq_ass_slice*/
};

typeobject Tupletype = {
	OB_HEAD_INIT(&Typetype)
	0,
	"tuple",
	sizeof(tupleobject) - sizeof(object *),
	sizeof(object *),
	tupledealloc,	/*tp_dealloc*/
	tupleprint,	/*tp_print*/
	0,		/*tp_getattr*/
	0,		/*tp_setattr*/
	tuplecompare,	/*tp_compare*/
	tuplerepr,	/*tp_repr*/
	0,		/*tp_as_number*/
	&tuple_as_sequence,	/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
};
