1313 tokenizing. */
1414static const char * type_comment_prefix = "# type: " ;
1515
16- static inline int
17- contains_null_bytes (const char * str , size_t size )
18- {
19- return memchr (str , 0 , size ) != NULL ;
20- }
21-
2216int
2317_PyLexer_refill (struct tok_state * tok )
2418{
@@ -29,8 +23,9 @@ _PyLexer_refill(struct tok_state *tok)
2923#if defined(Py_DEBUG )
3024 if (tok -> debug ) {
3125 fprintf (stderr , "line[%d] = " , tok -> lineno );
32- _PyTokenizer_print_escape (stderr , _PyLexer_BufferPointer (tok , tok -> cur ),
33- tok -> inp - tok -> cur );
26+ _PyTokenizer_print_escape (
27+ stderr , _PyTok_SourcePointer (& tok -> source , tok -> cur ),
28+ tok -> inp - tok -> cur );
3429 fprintf (stderr , " tok->done = %d\n" , tok -> done );
3530 }
3631#endif
@@ -39,8 +34,8 @@ _PyLexer_refill(struct tok_state *tok)
3934 return 0 ;
4035 }
4136 tok -> line_start = tok -> cur ;
42- if ( contains_null_bytes ( _PyLexer_BufferPointer ( tok , tok -> line_start ),
43- tok -> inp - tok -> line_start ) ) {
37+ _PyTok_Span line = { tok -> line_start , tok -> inp };
38+ if ( _PyTok_SourceFindByte ( & tok -> source , line , '\0' ) >= 0 ) {
4439 _PyTokenizer_syntaxerror (tok , "source code cannot contain null bytes" );
4540 tok -> cur = tok -> inp ;
4641 return 0 ;
@@ -56,7 +51,7 @@ _PyLexer_backup(struct tok_state *tok, int c)
5651 if (-- tok -> cur < tok -> buf_offset ) {
5752 Py_FatalError ("tokenizer beginning of buffer" );
5853 }
59- if (( int )( unsigned char ) * _PyLexer_BufferPointer ( tok , tok -> cur ) != Py_CHARMASK (c )) {
54+ if (_PyTok_SourceByte ( & tok -> source , tok -> cur ) != Py_CHARMASK (c )) {
6055 Py_FatalError ("tok_backup: wrong character" );
6156 }
6257 }
@@ -74,7 +69,8 @@ verify_identifier(struct tok_state *tok)
7469 PyObject * s ;
7570 if (tok_failed (tok ))
7671 return 0 ;
77- s = PyUnicode_DecodeUTF8 (_PyLexer_BufferPointer (tok , tok -> start ), tok -> cur - tok -> start , NULL );
72+ s = PyUnicode_DecodeUTF8 (_PyTok_SourcePointer (& tok -> source , tok -> start ),
73+ tok -> cur - tok -> start , NULL );
7874 if (s == NULL ) {
7975 if (PyErr_ExceptionMatches (PyExc_UnicodeDecodeError )) {
8076 tok -> done = E_DECODE ;
@@ -105,13 +101,13 @@ verify_identifier(struct tok_state *tok)
105101 Py_DECREF (s );
106102 if (Py_UNICODE_ISPRINTABLE (ch )) {
107103 _PyTokenizer_syntaxerror_at (
108- tok , _PyLexer_BufferPointer ( tok , tok -> line_start ),
104+ tok , _PyTok_SourcePointer ( & tok -> source , tok -> line_start ),
109105 error_cursor - tok -> line_start , tok -> lineno , -1 , -1 ,
110106 "invalid character '%c' (U+%04X)" , ch , ch );
111107 }
112108 else {
113109 _PyTokenizer_syntaxerror_at (
114- tok , _PyLexer_BufferPointer ( tok , tok -> line_start ),
110+ tok , _PyTok_SourcePointer ( & tok -> source , tok -> line_start ),
115111 error_cursor - tok -> line_start , tok -> lineno , -1 , -1 ,
116112 "invalid non-printable character U+%04X" , ch );
117113 }
@@ -172,10 +168,6 @@ _PyLexer_get_normal(struct tok_state *tok, ftstring_state *current, struct token
172168 /* Skip comment, unless it's a type comment */
173169 if (c == '#' ) {
174170
175- const char * p = NULL ;
176- const char * prefix , * type_start ;
177- int current_starting_col_offset ;
178-
179171 while (c != EOF && c != '\n' && c != '\r' ) {
180172 c = tok_nextc (tok );
181173 }
@@ -192,23 +184,20 @@ _PyLexer_get_normal(struct tok_state *tok, ftstring_state *current, struct token
192184 }
193185 }
194186
195- if (tok -> tok_extra_tokens ) {
196- p = _PyLexer_BufferPointer (tok , tok -> start );
197- }
198-
187+ _PyTok_Off comment = tok -> start ;
199188 if (tok -> type_comments ) {
200- p = _PyLexer_BufferPointer (tok , tok -> start );
201- current_starting_col_offset = tok -> start_loc .byte_col ;
202- prefix = type_comment_prefix ;
203- while (* prefix && p < _PyLexer_BufferPointer (tok , tok -> cur )) {
189+ const char * prefix = type_comment_prefix ;
190+ while (* prefix && comment < tok -> cur ) {
204191 if (* prefix == ' ' ) {
205- while (* p == ' ' || * p == '\t' ) {
206- p ++ ;
207- current_starting_col_offset ++ ;
192+ while (comment < tok -> cur ) {
193+ int ch = _PyTok_SourceByte (& tok -> source , comment );
194+ if (ch != ' ' && ch != '\t' ) {
195+ break ;
196+ }
197+ comment ++ ;
208198 }
209- } else if (* prefix == * p ) {
210- p ++ ;
211- current_starting_col_offset ++ ;
199+ } else if (* prefix == _PyTok_SourceByte (& tok -> source , comment )) {
200+ comment ++ ;
212201 } else {
213202 break ;
214203 }
@@ -218,35 +207,26 @@ _PyLexer_get_normal(struct tok_state *tok, ftstring_state *current, struct token
218207
219208 /* This is a type comment if we matched all of type_comment_prefix. */
220209 if (!* prefix ) {
221- int is_type_ignore = 1 ;
222- // +6 in order to skip the word 'ignore'
223- const char * ignore_end = p + 6 ;
224- const int ignore_end_col_offset = current_starting_col_offset + 6 ;
225210 tok_backup (tok , c ); /* don't eat the newline or EOF */
226-
227- type_start = p ;
228-
229211 /* A TYPE_IGNORE is "type: ignore" followed by the end of the token
230212 * or anything ASCII and non-alphanumeric. */
231- is_type_ignore = (
232- _PyLexer_BufferPointer (tok , tok -> cur ) >= ignore_end && memcmp (p , "ignore" , 6 ) == 0
233- && !(_PyLexer_BufferPointer (tok , tok -> cur ) > ignore_end
234- && ((unsigned char )ignore_end [0 ] >= 128 || Py_ISALNUM (ignore_end [0 ]))));
213+ int is_type_ignore = tok -> cur - comment >= 6 &&
214+ memcmp (_PyTok_SourcePointer (& tok -> source , comment ),
215+ "ignore" , 6 ) == 0 ;
216+ if (is_type_ignore && comment + 6 < tok -> cur ) {
217+ int ch = _PyTok_SourceByte (& tok -> source , comment + 6 );
218+ is_type_ignore = ch < 128 && !Py_ISALNUM (ch );
219+ }
235220
236221 int type = is_type_ignore ? TYPE_IGNORE : TYPE_COMMENT ;
237- int start_col_offset = is_type_ignore
238- ? ignore_end_col_offset : current_starting_col_offset ;
222+ p_start = comment + (is_type_ignore ? 6 : 0 );
239223 p_end = tok -> cur ;
240- if (is_type_ignore ) {
241- p_start = _PyLexer_BufferOffset (tok , ignore_end );
242-
243- /* If this type ignore is the only thing on the line, consume the newline also. */
244- if (blankline ) {
245- tok_nextc (tok );
246- tok -> layout .at_bol = 1 ;
247- }
248- } else {
249- p_start = _PyLexer_BufferOffset (tok , type_start );
224+ int start_col_offset = tok -> start_loc .byte_col +
225+ (int )(p_start - tok -> start );
226+ /* Consume the newline after a standalone type ignore. */
227+ if (is_type_ignore && blankline ) {
228+ tok_nextc (tok );
229+ tok -> layout .at_bol = 1 ;
250230 }
251231 _PyLexer_token_setup (tok , token , type , p_start , p_end );
252232 token -> start_loc = (_PyTok_Loc ){tok -> lineno , start_col_offset };
@@ -257,7 +237,7 @@ _PyLexer_get_normal(struct tok_state *tok, ftstring_state *current, struct token
257237 }
258238 if (tok -> tok_extra_tokens ) {
259239 tok_backup (tok , c ); /* don't eat the newline or EOF */
260- p_start = _PyLexer_BufferOffset ( tok , p ) ;
240+ p_start = comment ;
261241 p_end = tok -> cur ;
262242 tok -> layout .comment_newline = blankline ;
263243 return MAKE_TOKEN (COMMENT );
0 commit comments