@@ -554,36 +554,58 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
554
554
static void
555
555
print_error_text (PyObject * f , int offset , PyObject * text_obj )
556
556
{
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 );
561
559
if (text == NULL )
562
560
return ;
563
561
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 ;
578
592
}
593
+
594
+ /* Print text */
579
595
PyFile_WriteString (" " , f );
580
596
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' )
582
600
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 )
584
604
return ;
605
+
606
+ /* Write caret line */
585
607
PyFile_WriteString (" " , f );
586
- while (-- offset > 0 )
608
+ while (-- offset >= 0 )
587
609
PyFile_WriteString (" " , f );
588
610
PyFile_WriteString ("^\n" , f );
589
611
}
0 commit comments