@@ -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