From 5acc0c0cfc3b47ac993cb27e67b8e171a9d4f22d Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Fri, 2 Feb 2001 20:01:10 +0000 Subject: Fix symbol table pass to generation SyntaxError exceptions that include the filename and line number. --- Include/symtable.h | 1 + Python/compile.c | 78 ++++++++++++++++++++++++++++++++---------------------- 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/Include/symtable.h b/Include/symtable.h index 2d427aa..beea9f5 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -43,6 +43,7 @@ extern "C" { struct symtable { int st_pass; /* pass == 1 or 2 */ int st_keep; /* true if symtable will be returned */ + char *st_filename; /* name of file being compiled */ PyObject *st_symbols; /* dictionary of symbol tables */ PyObject *st_varnames; /* dictionary of parameter lists */ PyObject *st_stack; /* stack of namespace info */ diff --git a/Python/compile.c b/Python/compile.c index acad667..ce1ed3f 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -371,31 +371,14 @@ int is_free(int v) /* Error message including line number */ static void -com_error(struct compiling *c, PyObject *exc, char *msg) +set_error_location(char *filename, int lineno) { - PyObject *v, *tb, *tmp; - if (c == NULL) { - /* Error occurred via symtable call to - is_constant_false */ - PyErr_SetString(exc, msg); - return; - } - c->c_errors++; - if (c->c_lineno <= 1) { - /* Unknown line number or single interactive command */ - PyErr_SetString(exc, msg); - return; - } - v = PyString_FromString(msg); - if (v == NULL) - return; /* MemoryError, too bad */ - PyErr_SetObject(exc, v); - Py_DECREF(v); + PyObject *exc, *v, *tb, *tmp; /* add attributes for the line number and filename for the error */ PyErr_Fetch(&exc, &v, &tb); PyErr_NormalizeException(&exc, &v, &tb); - tmp = PyInt_FromLong(c->c_lineno); + tmp = PyInt_FromLong(lineno); if (tmp == NULL) PyErr_Clear(); else { @@ -403,8 +386,8 @@ com_error(struct compiling *c, PyObject *exc, char *msg) PyErr_Clear(); Py_DECREF(tmp); } - if (c->c_filename != NULL) { - tmp = PyString_FromString(c->c_filename); + if (filename != NULL) { + tmp = PyString_FromString(filename); if (tmp == NULL) PyErr_Clear(); else { @@ -416,6 +399,31 @@ com_error(struct compiling *c, PyObject *exc, char *msg) PyErr_Restore(exc, v, tb); } +static void +com_error(struct compiling *c, PyObject *exc, char *msg) +{ + PyObject *v; + if (c == NULL) { + /* Error occurred via symtable call to + is_constant_false */ + PyErr_SetString(exc, msg); + return; + } + c->c_errors++; + if (c->c_lineno <= 1) { + /* Unknown line number or single interactive command */ + PyErr_SetString(exc, msg); + return; + } + v = PyString_FromString(msg); + if (v == NULL) + return; /* MemoryError, too bad */ + PyErr_SetObject(exc, v); + Py_DECREF(v); + + set_error_location(c->c_filename, c->c_lineno); +} + /* Interface to the block stack */ @@ -3804,6 +3812,7 @@ PyNode_CompileSymtable(node *n, char *filename) st = symtable_init(1); if (st == NULL) return NULL; + assert(st->st_symbols != NULL); symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno); if (st->st_errors > 0) { PySymtable_Free(st); @@ -3952,6 +3961,7 @@ symtable_build(struct compiling *c, node *n) { if ((c->c_symtable = symtable_init(0)) == NULL) return -1; + c->c_symtable->st_filename = c->c_filename; symtable_enter_scope(c->c_symtable, TOP, TYPE(n), n->n_lineno); if (c->c_symtable->st_errors > 0) return -1; @@ -4057,11 +4067,11 @@ symtable_load_symbols(struct compiling *c) else if (info & DEF_GLOBAL) { if ((info & DEF_PARAM) && (PyString_AS_STRING(name)[0] != '.')){ - char buf[500]; - sprintf(buf, - "name '%.400s' is local and global", - PyString_AS_STRING(name)); - com_error(c, PyExc_SyntaxError, buf); + PyErr_Format(PyExc_SyntaxError, + "name '%.400s' is local and global", + PyString_AS_STRING(name)); + set_error_location(st->st_filename, + st->st_cur_lineno); goto fail; } if (PyDict_SetItem(c->c_globals, name, Py_None) < 0) @@ -4119,13 +4129,12 @@ symtable_load_symbols(struct compiling *c) if (PyDict_GetItemString(st->st_cur, NOOPT) == NULL) c->c_flags |= CO_OPTIMIZED; else if (ncells || nfrees) { - char buf[256]; - /* XXX need better error message */ - sprintf(buf, + PyErr_Format(PyExc_SyntaxError, "function %.100s: may not use lexical scoping" " and 'import *' or exec in same function", PyString_AS_STRING(st->st_cur_name)); - com_error(c, PyExc_SyntaxError, buf); + set_error_location(st->st_filename, + st->st_cur_lineno); return -1; } } @@ -4148,6 +4157,7 @@ symtable_init(int keep) return NULL; st->st_pass = 1; st->st_keep = keep; + st->st_filename = NULL; if ((st->st_stack = PyList_New(0)) == NULL) goto fail; if ((st->st_symbols = PyDict_New()) == NULL) @@ -4160,6 +4170,7 @@ symtable_init(int keep) goto fail; if (PyDict_SetItemString(st->st_symbols, TOP, d) < 0) goto fail; + st->st_global = d; Py_DECREF(d); if (keep) { if ((d = PyDict_New()) == NULL) @@ -4167,7 +4178,6 @@ symtable_init(int keep) st->st_scopes = d; } else st->st_scopes = NULL; - st->st_global = d; /* use ref borrowed from st->st_symbols */ st->st_cur = NULL; st->st_cur_id = NULL; st->st_cur_name = NULL; @@ -4505,6 +4515,8 @@ symtable_add_def_o(struct symtable *st, PyObject *dict, if ((flag & DEF_PARAM) && (val & DEF_PARAM)) { PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, PyString_AsString(name)); + set_error_location(st->st_filename, + st->st_cur_lineno); return -1; } val |= flag; @@ -4844,6 +4856,8 @@ symtable_import(struct symtable *st, node *n) if (st->st_cur_type != TYPE_MODULE) { PyErr_SetString(PyExc_SyntaxError, ILLEGAL_IMPORT_STAR); + set_error_location(st->st_filename, + n->n_lineno); st->st_errors++; return; } -- cgit v0.12