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 : 9 : get_tokenize_state(PyObject *module) {
12 : 9 : 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 "pycore_runtime.h"
19 : : #include "clinic/Python-tokenize.c.h"
20 : :
21 : : /*[clinic input]
22 : : module _tokenizer
23 : : class _tokenizer.tokenizeriter "tokenizeriterobject *" "_tokenize_get_state_by_type(type)->TokenizerIter"
24 : : [clinic start generated code]*/
25 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=96d98ee2fef7a8bc]*/
26 : :
27 : : typedef struct
28 : : {
29 : : PyObject_HEAD struct tok_state *tok;
30 : : } tokenizeriterobject;
31 : :
32 : : /*[clinic input]
33 : : @classmethod
34 : : _tokenizer.tokenizeriter.__new__ as tokenizeriter_new
35 : :
36 : : source: str
37 : : [clinic start generated code]*/
38 : :
39 : : static PyObject *
40 : 0 : tokenizeriter_new_impl(PyTypeObject *type, const char *source)
41 : : /*[clinic end generated code: output=7fd9f46cf9263cbb input=4384b368407375c6]*/
42 : : {
43 : 0 : tokenizeriterobject *self = (tokenizeriterobject *)type->tp_alloc(type, 0);
44 [ # # ]: 0 : if (self == NULL) {
45 : 0 : return NULL;
46 : : }
47 : 0 : PyObject *filename = PyUnicode_FromString("<string>");
48 [ # # ]: 0 : if (filename == NULL) {
49 : 0 : return NULL;
50 : : }
51 : 0 : self->tok = _PyTokenizer_FromUTF8(source, 1);
52 [ # # ]: 0 : if (self->tok == NULL) {
53 : 0 : Py_DECREF(filename);
54 : 0 : return NULL;
55 : : }
56 : 0 : self->tok->filename = filename;
57 : 0 : return (PyObject *)self;
58 : : }
59 : :
60 : : static PyObject *
61 : 0 : tokenizeriter_next(tokenizeriterobject *it)
62 : : {
63 : : struct token token;
64 : 0 : int type = _PyTokenizer_Get(it->tok, &token);
65 [ # # # # ]: 0 : if (type == ERRORTOKEN && PyErr_Occurred()) {
66 : 0 : return NULL;
67 : : }
68 [ # # # # ]: 0 : if (type == ERRORTOKEN || type == ENDMARKER) {
69 : 0 : PyErr_SetString(PyExc_StopIteration, "EOF");
70 : 0 : return NULL;
71 : : }
72 : 0 : PyObject *str = NULL;
73 [ # # # # ]: 0 : if (token.start == NULL || token.end == NULL) {
74 : 0 : str = PyUnicode_FromString("");
75 : : }
76 : : else {
77 : 0 : str = PyUnicode_FromStringAndSize(token.start, token.end - token.start);
78 : : }
79 [ # # ]: 0 : if (str == NULL) {
80 : 0 : return NULL;
81 : : }
82 : :
83 : 0 : Py_ssize_t size = it->tok->inp - it->tok->buf;
84 : 0 : PyObject *line = PyUnicode_DecodeUTF8(it->tok->buf, size, "replace");
85 [ # # ]: 0 : if (line == NULL) {
86 : 0 : Py_DECREF(str);
87 : 0 : return NULL;
88 : : }
89 [ # # ]: 0 : const char *line_start = type == STRING ? it->tok->multi_line_start : it->tok->line_start;
90 [ # # ]: 0 : int lineno = type == STRING ? it->tok->first_lineno : it->tok->lineno;
91 : 0 : int end_lineno = it->tok->lineno;
92 : 0 : int col_offset = -1;
93 : 0 : int end_col_offset = -1;
94 [ # # # # ]: 0 : if (token.start != NULL && token.start >= line_start) {
95 : 0 : col_offset = (int)(token.start - line_start);
96 : : }
97 [ # # # # ]: 0 : if (token.end != NULL && token.end >= it->tok->line_start) {
98 : 0 : end_col_offset = (int)(token.end - it->tok->line_start);
99 : : }
100 : :
101 : 0 : return Py_BuildValue("(NiiiiiN)", str, type, lineno, end_lineno, col_offset, end_col_offset, line);
102 : : }
103 : :
104 : : static void
105 : 0 : tokenizeriter_dealloc(tokenizeriterobject *it)
106 : : {
107 : 0 : PyTypeObject *tp = Py_TYPE(it);
108 : 0 : _PyTokenizer_Free(it->tok);
109 : 0 : tp->tp_free(it);
110 : 0 : Py_DECREF(tp);
111 : 0 : }
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 : 1 : tokenizemodule_exec(PyObject *m)
131 : : {
132 : 1 : tokenize_state *state = get_tokenize_state(m);
133 [ - + ]: 1 : if (state == NULL) {
134 : 0 : return -1;
135 : : }
136 : :
137 : 1 : state->TokenizerIter = (PyTypeObject *)PyType_FromModuleAndSpec(m, &tokenizeriter_spec, NULL);
138 [ - + ]: 1 : if (state->TokenizerIter == NULL) {
139 : 0 : return -1;
140 : : }
141 [ - + ]: 1 : if (PyModule_AddType(m, state->TokenizerIter) < 0) {
142 : 0 : return -1;
143 : : }
144 : :
145 : 1 : 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 : 6 : tokenizemodule_traverse(PyObject *m, visitproc visit, void *arg)
159 : : {
160 : 6 : tokenize_state *state = get_tokenize_state(m);
161 [ + - - + ]: 6 : Py_VISIT(state->TokenizerIter);
162 : 6 : return 0;
163 : : }
164 : :
165 : : static int
166 : 2 : tokenizemodule_clear(PyObject *m)
167 : : {
168 : 2 : tokenize_state *state = get_tokenize_state(m);
169 [ + + ]: 2 : Py_CLEAR(state->TokenizerIter);
170 : 2 : return 0;
171 : : }
172 : :
173 : : static void
174 : 1 : tokenizemodule_free(void *m)
175 : : {
176 : 1 : tokenizemodule_clear((PyObject *)m);
177 : 1 : }
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 : 1 : PyInit__tokenize(void)
192 : : {
193 : 1 : return PyModuleDef_Init(&_tokenizemodule);
194 : : }
|