summaryrefslogtreecommitdiffstats
path: root/Objects/tupleobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/tupleobject.c')
-rw-r--r--Objects/tupleobject.c276
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*/
+};