LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Objects - iterobject.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 56 101 55.4 %
Date: 2012-12-17 Functions: 6 12 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Iterator objects */
       2             : 
       3             : #include "Python.h"
       4             : 
       5             : typedef struct {
       6             :     PyObject_HEAD
       7             :     long      it_index;
       8             :     PyObject *it_seq; /* Set to NULL when iterator is exhausted */
       9             : } seqiterobject;
      10             : 
      11             : PyObject *
      12         586 : PySeqIter_New(PyObject *seq)
      13             : {
      14             :     seqiterobject *it;
      15             : 
      16         586 :     if (!PySequence_Check(seq)) {
      17           0 :         PyErr_BadInternalCall();
      18           0 :         return NULL;
      19             :     }
      20         586 :     it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
      21         586 :     if (it == NULL)
      22           0 :         return NULL;
      23         586 :     it->it_index = 0;
      24         586 :     Py_INCREF(seq);
      25         586 :     it->it_seq = seq;
      26         586 :     _PyObject_GC_TRACK(it);
      27         586 :     return (PyObject *)it;
      28             : }
      29             : 
      30             : static void
      31         586 : iter_dealloc(seqiterobject *it)
      32             : {
      33         586 :     _PyObject_GC_UNTRACK(it);
      34         586 :     Py_XDECREF(it->it_seq);
      35         586 :     PyObject_GC_Del(it);
      36         586 : }
      37             : 
      38             : static int
      39           0 : iter_traverse(seqiterobject *it, visitproc visit, void *arg)
      40             : {
      41           0 :     Py_VISIT(it->it_seq);
      42           0 :     return 0;
      43             : }
      44             : 
      45             : static PyObject *
      46        1568 : iter_iternext(PyObject *iterator)
      47             : {
      48             :     seqiterobject *it;
      49             :     PyObject *seq;
      50             :     PyObject *result;
      51             : 
      52             :     assert(PySeqIter_Check(iterator));
      53        1568 :     it = (seqiterobject *)iterator;
      54        1568 :     seq = it->it_seq;
      55        1568 :     if (seq == NULL)
      56           0 :         return NULL;
      57             : 
      58        1568 :     result = PySequence_GetItem(seq, it->it_index);
      59        1568 :     if (result != NULL) {
      60         982 :         it->it_index++;
      61         982 :         return result;
      62             :     }
      63         586 :     if (PyErr_ExceptionMatches(PyExc_IndexError) ||
      64           0 :         PyErr_ExceptionMatches(PyExc_StopIteration))
      65             :     {
      66         586 :         PyErr_Clear();
      67         586 :         Py_DECREF(seq);
      68         586 :         it->it_seq = NULL;
      69             :     }
      70         586 :     return NULL;
      71             : }
      72             : 
      73             : static PyObject *
      74           0 : iter_len(seqiterobject *it)
      75             : {
      76             :     Py_ssize_t seqsize, len;
      77             : 
      78           0 :     if (it->it_seq) {
      79           0 :         seqsize = PySequence_Size(it->it_seq);
      80           0 :         if (seqsize == -1)
      81           0 :             return NULL;
      82           0 :         len = seqsize - it->it_index;
      83           0 :         if (len >= 0)
      84           0 :             return PyLong_FromSsize_t(len);
      85             :     }
      86           0 :     return PyLong_FromLong(0);
      87             : }
      88             : 
      89             : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
      90             : 
      91             : static PyObject *
      92           0 : iter_reduce(seqiterobject *it)
      93             : {
      94           0 :     if (it->it_seq != NULL)
      95           0 :         return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
      96             :                              it->it_seq, it->it_index);
      97             :     else
      98           0 :         return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
      99             : }
     100             : 
     101             : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
     102             : 
     103             : static PyObject *
     104           0 : iter_setstate(seqiterobject *it, PyObject *state)
     105             : {
     106           0 :     Py_ssize_t index = PyLong_AsSsize_t(state);
     107           0 :     if (index == -1 && PyErr_Occurred())
     108           0 :         return NULL;
     109           0 :     if (it->it_seq != NULL) {
     110           0 :         if (index < 0)
     111           0 :             index = 0;
     112           0 :         it->it_index = index;
     113             :     }
     114           0 :     Py_RETURN_NONE;
     115             : }
     116             : 
     117             : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
     118             : 
     119             : static PyMethodDef seqiter_methods[] = {
     120             :     {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},
     121             :     {"__reduce__", (PyCFunction)iter_reduce, METH_NOARGS, reduce_doc},
     122             :     {"__setstate__", (PyCFunction)iter_setstate, METH_O, setstate_doc},
     123             :     {NULL,              NULL}           /* sentinel */
     124             : };
     125             : 
     126             : PyTypeObject PySeqIter_Type = {
     127             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     128             :     "iterator",                                 /* tp_name */
     129             :     sizeof(seqiterobject),                      /* tp_basicsize */
     130             :     0,                                          /* tp_itemsize */
     131             :     /* methods */
     132             :     (destructor)iter_dealloc,                   /* tp_dealloc */
     133             :     0,                                          /* tp_print */
     134             :     0,                                          /* tp_getattr */
     135             :     0,                                          /* tp_setattr */
     136             :     0,                                          /* tp_reserved */
     137             :     0,                                          /* tp_repr */
     138             :     0,                                          /* tp_as_number */
     139             :     0,                                          /* tp_as_sequence */
     140             :     0,                                          /* tp_as_mapping */
     141             :     0,                                          /* tp_hash */
     142             :     0,                                          /* tp_call */
     143             :     0,                                          /* tp_str */
     144             :     PyObject_GenericGetAttr,                    /* tp_getattro */
     145             :     0,                                          /* tp_setattro */
     146             :     0,                                          /* tp_as_buffer */
     147             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
     148             :     0,                                          /* tp_doc */
     149             :     (traverseproc)iter_traverse,                /* tp_traverse */
     150             :     0,                                          /* tp_clear */
     151             :     0,                                          /* tp_richcompare */
     152             :     0,                                          /* tp_weaklistoffset */
     153             :     PyObject_SelfIter,                          /* tp_iter */
     154             :     iter_iternext,                              /* tp_iternext */
     155             :     seqiter_methods,                            /* tp_methods */
     156             :     0,                                          /* tp_members */
     157             : };
     158             : 
     159             : /* -------------------------------------- */
     160             : 
     161             : typedef struct {
     162             :     PyObject_HEAD
     163             :     PyObject *it_callable; /* Set to NULL when iterator is exhausted */
     164             :     PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
     165             : } calliterobject;
     166             : 
     167             : PyObject *
     168        1890 : PyCallIter_New(PyObject *callable, PyObject *sentinel)
     169             : {
     170             :     calliterobject *it;
     171        1890 :     it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
     172        1890 :     if (it == NULL)
     173           0 :         return NULL;
     174        1890 :     Py_INCREF(callable);
     175        1890 :     it->it_callable = callable;
     176        1890 :     Py_INCREF(sentinel);
     177        1890 :     it->it_sentinel = sentinel;
     178        1890 :     _PyObject_GC_TRACK(it);
     179        1890 :     return (PyObject *)it;
     180             : }
     181             : static void
     182        1890 : calliter_dealloc(calliterobject *it)
     183             : {
     184        1890 :     _PyObject_GC_UNTRACK(it);
     185        1890 :     Py_XDECREF(it->it_callable);
     186        1890 :     Py_XDECREF(it->it_sentinel);
     187        1890 :     PyObject_GC_Del(it);
     188        1890 : }
     189             : 
     190             : static int
     191           0 : calliter_traverse(calliterobject *it, visitproc visit, void *arg)
     192             : {
     193           0 :     Py_VISIT(it->it_callable);
     194           0 :     Py_VISIT(it->it_sentinel);
     195           0 :     return 0;
     196             : }
     197             : 
     198             : static PyObject *
     199        1890 : calliter_iternext(calliterobject *it)
     200             : {
     201        1890 :     if (it->it_callable != NULL) {
     202        1890 :         PyObject *args = PyTuple_New(0);
     203             :         PyObject *result;
     204        1890 :         if (args == NULL)
     205           0 :             return NULL;
     206        1890 :         result = PyObject_Call(it->it_callable, args, NULL);
     207        1890 :         Py_DECREF(args);
     208        1890 :         if (result != NULL) {
     209             :             int ok;
     210        1890 :             ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ);               
     211        1890 :             if (ok == 0)
     212           0 :                 return result; /* Common case, fast path */
     213        1890 :             Py_DECREF(result);
     214        1890 :             if (ok > 0) {
     215        1890 :                 Py_CLEAR(it->it_callable);
     216        1890 :                 Py_CLEAR(it->it_sentinel);
     217             :             }
     218             :         }
     219           0 :         else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
     220           0 :             PyErr_Clear();
     221           0 :             Py_CLEAR(it->it_callable);
     222           0 :             Py_CLEAR(it->it_sentinel);
     223             :         }
     224             :     }
     225        1890 :     return NULL;
     226             : }
     227             : 
     228             : static PyObject *
     229           0 : calliter_reduce(calliterobject *it)
     230             : {
     231           0 :     if (it->it_callable != NULL && it->it_sentinel != NULL)
     232           0 :         return Py_BuildValue("N(OO)", _PyObject_GetBuiltin("iter"),
     233             :                              it->it_callable, it->it_sentinel);
     234             :     else
     235           0 :         return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
     236             : }
     237             : 
     238             : static PyMethodDef calliter_methods[] = {
     239             :     {"__reduce__", (PyCFunction)calliter_reduce, METH_NOARGS, reduce_doc},
     240             :     {NULL,              NULL}           /* sentinel */
     241             : };
     242             : 
     243             : PyTypeObject PyCallIter_Type = {
     244             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     245             :     "callable_iterator",                        /* tp_name */
     246             :     sizeof(calliterobject),                     /* tp_basicsize */
     247             :     0,                                          /* tp_itemsize */
     248             :     /* methods */
     249             :     (destructor)calliter_dealloc,               /* tp_dealloc */
     250             :     0,                                          /* tp_print */
     251             :     0,                                          /* tp_getattr */
     252             :     0,                                          /* tp_setattr */
     253             :     0,                                          /* tp_reserved */
     254             :     0,                                          /* tp_repr */
     255             :     0,                                          /* tp_as_number */
     256             :     0,                                          /* tp_as_sequence */
     257             :     0,                                          /* tp_as_mapping */
     258             :     0,                                          /* tp_hash */
     259             :     0,                                          /* tp_call */
     260             :     0,                                          /* tp_str */
     261             :     PyObject_GenericGetAttr,                    /* tp_getattro */
     262             :     0,                                          /* tp_setattro */
     263             :     0,                                          /* tp_as_buffer */
     264             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
     265             :     0,                                          /* tp_doc */
     266             :     (traverseproc)calliter_traverse,            /* tp_traverse */
     267             :     0,                                          /* tp_clear */
     268             :     0,                                          /* tp_richcompare */
     269             :     0,                                          /* tp_weaklistoffset */
     270             :     PyObject_SelfIter,                          /* tp_iter */
     271             :     (iternextfunc)calliter_iternext,            /* tp_iternext */
     272             :     calliter_methods,                           /* tp_methods */
     273             : };
     274             : 
     275             : 

Generated by: LCOV version 1.10