LCOV - code coverage report
Current view: top level - Python - Python-tokenize.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 62 72 86.1 %
Date: 2022-07-20 13:12:14 Functions: 9 9 100.0 %
Branches: 31 46 67.4 %

           Branch data     Line data    Source code
       1                 :            : #include "Python.h"
       2                 :            : #include "../Parser/tokenizer.h"
       3                 :            : 
       4                 :            : static struct PyModuleDef _tokenizemodule;
       5                 :            : 
       6                 :            : typedef struct {
       7                 :            :     PyTypeObject *TokenizerIter;
       8                 :            : } tokenize_state;
       9                 :            : 
      10                 :            : static tokenize_state *
      11                 :        337 : get_tokenize_state(PyObject *module) {
      12                 :        337 :     return (tokenize_state *)PyModule_GetState(module);
      13                 :            : }
      14                 :            : 
      15                 :            : #define _tokenize_get_state_by_type(type) \
      16                 :            :     get_tokenize_state(PyType_GetModuleByDef(type, &_tokenizemodule))
      17                 :            : 
      18                 :            : #include "clinic/Python-tokenize.c.h"
      19                 :            : 
      20                 :            : /*[clinic input]
      21                 :            : module _tokenizer
      22                 :            : class _tokenizer.tokenizeriter "tokenizeriterobject *" "_tokenize_get_state_by_type(type)->TokenizerIter"
      23                 :            : [clinic start generated code]*/
      24                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=96d98ee2fef7a8bc]*/
      25                 :            : 
      26                 :            : typedef struct
      27                 :            : {
      28                 :            :     PyObject_HEAD struct tok_state *tok;
      29                 :            : } tokenizeriterobject;
      30                 :            : 
      31                 :            : /*[clinic input]
      32                 :            : @classmethod
      33                 :            : _tokenizer.tokenizeriter.__new__ as tokenizeriter_new
      34                 :            : 
      35                 :            :     source: str
      36                 :            : [clinic start generated code]*/
      37                 :            : 
      38                 :            : static PyObject *
      39                 :        114 : tokenizeriter_new_impl(PyTypeObject *type, const char *source)
      40                 :            : /*[clinic end generated code: output=7fd9f46cf9263cbb input=4384b368407375c6]*/
      41                 :            : {
      42                 :        114 :     tokenizeriterobject *self = (tokenizeriterobject *)type->tp_alloc(type, 0);
      43         [ -  + ]:        114 :     if (self == NULL) {
      44                 :          0 :         return NULL;
      45                 :            :     }
      46                 :        114 :     PyObject *filename = PyUnicode_FromString("<string>");
      47         [ -  + ]:        114 :     if (filename == NULL) {
      48                 :          0 :         return NULL;
      49                 :            :     }
      50                 :        114 :     self->tok = _PyTokenizer_FromUTF8(source, 1);
      51         [ -  + ]:        114 :     if (self->tok == NULL) {
      52                 :          0 :         Py_DECREF(filename);
      53                 :          0 :         return NULL;
      54                 :            :     }
      55                 :        114 :     self->tok->filename = filename;
      56                 :        114 :     return (PyObject *)self;
      57                 :            : }
      58                 :            : 
      59                 :            : static PyObject *
      60                 :       1045 : tokenizeriter_next(tokenizeriterobject *it)
      61                 :            : {
      62                 :            :     const char *start;
      63                 :            :     const char *end;
      64                 :       1045 :     int type = _PyTokenizer_Get(it->tok, &start, &end);
      65   [ +  +  +  - ]:       1045 :     if (type == ERRORTOKEN && PyErr_Occurred()) {
      66                 :         30 :         return NULL;
      67                 :            :     }
      68   [ +  -  +  + ]:       1015 :     if (type == ERRORTOKEN || type == ENDMARKER) {
      69                 :         84 :         PyErr_SetString(PyExc_StopIteration, "EOF");
      70                 :         84 :         return NULL;
      71                 :            :     }
      72                 :        931 :     PyObject *str = NULL;
      73   [ +  +  -  + ]:        931 :     if (start == NULL || end == NULL) {
      74                 :         24 :         str = PyUnicode_FromString("");
      75                 :            :     }
      76                 :            :     else {
      77                 :        907 :         str = PyUnicode_FromStringAndSize(start, end - start);
      78                 :            :     }
      79         [ -  + ]:        931 :     if (str == NULL) {
      80                 :          0 :         return NULL;
      81                 :            :     }
      82                 :            : 
      83                 :        931 :     Py_ssize_t size = it->tok->inp - it->tok->buf;
      84                 :        931 :     PyObject *line = PyUnicode_DecodeUTF8(it->tok->buf, size, "replace");
      85         [ -  + ]:        931 :     if (line == NULL) {
      86                 :          0 :         Py_DECREF(str);
      87                 :          0 :         return NULL;
      88                 :            :     }
      89         [ +  + ]:        931 :     const char *line_start = type == STRING ? it->tok->multi_line_start : it->tok->line_start;
      90         [ +  + ]:        931 :     int lineno = type == STRING ? it->tok->first_lineno : it->tok->lineno;
      91                 :        931 :     int end_lineno = it->tok->lineno;
      92                 :        931 :     int col_offset = -1;
      93                 :        931 :     int end_col_offset = -1;
      94   [ +  +  +  - ]:        931 :     if (start != NULL && start >= line_start) {
      95                 :        907 :         col_offset = (int)(start - line_start);
      96                 :            :     }
      97   [ +  +  +  - ]:        931 :     if (end != NULL && end >= it->tok->line_start) {
      98                 :        907 :         end_col_offset = (int)(end - it->tok->line_start);
      99                 :            :     }
     100                 :            : 
     101                 :        931 :     return Py_BuildValue("(NiiiiiN)", str, type, lineno, end_lineno, col_offset, end_col_offset, line);
     102                 :            : }
     103                 :            : 
     104                 :            : static void
     105                 :        114 : tokenizeriter_dealloc(tokenizeriterobject *it)
     106                 :            : {
     107                 :        114 :     PyTypeObject *tp = Py_TYPE(it);
     108                 :        114 :     _PyTokenizer_Free(it->tok);
     109                 :        114 :     tp->tp_free(it);
     110                 :        114 :     Py_DECREF(tp);
     111                 :        114 : }
     112                 :            : 
     113                 :            : static PyType_Slot tokenizeriter_slots[] = {
     114                 :            :     {Py_tp_new, tokenizeriter_new},
     115                 :            :     {Py_tp_dealloc, tokenizeriter_dealloc},
     116                 :            :     {Py_tp_getattro, PyObject_GenericGetAttr},
     117                 :            :     {Py_tp_iter, PyObject_SelfIter},
     118                 :            :     {Py_tp_iternext, tokenizeriter_next},
     119                 :            :     {0, NULL},
     120                 :            : };
     121                 :            : 
     122                 :            : static PyType_Spec tokenizeriter_spec = {
     123                 :            :     .name = "_tokenize.TokenizerIter",
     124                 :            :     .basicsize = sizeof(tokenizeriterobject),
     125                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
     126                 :            :     .slots = tokenizeriter_slots,
     127                 :            : };
     128                 :            : 
     129                 :            : static int
     130                 :          3 : tokenizemodule_exec(PyObject *m)
     131                 :            : {
     132                 :          3 :     tokenize_state *state = get_tokenize_state(m);
     133         [ -  + ]:          3 :     if (state == NULL) {
     134                 :          0 :         return -1;
     135                 :            :     }
     136                 :            : 
     137                 :          3 :     state->TokenizerIter = (PyTypeObject *)PyType_FromModuleAndSpec(m, &tokenizeriter_spec, NULL);
     138         [ -  + ]:          3 :     if (state->TokenizerIter == NULL) {
     139                 :          0 :         return -1;
     140                 :            :     }
     141         [ -  + ]:          3 :     if (PyModule_AddType(m, state->TokenizerIter) < 0) {
     142                 :          0 :         return -1;
     143                 :            :     }
     144                 :            : 
     145                 :          3 :     return 0;
     146                 :            : }
     147                 :            : 
     148                 :            : static PyMethodDef tokenize_methods[] = {
     149                 :            :     {NULL, NULL, 0, NULL} /* Sentinel */
     150                 :            : };
     151                 :            : 
     152                 :            : static PyModuleDef_Slot tokenizemodule_slots[] = {
     153                 :            :     {Py_mod_exec, tokenizemodule_exec},
     154                 :            :     {0, NULL}
     155                 :            : };
     156                 :            : 
     157                 :            : static int
     158                 :        328 : tokenizemodule_traverse(PyObject *m, visitproc visit, void *arg)
     159                 :            : {
     160                 :        328 :     tokenize_state *state = get_tokenize_state(m);
     161   [ +  -  -  + ]:        328 :     Py_VISIT(state->TokenizerIter);
     162                 :        328 :     return 0;
     163                 :            : }
     164                 :            : 
     165                 :            : static int
     166                 :          6 : tokenizemodule_clear(PyObject *m)
     167                 :            : {
     168                 :          6 :     tokenize_state *state = get_tokenize_state(m);
     169         [ +  + ]:          6 :     Py_CLEAR(state->TokenizerIter);
     170                 :          6 :     return 0;
     171                 :            : }
     172                 :            : 
     173                 :            : static void
     174                 :          3 : tokenizemodule_free(void *m)
     175                 :            : {
     176                 :          3 :     tokenizemodule_clear((PyObject *)m);
     177                 :          3 : }
     178                 :            : 
     179                 :            : static struct PyModuleDef _tokenizemodule = {
     180                 :            :     PyModuleDef_HEAD_INIT,
     181                 :            :     .m_name = "_tokenize",
     182                 :            :     .m_size = sizeof(tokenize_state),
     183                 :            :     .m_slots = tokenizemodule_slots,
     184                 :            :     .m_methods = tokenize_methods,
     185                 :            :     .m_traverse = tokenizemodule_traverse,
     186                 :            :     .m_clear = tokenizemodule_clear,
     187                 :            :     .m_free = tokenizemodule_free,
     188                 :            : };
     189                 :            : 
     190                 :            : PyMODINIT_FUNC
     191                 :          3 : PyInit__tokenize(void)
     192                 :            : {
     193                 :          3 :     return PyModuleDef_Init(&_tokenizemodule);
     194                 :            : }

Generated by: LCOV version 1.14