@@ -554,36 +554,58 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
554554static void
555555print_error_text (PyObject * f , int offset , PyObject * text_obj )
556556{
557- const char * text ;
558- const char * nl ;
559-
560- text = PyUnicode_AsUTF8 (text_obj );
557+ /* Convert text to a char pointer; return if error */
558+ const char * text = PyUnicode_AsUTF8 (text_obj );
561559 if (text == NULL )
562560 return ;
563561
564- if (offset >= 0 ) {
565- if (offset > 0 && (size_t )offset == strlen (text ) && text [offset - 1 ] == '\n' )
566- offset -- ;
567- for (;;) {
568- nl = strchr (text , '\n' );
569- if (nl == NULL || nl - text >= offset )
570- break ;
571- offset -= (int )(nl + 1 - text );
572- text = nl + 1 ;
573- }
574- while (* text == ' ' || * text == '\t' || * text == '\f' ) {
575- text ++ ;
576- offset -- ;
577- }
562+ /* Convert offset from 1-based to 0-based */
563+ offset -- ;
564+
565+ /* Strip leading whitespace from text, adjusting offset as we go */
566+ while (* text == ' ' || * text == '\t' || * text == '\f' ) {
567+ text ++ ;
568+ offset -- ;
569+ }
570+
571+ /* Calculate text length excluding trailing newline */
572+ Py_ssize_t len = strlen (text );
573+ if (len > 0 && text [len - 1 ] == '\n' )
574+ len -- ;
575+
576+ /* Clip offset to at most len */
577+ if (offset > len )
578+ offset = len ;
579+
580+ /* Skip past newlines embedded in text */
581+ for (;;) {
582+ const char * nl = strchr (text , '\n' );
583+ if (nl == NULL )
584+ break ;
585+ Py_ssize_t inl = nl - text ;
586+ if (inl >= (Py_ssize_t )offset )
587+ break ;
588+ inl += 1 ;
589+ text += inl ;
590+ len -= inl ;
591+ offset -= (int )inl ;
578592 }
593+
594+ /* Print text */
579595 PyFile_WriteString (" " , f );
580596 PyFile_WriteString (text , f );
581- if (* text == '\0' || text [strlen (text )- 1 ] != '\n' )
597+
598+ /* Make sure there's a newline at the end */
599+ if (text [len ] != '\n' )
582600 PyFile_WriteString ("\n" , f );
583- if (offset == -1 )
601+
602+ /* Don't print caret if it points to the left of the text */
603+ if (offset < 0 )
584604 return ;
605+
606+ /* Write caret line */
585607 PyFile_WriteString (" " , f );
586- while (-- offset > 0 )
608+ while (-- offset >= 0 )
587609 PyFile_WriteString (" " , f );
588610 PyFile_WriteString ("^\n" , f );
589611}
0 commit comments