summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-02-02 20:01:10 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-02-02 20:01:10 (GMT)
commit5acc0c0cfc3b47ac993cb27e67b8e171a9d4f22d (patch)
treeae9c2c72fd47bba564bb1b082fe2a3bfd2fd4fbd
parentdbfb66296c81e7828f909ecb2cc14424b59b2995 (diff)
downloadcpython-5acc0c0cfc3b47ac993cb27e67b8e171a9d4f22d.zip
cpython-5acc0c0cfc3b47ac993cb27e67b8e171a9d4f22d.tar.gz
cpython-5acc0c0cfc3b47ac993cb27e67b8e171a9d4f22d.tar.bz2
Fix symbol table pass to generation SyntaxError exceptions that
include the filename and line number.
-rw-r--r--Include/symtable.h1
-rw-r--r--Python/compile.c78
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;
}