LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Objects - enumobject.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 68 171 39.8 %
Date: 2012-12-17 Functions: 6 13 46.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* enumerate object */
       2             : 
       3             : #include "Python.h"
       4             : 
       5             : typedef struct {
       6             :     PyObject_HEAD
       7             :     Py_ssize_t en_index;           /* current index of enumeration */
       8             :     PyObject* en_sit;          /* secondary iterator of enumeration */
       9             :     PyObject* en_result;           /* result tuple  */
      10             :     PyObject* en_longindex;        /* index for sequences >= PY_SSIZE_T_MAX */
      11             : } enumobject;
      12             : 
      13             : static PyObject *
      14           2 : enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
      15             : {
      16             :     enumobject *en;
      17           2 :     PyObject *seq = NULL;
      18           2 :     PyObject *start = NULL;
      19             :     static char *kwlist[] = {"iterable", "start", 0};
      20             : 
      21           2 :     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist,
      22             :                                      &seq, &start))
      23           0 :         return NULL;
      24             : 
      25           2 :     en = (enumobject *)type->tp_alloc(type, 0);
      26           2 :     if (en == NULL)
      27           0 :         return NULL;
      28           2 :     if (start != NULL) {
      29           0 :         start = PyNumber_Index(start);
      30           0 :         if (start == NULL) {
      31           0 :             Py_DECREF(en);
      32           0 :             return NULL;
      33             :         }
      34             :         assert(PyLong_Check(start));
      35           0 :         en->en_index = PyLong_AsSsize_t(start);
      36           0 :         if (en->en_index == -1 && PyErr_Occurred()) {
      37           0 :             PyErr_Clear();
      38           0 :             en->en_index = PY_SSIZE_T_MAX;
      39           0 :             en->en_longindex = start;
      40             :         } else {
      41           0 :             en->en_longindex = NULL;
      42           0 :             Py_DECREF(start);
      43             :         }
      44             :     } else {
      45           2 :         en->en_index = 0;
      46           2 :         en->en_longindex = NULL;
      47             :     }
      48           2 :     en->en_sit = PyObject_GetIter(seq);
      49           2 :     if (en->en_sit == NULL) {
      50           0 :         Py_DECREF(en);
      51           0 :         return NULL;
      52             :     }
      53           2 :     en->en_result = PyTuple_Pack(2, Py_None, Py_None);
      54           2 :     if (en->en_result == NULL) {
      55           0 :         Py_DECREF(en);
      56           0 :         return NULL;
      57             :     }
      58           2 :     return (PyObject *)en;
      59             : }
      60             : 
      61             : static void
      62           2 : enum_dealloc(enumobject *en)
      63             : {
      64           2 :     PyObject_GC_UnTrack(en);
      65           2 :     Py_XDECREF(en->en_sit);
      66           2 :     Py_XDECREF(en->en_result);
      67           2 :     Py_XDECREF(en->en_longindex);
      68           2 :     Py_TYPE(en)->tp_free(en);
      69           2 : }
      70             : 
      71             : static int
      72           0 : enum_traverse(enumobject *en, visitproc visit, void *arg)
      73             : {
      74           0 :     Py_VISIT(en->en_sit);
      75           0 :     Py_VISIT(en->en_result);
      76           0 :     Py_VISIT(en->en_longindex);
      77           0 :     return 0;
      78             : }
      79             : 
      80             : static PyObject *
      81           0 : enum_next_long(enumobject *en, PyObject* next_item)
      82             : {
      83             :     static PyObject *one = NULL;
      84           0 :     PyObject *result = en->en_result;
      85             :     PyObject *next_index;
      86             :     PyObject *stepped_up;
      87             : 
      88           0 :     if (en->en_longindex == NULL) {
      89           0 :         en->en_longindex = PyLong_FromSsize_t(PY_SSIZE_T_MAX);
      90           0 :         if (en->en_longindex == NULL)
      91           0 :             return NULL;
      92             :     }
      93           0 :     if (one == NULL) {
      94           0 :         one = PyLong_FromLong(1);
      95           0 :         if (one == NULL)
      96           0 :             return NULL;
      97             :     }
      98           0 :     next_index = en->en_longindex;
      99             :     assert(next_index != NULL);
     100           0 :     stepped_up = PyNumber_Add(next_index, one);
     101           0 :     if (stepped_up == NULL)
     102           0 :         return NULL;
     103           0 :     en->en_longindex = stepped_up;
     104             : 
     105           0 :     if (result->ob_refcnt == 1) {
     106           0 :         Py_INCREF(result);
     107           0 :         Py_DECREF(PyTuple_GET_ITEM(result, 0));
     108           0 :         Py_DECREF(PyTuple_GET_ITEM(result, 1));
     109             :     } else {
     110           0 :         result = PyTuple_New(2);
     111           0 :         if (result == NULL) {
     112           0 :             Py_DECREF(next_index);
     113           0 :             Py_DECREF(next_item);
     114           0 :             return NULL;
     115             :         }
     116             :     }
     117           0 :     PyTuple_SET_ITEM(result, 0, next_index);
     118           0 :     PyTuple_SET_ITEM(result, 1, next_item);
     119           0 :     return result;
     120             : }
     121             : 
     122             : static PyObject *
     123          11 : enum_next(enumobject *en)
     124             : {
     125             :     PyObject *next_index;
     126             :     PyObject *next_item;
     127          11 :     PyObject *result = en->en_result;
     128          11 :     PyObject *it = en->en_sit;
     129             : 
     130          11 :     next_item = (*Py_TYPE(it)->tp_iternext)(it);
     131          11 :     if (next_item == NULL)
     132           2 :         return NULL;
     133             : 
     134           9 :     if (en->en_index == PY_SSIZE_T_MAX)
     135           0 :         return enum_next_long(en, next_item);
     136             : 
     137           9 :     next_index = PyLong_FromSsize_t(en->en_index);
     138           9 :     if (next_index == NULL) {
     139           0 :         Py_DECREF(next_item);
     140           0 :         return NULL;
     141             :     }
     142           9 :     en->en_index++;
     143             : 
     144           9 :     if (result->ob_refcnt == 1) {
     145           9 :         Py_INCREF(result);
     146           9 :         Py_DECREF(PyTuple_GET_ITEM(result, 0));
     147           9 :         Py_DECREF(PyTuple_GET_ITEM(result, 1));
     148             :     } else {
     149           0 :         result = PyTuple_New(2);
     150           0 :         if (result == NULL) {
     151           0 :             Py_DECREF(next_index);
     152           0 :             Py_DECREF(next_item);
     153           0 :             return NULL;
     154             :         }
     155             :     }
     156           9 :     PyTuple_SET_ITEM(result, 0, next_index);
     157           9 :     PyTuple_SET_ITEM(result, 1, next_item);
     158           9 :     return result;
     159             : }
     160             : 
     161             : static PyObject *
     162           0 : enum_reduce(enumobject *en)
     163             : {
     164           0 :     if (en->en_longindex != NULL)
     165           0 :         return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex);
     166             :     else
     167           0 :         return Py_BuildValue("O(On)", Py_TYPE(en), en->en_sit, en->en_index);
     168             : }
     169             : 
     170             : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
     171             : 
     172             : static PyMethodDef enum_methods[] = {
     173             :     {"__reduce__", (PyCFunction)enum_reduce, METH_NOARGS, reduce_doc},
     174             :     {NULL,              NULL}           /* sentinel */
     175             : };
     176             : 
     177             : PyDoc_STRVAR(enum_doc,
     178             : "enumerate(iterable[, start]) -> iterator for index, value of iterable\n"
     179             : "\n"
     180             : "Return an enumerate object.  iterable must be another object that supports\n"
     181             : "iteration.  The enumerate object yields pairs containing a count (from\n"
     182             : "start, which defaults to zero) and a value yielded by the iterable argument.\n"
     183             : "enumerate is useful for obtaining an indexed list:\n"
     184             : "    (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
     185             : 
     186             : PyTypeObject PyEnum_Type = {
     187             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     188             :     "enumerate",                    /* tp_name */
     189             :     sizeof(enumobject),             /* tp_basicsize */
     190             :     0,                              /* tp_itemsize */
     191             :     /* methods */
     192             :     (destructor)enum_dealloc,       /* tp_dealloc */
     193             :     0,                              /* tp_print */
     194             :     0,                              /* tp_getattr */
     195             :     0,                              /* tp_setattr */
     196             :     0,                              /* tp_reserved */
     197             :     0,                              /* tp_repr */
     198             :     0,                              /* tp_as_number */
     199             :     0,                              /* tp_as_sequence */
     200             :     0,                              /* tp_as_mapping */
     201             :     0,                              /* tp_hash */
     202             :     0,                              /* tp_call */
     203             :     0,                              /* tp_str */
     204             :     PyObject_GenericGetAttr,        /* tp_getattro */
     205             :     0,                              /* tp_setattro */
     206             :     0,                              /* tp_as_buffer */
     207             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
     208             :         Py_TPFLAGS_BASETYPE,    /* tp_flags */
     209             :     enum_doc,                       /* tp_doc */
     210             :     (traverseproc)enum_traverse,    /* tp_traverse */
     211             :     0,                              /* tp_clear */
     212             :     0,                              /* tp_richcompare */
     213             :     0,                              /* tp_weaklistoffset */
     214             :     PyObject_SelfIter,                  /* tp_iter */
     215             :     (iternextfunc)enum_next,        /* tp_iternext */
     216             :     enum_methods,                   /* tp_methods */
     217             :     0,                              /* tp_members */
     218             :     0,                              /* tp_getset */
     219             :     0,                              /* tp_base */
     220             :     0,                              /* tp_dict */
     221             :     0,                              /* tp_descr_get */
     222             :     0,                              /* tp_descr_set */
     223             :     0,                              /* tp_dictoffset */
     224             :     0,                              /* tp_init */
     225             :     PyType_GenericAlloc,            /* tp_alloc */
     226             :     enum_new,                       /* tp_new */
     227             :     PyObject_GC_Del,                /* tp_free */
     228             : };
     229             : 
     230             : /* Reversed Object ***************************************************************/
     231             : 
     232             : typedef struct {
     233             :     PyObject_HEAD
     234             :     Py_ssize_t      index;
     235             :     PyObject* seq;
     236             : } reversedobject;
     237             : 
     238             : static PyObject *
     239         188 : reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     240             : {
     241             :     Py_ssize_t n;
     242             :     PyObject *seq, *reversed_meth;
     243             :     reversedobject *ro;
     244             :     _Py_IDENTIFIER(__reversed__);
     245             : 
     246         188 :     if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
     247           0 :         return NULL;
     248             : 
     249         188 :     if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
     250           0 :         return NULL;
     251             : 
     252         188 :     reversed_meth = _PyObject_LookupSpecial(seq, &PyId___reversed__);
     253         188 :     if (reversed_meth != NULL) {
     254           1 :         PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL);
     255           1 :         Py_DECREF(reversed_meth);
     256           1 :         return res;
     257             :     }
     258         187 :     else if (PyErr_Occurred())
     259           0 :         return NULL;
     260             : 
     261         187 :     if (!PySequence_Check(seq)) {
     262           0 :         PyErr_SetString(PyExc_TypeError,
     263             :                         "argument to reversed() must be a sequence");
     264           0 :         return NULL;
     265             :     }
     266             : 
     267         187 :     n = PySequence_Size(seq);
     268         187 :     if (n == -1)
     269           0 :         return NULL;
     270             : 
     271         187 :     ro = (reversedobject *)type->tp_alloc(type, 0);
     272         187 :     if (ro == NULL)
     273           0 :         return NULL;
     274             : 
     275         187 :     ro->index = n-1;
     276         187 :     Py_INCREF(seq);
     277         187 :     ro->seq = seq;
     278         187 :     return (PyObject *)ro;
     279             : }
     280             : 
     281             : static void
     282         187 : reversed_dealloc(reversedobject *ro)
     283             : {
     284         187 :     PyObject_GC_UnTrack(ro);
     285         187 :     Py_XDECREF(ro->seq);
     286         187 :     Py_TYPE(ro)->tp_free(ro);
     287         187 : }
     288             : 
     289             : static int
     290           0 : reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
     291             : {
     292           0 :     Py_VISIT(ro->seq);
     293           0 :     return 0;
     294             : }
     295             : 
     296             : static PyObject *
     297        2289 : reversed_next(reversedobject *ro)
     298             : {
     299             :     PyObject *item;
     300        2289 :     Py_ssize_t index = ro->index;
     301             : 
     302        2289 :     if (index >= 0) {
     303        2289 :         item = PySequence_GetItem(ro->seq, index);
     304        2289 :         if (item != NULL) {
     305        2289 :             ro->index--;
     306        2289 :             return item;
     307             :         }
     308           0 :         if (PyErr_ExceptionMatches(PyExc_IndexError) ||
     309           0 :             PyErr_ExceptionMatches(PyExc_StopIteration))
     310           0 :             PyErr_Clear();
     311             :     }
     312           0 :     ro->index = -1;
     313           0 :     Py_CLEAR(ro->seq);
     314           0 :     return NULL;
     315             : }
     316             : 
     317             : PyDoc_STRVAR(reversed_doc,
     318             : "reversed(sequence) -> reverse iterator over values of the sequence\n"
     319             : "\n"
     320             : "Return a reverse iterator");
     321             : 
     322             : static PyObject *
     323           0 : reversed_len(reversedobject *ro)
     324             : {
     325             :     Py_ssize_t position, seqsize;
     326             : 
     327           0 :     if (ro->seq == NULL)
     328           0 :         return PyLong_FromLong(0);
     329           0 :     seqsize = PySequence_Size(ro->seq);
     330           0 :     if (seqsize == -1)
     331           0 :         return NULL;
     332           0 :     position = ro->index + 1;
     333           0 :     return PyLong_FromSsize_t((seqsize < position)  ?  0  :  position);
     334             : }
     335             : 
     336             : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
     337             : 
     338             : static PyObject *
     339           0 : reversed_reduce(reversedobject *ro)
     340             : {
     341           0 :     if (ro->seq)
     342           0 :         return Py_BuildValue("O(O)n", Py_TYPE(ro), ro->seq, ro->index);
     343             :     else
     344           0 :         return Py_BuildValue("O(())", Py_TYPE(ro));
     345             : }
     346             : 
     347             : static PyObject *
     348           0 : reversed_setstate(reversedobject *ro, PyObject *state)
     349             : {
     350           0 :     Py_ssize_t index = PyLong_AsSsize_t(state);
     351           0 :     if (index == -1 && PyErr_Occurred())
     352           0 :         return NULL;
     353           0 :     if (ro->seq != 0) {
     354           0 :         Py_ssize_t n = PySequence_Size(ro->seq);
     355           0 :         if (n < 0)
     356           0 :             return NULL;
     357           0 :         if (index < -1)
     358           0 :             index = -1;
     359           0 :         else if (index > n-1)
     360           0 :             index = n-1;
     361           0 :         ro->index = index;
     362             :     }
     363           0 :     Py_RETURN_NONE;
     364             : }
     365             : 
     366             : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
     367             : 
     368             : static PyMethodDef reversediter_methods[] = {
     369             :     {"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},
     370             :     {"__reduce__", (PyCFunction)reversed_reduce, METH_NOARGS, reduce_doc},
     371             :     {"__setstate__", (PyCFunction)reversed_setstate, METH_O, setstate_doc},
     372             :     {NULL,              NULL}           /* sentinel */
     373             : };
     374             : 
     375             : PyTypeObject PyReversed_Type = {
     376             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     377             :     "reversed",                     /* tp_name */
     378             :     sizeof(reversedobject),         /* tp_basicsize */
     379             :     0,                              /* tp_itemsize */
     380             :     /* methods */
     381             :     (destructor)reversed_dealloc,   /* tp_dealloc */
     382             :     0,                              /* tp_print */
     383             :     0,                              /* tp_getattr */
     384             :     0,                              /* tp_setattr */
     385             :     0,                              /* tp_reserved */
     386             :     0,                              /* tp_repr */
     387             :     0,                              /* tp_as_number */
     388             :     0,                                  /* tp_as_sequence */
     389             :     0,                              /* tp_as_mapping */
     390             :     0,                              /* tp_hash */
     391             :     0,                              /* tp_call */
     392             :     0,                              /* tp_str */
     393             :     PyObject_GenericGetAttr,        /* tp_getattro */
     394             :     0,                              /* tp_setattro */
     395             :     0,                              /* tp_as_buffer */
     396             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
     397             :         Py_TPFLAGS_BASETYPE,    /* tp_flags */
     398             :     reversed_doc,                   /* tp_doc */
     399             :     (traverseproc)reversed_traverse,/* tp_traverse */
     400             :     0,                              /* tp_clear */
     401             :     0,                              /* tp_richcompare */
     402             :     0,                              /* tp_weaklistoffset */
     403             :     PyObject_SelfIter,                  /* tp_iter */
     404             :     (iternextfunc)reversed_next,    /* tp_iternext */
     405             :     reversediter_methods,               /* tp_methods */
     406             :     0,                              /* tp_members */
     407             :     0,                              /* tp_getset */
     408             :     0,                              /* tp_base */
     409             :     0,                              /* tp_dict */
     410             :     0,                              /* tp_descr_get */
     411             :     0,                              /* tp_descr_set */
     412             :     0,                              /* tp_dictoffset */
     413             :     0,                              /* tp_init */
     414             :     PyType_GenericAlloc,            /* tp_alloc */
     415             :     reversed_new,                   /* tp_new */
     416             :     PyObject_GC_Del,                /* tp_free */
     417             : };

Generated by: LCOV version 1.10