comparison Python/errors.c @ 16838:09f6c1372056 legacy-trunk

Improve SyntaxErrors for bad future statements. Set file and location for errors raised in future.c. Move some helper functions from compile.c to errors.c and make them API functions: PyErr_SyntaxLocation() and PyErr_ProgramText().
author Jeremy Hylton <jeremy@alum.mit.edu>
date Wed, 28 Feb 2001 17:47:12 +0000
parents 36286632ff3a
children 2d4da6cfee61
comparison
equal deleted inserted replaced
16837:0e6a3da4f956 16838:09f6c1372056
620 return -1; 620 return -1;
621 Py_DECREF(res); 621 Py_DECREF(res);
622 return 0; 622 return 0;
623 } 623 }
624 } 624 }
625
626 void
627 PyErr_SyntaxLocation(char *filename, int lineno)
628 {
629 PyObject *exc, *v, *tb, *tmp;
630
631 /* add attributes for the line number and filename for the error */
632 PyErr_Fetch(&exc, &v, &tb);
633 PyErr_NormalizeException(&exc, &v, &tb);
634 /* XXX check that it is, indeed, a syntax error */
635 tmp = PyInt_FromLong(lineno);
636 if (tmp == NULL)
637 PyErr_Clear();
638 else {
639 if (PyObject_SetAttrString(v, "lineno", tmp))
640 PyErr_Clear();
641 Py_DECREF(tmp);
642 }
643 if (filename != NULL) {
644 tmp = PyString_FromString(filename);
645 if (tmp == NULL)
646 PyErr_Clear();
647 else {
648 if (PyObject_SetAttrString(v, "filename", tmp))
649 PyErr_Clear();
650 Py_DECREF(tmp);
651 }
652
653 tmp = PyErr_ProgramText(filename, lineno);
654 if (tmp) {
655 PyObject_SetAttrString(v, "text", tmp);
656 Py_DECREF(tmp);
657 }
658 }
659 PyErr_Restore(exc, v, tb);
660 }
661
662 /* com_fetch_program_text will attempt to load the line of text that
663 the exception refers to. If it fails, it will return NULL but will
664 not set an exception.
665
666 XXX The functionality of this function is quite similar to the
667 functionality in tb_displayline() in traceback.c.
668 */
669
670 PyObject *
671 PyErr_ProgramText(char *filename, int lineno)
672 {
673 FILE *fp;
674 int i;
675 char linebuf[1000];
676
677 if (filename == NULL || lineno <= 0)
678 return NULL;
679 fp = fopen(filename, "r");
680 if (fp == NULL)
681 return NULL;
682 for (i = 0; i < lineno; i++) {
683 char *pLastChar = &linebuf[sizeof(linebuf) - 2];
684 do {
685 *pLastChar = '\0';
686 if (fgets(linebuf, sizeof linebuf, fp) == NULL)
687 break;
688 /* fgets read *something*; if it didn't get as
689 far as pLastChar, it must have found a newline
690 or hit the end of the file; if pLastChar is \n,
691 it obviously found a newline; else we haven't
692 yet seen a newline, so must continue */
693 } while (*pLastChar != '\0' && *pLastChar != '\n');
694 }
695 fclose(fp);
696 if (i == lineno) {
697 char *p = linebuf;
698 while (*p == ' ' || *p == '\t' || *p == '\014')
699 p++;
700 return PyString_FromString(p);
701 }
702 return NULL;
703 }