]> granicus.if.org Git - python/commitdiff
Fix symbol table pass to generation SyntaxError exceptions that
authorJeremy Hylton <jeremy@alum.mit.edu>
Fri, 2 Feb 2001 20:01:10 +0000 (20:01 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Fri, 2 Feb 2001 20:01:10 +0000 (20:01 +0000)
include the filename and line number.

Include/symtable.h
Python/compile.c

index 2d427aa68999a330dd357738e00b4f0474b4ecb8..beea9f50b64e5147bebd755235f74c21340e403e 100644 (file)
@@ -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 */
index acad6673eabc8b798c20813081a2d16ad44482ef..ce1ed3ffdfccba4f26858d3346c01cfc692545a3 100644 (file)
@@ -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;
                        }