diff options
Diffstat (limited to 'Modules/parsermodule.c')
-rw-r--r-- | Modules/parsermodule.c | 154 |
1 files changed, 101 insertions, 53 deletions
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index e598046..36e9893 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -83,54 +83,78 @@ node2tuple(node *n, /* node to convert */ int lineno, /* include line numbers? */ int col_offset) /* include column offsets? */ { + PyObject *result = NULL, *w; + if (n == NULL) { Py_INCREF(Py_None); - return (Py_None); + return Py_None; } + if (ISNONTERMINAL(TYPE(n))) { int i; - PyObject *v; - PyObject *w; - v = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl)); - if (v == NULL) - return (v); + result = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl)); + if (result == NULL) + goto error; + w = PyLong_FromLong(TYPE(n)); - if (w == NULL) { - Py_DECREF(v); - return ((PyObject*) NULL); - } - (void) addelem(v, 0, w); + if (w == NULL) + goto error; + (void) addelem(result, 0, w); + for (i = 0; i < NCH(n); i++) { w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset); - if (w == NULL) { - Py_DECREF(v); - return ((PyObject*) NULL); - } - (void) addelem(v, i+1, w); + if (w == NULL) + goto error; + (void) addelem(result, i+1, w); } - if (TYPE(n) == encoding_decl) - (void) addelem(v, i+1, PyUnicode_FromString(STR(n))); - return (v); + if (TYPE(n) == encoding_decl) { + w = PyUnicode_FromString(STR(n)); + if (w == NULL) + goto error; + (void) addelem(result, i+1, w); + } } else if (ISTERMINAL(TYPE(n))) { - PyObject *result = mkseq(2 + lineno + col_offset); - if (result != NULL) { - (void) addelem(result, 0, PyLong_FromLong(TYPE(n))); - (void) addelem(result, 1, PyUnicode_FromString(STR(n))); - if (lineno == 1) - (void) addelem(result, 2, PyLong_FromLong(n->n_lineno)); - if (col_offset == 1) - (void) addelem(result, 3, PyLong_FromLong(n->n_col_offset)); + result = mkseq(2 + lineno + col_offset); + if (result == NULL) + goto error; + + w = PyLong_FromLong(TYPE(n)); + if (w == NULL) + goto error; + (void) addelem(result, 0, w); + + w = PyUnicode_FromString(STR(n)); + if (w == NULL) + goto error; + (void) addelem(result, 1, w); + + if (lineno == 1) { + w = PyLong_FromLong(n->n_lineno); + if (w == NULL) + goto error; + (void) addelem(result, 2, w); + } + + if (col_offset == 1) { + w = PyLong_FromLong(n->n_col_offset); + if (w == NULL) + goto error; + (void) addelem(result, 3, w); } - return (result); } else { PyErr_SetString(PyExc_SystemError, "unrecognized parse tree node type"); return ((PyObject*) NULL); } + return result; + +error: + Py_XDECREF(result); + return NULL; } /* * End of material copyrighted by Stichting Mathematisch Centrum. @@ -453,33 +477,46 @@ parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw) static PyObject* parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) { - PyObject* res = 0; - PyArena* arena; + PyObject* res = NULL; + PyArena* arena = NULL; mod_ty mod; - char* str = "<syntax-tree>"; + PyObject* filename = NULL; int ok; static char *keywords[] = {"st", "filename", NULL}; if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords, - &PyST_Type, &self, &str); + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O&:compilest", keywords, + &PyST_Type, &self, + PyUnicode_FSDecoder, &filename); else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1], - &str); - - if (ok) { - arena = PyArena_New(); - if (arena) { - mod = PyAST_FromNode(self->st_node, &(self->st_flags), str, arena); - if (mod) { - res = (PyObject *)PyAST_Compile(mod, str, &(self->st_flags), arena); - } - PyArena_Free(arena); - } - } - - return (res); + ok = PyArg_ParseTupleAndKeywords(args, kw, "|O&:compile", &keywords[1], + PyUnicode_FSDecoder, &filename); + if (!ok) + goto error; + + if (filename == NULL) { + filename = PyUnicode_FromString("<syntax-tree>"); + if (filename == NULL) + goto error; + } + + arena = PyArena_New(); + if (!arena) + goto error; + + mod = PyAST_FromNodeObject(self->st_node, &self->st_flags, + filename, arena); + if (!mod) + goto error; + + res = (PyObject *)PyAST_CompileObject(mod, filename, + &self->st_flags, -1, arena); +error: + Py_XDECREF(filename); + if (arena != NULL) + PyArena_Free(arena); + return res; } @@ -809,8 +846,13 @@ build_node_children(PyObject *tuple, node *root, int *line_num) return 0; } strn = (char *)PyObject_MALLOC(len + 1); - if (strn != NULL) - (void) memcpy(strn, temp_str, len + 1); + if (strn == NULL) { + Py_DECREF(temp); + Py_XDECREF(elem); + PyErr_NoMemory(); + return 0; + } + (void) memcpy(strn, temp_str, len + 1); Py_DECREF(temp); } else if (!ISNONTERMINAL(type)) { @@ -870,7 +912,7 @@ build_node_tree(PyObject *tuple) * The tuple is simple, but it doesn't start with a start symbol. * Raise an exception now and be done with it. */ - tuple = Py_BuildValue("os", tuple, + tuple = Py_BuildValue("Os", tuple, "Illegal syntax-tree; cannot start with terminal symbol."); PyErr_SetObject(parser_error, tuple); Py_XDECREF(tuple); @@ -906,8 +948,14 @@ build_node_tree(PyObject *tuple) return NULL; } res->n_str = (char *)PyObject_MALLOC(len + 1); - if (res->n_str != NULL && temp != NULL) - (void) memcpy(res->n_str, temp, len + 1); + if (res->n_str == NULL) { + Py_DECREF(res); + Py_DECREF(encoding); + Py_DECREF(tuple); + PyErr_NoMemory(); + return NULL; + } + (void) memcpy(res->n_str, temp, len + 1); Py_DECREF(encoding); Py_DECREF(tuple); } |