@@ -225,45 +225,23 @@ _PyPegen_raise_error(Parser *p, PyObject *errtype, int use_mark, const char *err
225225}
226226
227227static PyObject *
228- get_error_line_from_tokenizer_buffers (Parser * p , Py_ssize_t lineno )
228+ get_error_line_from_source (Parser * p , Py_ssize_t lineno )
229229{
230- /* If the file descriptor is interactive, the source lines of the current
231- * (multi-line) statement are stored in p->tok->interactive_src_start.
232- * If not, we're parsing from a string, which means that the whole source
233- * is stored in p->tok->str. */
234- assert ((p -> tok -> fp == NULL && p -> tok -> str != NULL ) || p -> tok -> fp != NULL );
235-
236- char * cur_line = p -> tok -> fp_interactive ? p -> tok -> interactive_src_start : p -> tok -> str ;
237- if (cur_line == NULL ) {
238- assert (p -> tok -> fp_interactive );
239- // We can reach this point if the tokenizer buffers for interactive source have not been
240- // initialized because we failed to decode the original source with the given locale.
241- return Py_GetConstant (Py_CONSTANT_EMPTY_STR );
242- }
230+ const char * cur_line = _PyTok_SourceData (& p -> tok -> source );
243231
244232 Py_ssize_t relative_lineno = p -> starting_lineno ? lineno - p -> starting_lineno + 1 : lineno ;
245- const char * buf_end = p -> tok -> fp_interactive ? p -> tok -> interactive_src_end : p -> tok -> inp ;
246-
247- if (buf_end < cur_line ) {
248- buf_end = cur_line + strlen (cur_line );
249- }
233+ const char * buf_end = cur_line + p -> tok -> source .len ;
250234
251235 for (int i = 0 ; i < relative_lineno - 1 ; i ++ ) {
252- char * new_line = strchr (cur_line , '\n' );
253- // The assert is here for debug builds but the conditional that
254- // follows is there so in release builds we do not crash at the cost
255- // to report a potentially wrong line.
256- assert (new_line != NULL && new_line + 1 < buf_end );
257- if (new_line == NULL || new_line + 1 > buf_end ) {
236+ const char * new_line = memchr (cur_line , '\n' , buf_end - cur_line );
237+ if (new_line == NULL ) {
258238 break ;
259239 }
260240 cur_line = new_line + 1 ;
261241 }
262242
263- char * next_newline ;
264- if ((next_newline = strchr (cur_line , '\n' )) == NULL ) { // This is the last line
265- next_newline = cur_line + strlen (cur_line );
266- }
243+ const char * next_newline = memchr (cur_line , '\n' , buf_end - cur_line );
244+ next_newline = next_newline != NULL ? next_newline : buf_end ;
267245 return PyUnicode_DecodeUTF8 (cur_line , next_newline - cur_line , "replace" );
268246}
269247
@@ -296,7 +274,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype,
296274 }
297275
298276 if (p -> tok -> fp_interactive && p -> tok -> interactive_src_start != NULL ) {
299- error_line = get_error_line_from_tokenizer_buffers (p , lineno );
277+ error_line = get_error_line_from_source (p , lineno );
300278 }
301279 else if (p -> start_rule == Py_file_input ) {
302280 error_line = _PyErr_ProgramDecodedTextObject (p -> tok -> filename ,
@@ -318,7 +296,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype,
318296 error_line = PyUnicode_DecodeUTF8 (p -> tok -> line_start , size , "replace" );
319297 }
320298 else if (p -> tok -> fp == NULL || p -> tok -> fp == stdin ) {
321- error_line = get_error_line_from_tokenizer_buffers (p , lineno );
299+ error_line = get_error_line_from_source (p , lineno );
322300 }
323301 else {
324302 error_line = Py_GetConstant (Py_CONSTANT_EMPTY_STR );
0 commit comments