/* Tuple object implementation */

#include <stdio.h>

#include "PROTO.h"
#include "object.h"
#include "stringobject.h"
#include "tupleobject.h"
#include "intobject.h"
#include "objimpl.h"
#include "errors.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) {
		err_badcall();
		return NULL;
	}
	op = (tupleobject *)
		malloc(sizeof(tupleobject) + size * sizeof(object *));
	if (op == NULL)
		return err_nomem();
	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)) {
		err_badcall();
		return -1;
	}
	else
		return ((tupleobject *)op)->ob_size;
}

object *
gettupleitem(op, i)
	register object *op;
	register int i;
{
	if (!is_tupleobject(op)) {
		err_badcall();
		return NULL;
	}
	if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
		err_setstr(IndexError, "tuple index out of range");
		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);
		err_badcall();
		return -1;
	}
	if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
		if (newitem != NULL)
			DECREF(newitem);
		err_setstr(IndexError, "tuple assignment index out of range");
		return -1;
	}
	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) {
		err_setstr(IndexError, "tuple index out of range");
		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)) {
		err_badarg();
		return NULL;
	}
#define b ((tupleobject *)bb)
	size = a->ob_size + b->ob_size;
	np = (tupleobject *) newtupleobject(size);
	if (np == NULL) {
		return err_nomem();
	}
	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*/
};
