diff options
Diffstat (limited to 'Objects/tupleobject.c')
-rw-r--r-- | Objects/tupleobject.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c new file mode 100644 index 0000000..02d68b3 --- /dev/null +++ b/Objects/tupleobject.c @@ -0,0 +1,276 @@ +/* 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*/ +}; |