Mercurial > cpython-lru_cache-weakref
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 } |
