comparison Python/pythonrun.c @ 16831:27f04d714ecb legacy-trunk

Print the offending line of code in the traceback for SyntaxErrors raised by the compiler. XXX For now, text entered into the interactive intepreter is not printed in the traceback. Inspired by a patch from Roman Sulzhyk compile.c: Add helper fetch_program_text() that opens a file and reads until it finds the specified line number. The code is a near duplicate of similar code in traceback.c. Modify com_error() to pass two arguments to SyntaxError constructor, where the second argument contains the offending text when possible. Modify set_error_location(), now used only by the symtable pass, to set the text attribute on existing exceptions. pythonrun.c: Change parse_syntax_error() to continue of the offset attribute of a SyntaxError is None. In this case, it sets offset to -1. Move code from PyErr_PrintEx() into helper function print_error_text(). In the helper, only print the caret for a SyntaxError if offset > 0.
author Jeremy Hylton <jeremy@alum.mit.edu>
date Wed, 28 Feb 2001 07:07:43 +0000
parents a51b9961f3bb
children 09dcf5ebcd80
comparison
equal deleted inserted replaced
16830:f5370e1e2392 16831:27f04d714ecb
691 goto finally; 691 goto finally;
692 *lineno = (int)hold; 692 *lineno = (int)hold;
693 693
694 if (!(v = PyObject_GetAttrString(err, "offset"))) 694 if (!(v = PyObject_GetAttrString(err, "offset")))
695 goto finally; 695 goto finally;
696 hold = PyInt_AsLong(v); 696 if (v == Py_None) {
697 Py_DECREF(v); 697 *offset = -1;
698 v = NULL; 698 Py_DECREF(v);
699 if (hold < 0 && PyErr_Occurred()) 699 v = NULL;
700 goto finally; 700 } else {
701 *offset = (int)hold; 701 hold = PyInt_AsLong(v);
702 Py_DECREF(v);
703 v = NULL;
704 if (hold < 0 && PyErr_Occurred())
705 goto finally;
706 *offset = (int)hold;
707 }
702 708
703 if (!(v = PyObject_GetAttrString(err, "text"))) 709 if (!(v = PyObject_GetAttrString(err, "text")))
704 goto finally; 710 goto finally;
705 if (v == Py_None) 711 if (v == Py_None)
706 *text = NULL; 712 *text = NULL;
716 722
717 void 723 void
718 PyErr_Print(void) 724 PyErr_Print(void)
719 { 725 {
720 PyErr_PrintEx(1); 726 PyErr_PrintEx(1);
727 }
728
729 static void
730 print_error_text(PyObject *f, int offset, char *text)
731 {
732 char *nl;
733 if (offset >= 0) {
734 if (offset > 0 && offset == (int)strlen(text))
735 offset--;
736 for (;;) {
737 nl = strchr(text, '\n');
738 if (nl == NULL || nl-text >= offset)
739 break;
740 offset -= (nl+1-text);
741 text = nl+1;
742 }
743 while (*text == ' ' || *text == '\t') {
744 text++;
745 offset--;
746 }
747 }
748 PyFile_WriteString(" ", f);
749 PyFile_WriteString(text, f);
750 if (*text == '\0' || text[strlen(text)-1] != '\n')
751 PyFile_WriteString("\n", f);
752 if (offset == -1)
753 return;
754 PyFile_WriteString(" ", f);
755 offset--;
756 while (offset > 0) {
757 PyFile_WriteString(" ", f);
758 offset--;
759 }
760 PyFile_WriteString("^\n", f);
721 } 761 }
722 762
723 void 763 void
724 PyErr_PrintEx(int set_sys_last_vars) 764 PyErr_PrintEx(int set_sys_last_vars)
725 { 765 {
793 PyFile_WriteString(filename, f); 833 PyFile_WriteString(filename, f);
794 PyFile_WriteString("\", line ", f); 834 PyFile_WriteString("\", line ", f);
795 sprintf(buf, "%d", lineno); 835 sprintf(buf, "%d", lineno);
796 PyFile_WriteString(buf, f); 836 PyFile_WriteString(buf, f);
797 PyFile_WriteString("\n", f); 837 PyFile_WriteString("\n", f);
798 if (text != NULL) { 838 if (text != NULL)
799 char *nl; 839 print_error_text(f, offset, text);
800 if (offset > 0 &&
801 offset == (int)strlen(text))
802 offset--;
803 for (;;) {
804 nl = strchr(text, '\n');
805 if (nl == NULL ||
806 nl-text >= offset)
807 break;
808 offset -= (nl+1-text);
809 text = nl+1;
810 }
811 while (*text == ' ' || *text == '\t') {
812 text++;
813 offset--;
814 }
815 PyFile_WriteString(" ", f);
816 PyFile_WriteString(text, f);
817 if (*text == '\0' ||
818 text[strlen(text)-1] != '\n')
819 PyFile_WriteString("\n", f);
820 PyFile_WriteString(" ", f);
821 offset--;
822 while (offset > 0) {
823 PyFile_WriteString(" ", f);
824 offset--;
825 }
826 PyFile_WriteString("^\n", f);
827 }
828 Py_INCREF(message); 840 Py_INCREF(message);
829 Py_DECREF(v); 841 Py_DECREF(v);
830 v = message; 842 v = message;
831 /* Can't be bothered to check all those 843 /* Can't be bothered to check all those
832 PyFile_WriteString() calls */ 844 PyFile_WriteString() calls */