symbian-qemu-0.9.1-12/python-2.6.1/Objects/enumobject.c
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Objects/enumobject.c	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,361 @@
+/* enumerate object */
+
+#include "Python.h"
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t en_index;	   /* current index of enumeration */
+	PyObject* en_sit;          /* secondary iterator of enumeration */
+	PyObject* en_result;	   /* result tuple  */
+	PyObject* en_longindex;	   /* index for sequences >= PY_SSIZE_T_MAX */
+} enumobject;
+
+static PyObject *
+enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	enumobject *en;
+	PyObject *seq = NULL;
+	PyObject *start = NULL;
+	static char *kwlist[] = {"sequence", "start", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist,
+					 &seq, &start))
+		return NULL;
+
+	en = (enumobject *)type->tp_alloc(type, 0);
+	if (en == NULL)
+		return NULL;
+	if (start != NULL) {
+		start = PyNumber_Index(start);
+		if (start == NULL) {
+			Py_DECREF(en);
+			return NULL;
+		}
+		assert(PyInt_Check(start) || PyLong_Check(start));
+		en->en_index = PyInt_AsSsize_t(start);
+		if (en->en_index == -1 && PyErr_Occurred()) {
+			PyErr_Clear();
+			en->en_index = PY_SSIZE_T_MAX;
+			en->en_longindex = start;
+		} else {
+			en->en_longindex = NULL;
+			Py_DECREF(start);
+		}
+	} else {
+		en->en_index = 0;
+		en->en_longindex = NULL;
+	}
+	en->en_sit = PyObject_GetIter(seq);
+	if (en->en_sit == NULL) {
+		Py_DECREF(en);
+		return NULL;
+	}
+	en->en_result = PyTuple_Pack(2, Py_None, Py_None);
+	if (en->en_result == NULL) {
+		Py_DECREF(en);
+		return NULL;
+	}
+	return (PyObject *)en;
+}
+
+static void
+enum_dealloc(enumobject *en)
+{
+	PyObject_GC_UnTrack(en);
+	Py_XDECREF(en->en_sit);
+	Py_XDECREF(en->en_result);
+	Py_XDECREF(en->en_longindex);
+	Py_TYPE(en)->tp_free(en);
+}
+
+static int
+enum_traverse(enumobject *en, visitproc visit, void *arg)
+{
+	Py_VISIT(en->en_sit);
+	Py_VISIT(en->en_result);
+	Py_VISIT(en->en_longindex);
+	return 0;
+}
+
+static PyObject *
+enum_next_long(enumobject *en, PyObject* next_item)
+{
+	static PyObject *one = NULL;
+	PyObject *result = en->en_result;
+	PyObject *next_index;
+	PyObject *stepped_up;
+
+	if (en->en_longindex == NULL) {
+		en->en_longindex = PyInt_FromSsize_t(PY_SSIZE_T_MAX);
+		if (en->en_longindex == NULL)
+			return NULL;
+	}
+	if (one == NULL) {
+		one = PyInt_FromLong(1);
+		if (one == NULL)
+			return NULL;
+	}
+	next_index = en->en_longindex;
+	assert(next_index != NULL);
+	stepped_up = PyNumber_Add(next_index, one);
+	if (stepped_up == NULL)
+		return NULL;
+	en->en_longindex = stepped_up;
+
+	if (result->ob_refcnt == 1) {
+		Py_INCREF(result);
+		Py_DECREF(PyTuple_GET_ITEM(result, 0));
+		Py_DECREF(PyTuple_GET_ITEM(result, 1));
+	} else {
+		result = PyTuple_New(2);
+		if (result == NULL) {
+			Py_DECREF(next_index);
+			Py_DECREF(next_item);
+			return NULL;
+		}
+	}
+	PyTuple_SET_ITEM(result, 0, next_index);
+	PyTuple_SET_ITEM(result, 1, next_item);
+	return result;
+}
+
+static PyObject *
+enum_next(enumobject *en)
+{
+	PyObject *next_index;
+	PyObject *next_item;
+	PyObject *result = en->en_result;
+	PyObject *it = en->en_sit;
+
+	next_item = (*Py_TYPE(it)->tp_iternext)(it);
+	if (next_item == NULL)
+		return NULL;
+
+	if (en->en_index == PY_SSIZE_T_MAX)
+		return enum_next_long(en, next_item);
+
+	next_index = PyInt_FromSsize_t(en->en_index);
+	if (next_index == NULL) {
+		Py_DECREF(next_item);
+		return NULL;
+	}
+	en->en_index++;
+
+	if (result->ob_refcnt == 1) {
+		Py_INCREF(result);
+		Py_DECREF(PyTuple_GET_ITEM(result, 0));
+		Py_DECREF(PyTuple_GET_ITEM(result, 1));
+	} else {
+		result = PyTuple_New(2);
+		if (result == NULL) {
+			Py_DECREF(next_index);
+			Py_DECREF(next_item);
+			return NULL;
+		}
+	}
+	PyTuple_SET_ITEM(result, 0, next_index);
+	PyTuple_SET_ITEM(result, 1, next_item);
+	return result;
+}
+
+PyDoc_STRVAR(enum_doc,
+"enumerate(iterable) -> iterator for index, value of iterable\n"
+"\n"
+"Return an enumerate object.  iterable must be an other object that supports\n"
+"iteration.  The enumerate object yields pairs containing a count (from\n"
+"zero) and a value yielded by the iterable argument.  enumerate is useful\n"
+"for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
+
+PyTypeObject PyEnum_Type = {
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
+	"enumerate",                    /* tp_name */
+	sizeof(enumobject),             /* tp_basicsize */
+	0,                              /* tp_itemsize */
+	/* methods */
+	(destructor)enum_dealloc,       /* tp_dealloc */
+	0,                              /* tp_print */
+	0,                              /* tp_getattr */
+	0,                              /* tp_setattr */
+	0,                              /* tp_compare */
+	0,                              /* tp_repr */
+	0,                              /* tp_as_number */
+	0,                              /* tp_as_sequence */
+	0,                              /* tp_as_mapping */
+	0,                              /* tp_hash */
+	0,                              /* tp_call */
+	0,                              /* tp_str */
+	PyObject_GenericGetAttr,        /* tp_getattro */
+	0,                              /* tp_setattro */
+	0,                              /* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,    /* tp_flags */
+	enum_doc,                       /* tp_doc */
+	(traverseproc)enum_traverse,    /* tp_traverse */
+	0,                              /* tp_clear */
+	0,                              /* tp_richcompare */
+	0,                              /* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)enum_next,        /* tp_iternext */
+	0,                              /* tp_methods */
+	0,                              /* tp_members */
+	0,                              /* tp_getset */
+	0,                              /* tp_base */
+	0,                              /* tp_dict */
+	0,                              /* tp_descr_get */
+	0,                              /* tp_descr_set */
+	0,                              /* tp_dictoffset */
+	0,                              /* tp_init */
+	PyType_GenericAlloc,            /* tp_alloc */
+	enum_new,                       /* tp_new */
+	PyObject_GC_Del,                /* tp_free */
+};
+
+/* Reversed Object ***************************************************************/
+
+typedef struct {
+	PyObject_HEAD
+	Py_ssize_t      index;
+	PyObject* seq;
+} reversedobject;
+
+static PyObject *
+reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	Py_ssize_t n;
+	PyObject *seq;
+	reversedobject *ro;
+
+	if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
+		return NULL;
+
+	if (PyObject_HasAttrString(seq, "__reversed__"))
+		return PyObject_CallMethod(seq, "__reversed__", NULL);
+
+	if (!PySequence_Check(seq)) {
+		PyErr_SetString(PyExc_TypeError,
+				"argument to reversed() must be a sequence");
+		return NULL;
+	}
+
+	n = PySequence_Size(seq);
+	if (n == -1)
+		return NULL;
+
+	ro = (reversedobject *)type->tp_alloc(type, 0);
+	if (ro == NULL)
+		return NULL;
+
+	ro->index = n-1;
+	Py_INCREF(seq);
+	ro->seq = seq;
+	return (PyObject *)ro;
+}
+
+static void
+reversed_dealloc(reversedobject *ro)
+{
+	PyObject_GC_UnTrack(ro);
+	Py_XDECREF(ro->seq);
+	Py_TYPE(ro)->tp_free(ro);
+}
+
+static int
+reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
+{
+	Py_VISIT(ro->seq);
+	return 0;
+}
+
+static PyObject *
+reversed_next(reversedobject *ro)
+{
+	PyObject *item;
+	Py_ssize_t index = ro->index;
+
+	if (index >= 0) {
+		item = PySequence_GetItem(ro->seq, index);
+		if (item != NULL) {
+			ro->index--;
+			return item;
+		}
+		if (PyErr_ExceptionMatches(PyExc_IndexError) ||
+		    PyErr_ExceptionMatches(PyExc_StopIteration))
+			PyErr_Clear();
+	}
+	ro->index = -1;
+	Py_CLEAR(ro->seq);
+	return NULL;
+}
+
+PyDoc_STRVAR(reversed_doc,
+"reversed(sequence) -> reverse iterator over values of the sequence\n"
+"\n"
+"Return a reverse iterator");
+
+static PyObject *
+reversed_len(reversedobject *ro)
+{
+	Py_ssize_t position, seqsize;
+
+	if (ro->seq == NULL)
+		return PyInt_FromLong(0);
+	seqsize = PySequence_Size(ro->seq);
+	if (seqsize == -1)
+		return NULL;
+	position = ro->index + 1;
+	return PyInt_FromSsize_t((seqsize < position)  ?  0  :  position);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef reversediter_methods[] = {
+	{"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},
+ 	{NULL,		NULL}		/* sentinel */
+};
+
+PyTypeObject PyReversed_Type = {
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
+	"reversed",                     /* tp_name */
+	sizeof(reversedobject),         /* tp_basicsize */
+	0,                              /* tp_itemsize */
+	/* methods */
+	(destructor)reversed_dealloc,   /* tp_dealloc */
+	0,                              /* tp_print */
+	0,                              /* tp_getattr */
+	0,                              /* tp_setattr */
+	0,                              /* tp_compare */
+	0,                              /* tp_repr */
+	0,                              /* tp_as_number */
+	0,				/* tp_as_sequence */
+	0,                              /* tp_as_mapping */
+	0,                              /* tp_hash */
+	0,                              /* tp_call */
+	0,                              /* tp_str */
+	PyObject_GenericGetAttr,        /* tp_getattro */
+	0,                              /* tp_setattro */
+	0,                              /* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,    /* tp_flags */
+	reversed_doc,                   /* tp_doc */
+	(traverseproc)reversed_traverse,/* tp_traverse */
+	0,                              /* tp_clear */
+	0,                              /* tp_richcompare */
+	0,                              /* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)reversed_next,    /* tp_iternext */
+	reversediter_methods,		/* tp_methods */
+	0,                              /* tp_members */
+	0,                              /* tp_getset */
+	0,                              /* tp_base */
+	0,                              /* tp_dict */
+	0,                              /* tp_descr_get */
+	0,                              /* tp_descr_set */
+	0,                              /* tp_dictoffset */
+	0,                              /* tp_init */
+	PyType_GenericAlloc,            /* tp_alloc */
+	reversed_new,                   /* tp_new */
+	PyObject_GC_Del,                /* tp_free */
+};