* Unlike the prior interface, the ability to give a parse tree
* produced by Python code as a tuple to the compiler is enabled by
* this module. See the documentation for more details.
+ *
+ * I've added some annotations that help with the lint code-checking
+ * program, but they're not complete by a long shot. The real errors
+ * that lint detects are gone, but there are still warnings with
+ * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations
+ * look like "NOTE(...)".
*/
#include "Python.h" /* general Python API */
/* ISTERMINAL() / ISNONTERMINAL() */
#include "compile.h" /* PyNode_Compile() */
+#ifdef lint
+#include <note.h>
+#else
+#define NOTE(x)
+#endif
+
#ifdef macintosh
char *strdup Py_PROTO((char *));
#endif
typedef PyObject* (*SeqMaker) Py_PROTO((int length));
-typedef void (*SeqInserter) Py_PROTO((PyObject* sequence,
- int index,
- PyObject* element));
+typedef int (*SeqInserter) Py_PROTO((PyObject* sequence,
+ int index,
+ PyObject* element));
/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
* original copyright statement is included below, and continues to apply
{
if (n == NULL) {
Py_INCREF(Py_None);
- return Py_None;
+ return (Py_None);
}
if (ISNONTERMINAL(TYPE(n))) {
int i;
- PyObject *v, *w;
+ PyObject *v;
+ PyObject *w;
+
v = mkseq(1 + NCH(n));
if (v == NULL)
- return v;
+ return (v);
w = PyInt_FromLong(TYPE(n));
if (w == NULL) {
Py_DECREF(v);
- return NULL;
+ return ((PyObject*) NULL);
}
- addelem(v, 0, w);
+ (void) addelem(v, 0, w);
for (i = 0; i < NCH(n); i++) {
w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
if (w == NULL) {
Py_DECREF(v);
- return NULL;
+ return ((PyObject*) NULL);
}
- addelem(v, i+1, w);
+ (void) addelem(v, i+1, w);
}
return (v);
}
else if (ISTERMINAL(TYPE(n))) {
PyObject *result = mkseq(2 + lineno);
if (result != NULL) {
- addelem(result, 0, PyInt_FromLong(TYPE(n)));
- addelem(result, 1, PyString_FromString(STR(n)));
+ (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
+ (void) addelem(result, 1, PyString_FromString(STR(n)));
if (lineno == 1)
- addelem(result, 2, PyInt_FromLong(n->n_lineno));
+ (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
}
return (result);
}
else {
PyErr_SetString(PyExc_SystemError,
"unrecognized parse tree node type");
- return NULL;
+ return ((PyObject*) NULL);
}
} /* node2tuple() */
/*
} PyAST_Object;
-staticforward void parser_free Py_PROTO((PyAST_Object *ast));
-staticforward int parser_compare Py_PROTO((PyAST_Object *left,
- PyAST_Object *right));
+staticforward void
+parser_free Py_PROTO((PyAST_Object *ast));
+
+staticforward int
+parser_compare Py_PROTO((PyAST_Object *left, PyAST_Object *right));
-staticforward PyObject *parser_getattr Py_PROTO((PyObject *self, char *name));
+staticforward PyObject *
+parser_getattr Py_PROTO((PyObject *self, char *name));
-/* static */
+static
PyTypeObject PyAST_Type = {
- PyObject_HEAD_INIT(NULL)
+ PyObject_HEAD_INIT(&PyType_Type)
0,
"ast", /* tp_name */
- sizeof(PyAST_Object), /* tp_basicsize */
+ (int) sizeof(PyAST_Object), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)parser_free, /* tp_dealloc */
0, /* tp_print */
for (j = 0; j < NCH(left); ++j) {
int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
- if (v)
+ if (v != NULL)
return (v);
}
return (0);
o->ast_node = ast;
o->ast_type = type;
}
+ else {
+ PyNode_Free(ast);
+ }
return ((PyObject*)o);
} /* parser_newastobject() */
PyObject *res = 0;
int ok;
- if (self == NULL)
+ if (self == NULL) {
ok = PyArg_ParseTuple(
args, "O!|O:ast2tuple", &PyAST_Type, &self, &line_option);
+ }
else
ok = PyArg_ParseTuple(args, "|O:totuple", &line_option);
- if (ok) {
+ if (ok != 0) {
int lineno = 0;
if (line_option != NULL) {
- lineno = PyObject_IsTrue(line_option) ? 1 : 0;
+ lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
}
/*
* Convert AST into a tuple representation. Use Guido's function,
* Convert AST into a tuple representation. Use Guido's function,
* since it's known to work already.
*/
- res = node2tuple(((PyAST_Object *)self)->ast_node,
+ res = node2tuple(self->ast_node,
PyList_New, PyList_SetItem, lineno);
}
return (res);
{"totuple", (PyCFunction)parser_ast2tuple, METH_VARARGS,
"Creates a tuple-tree representation of this AST."},
- {NULL}
+ {NULL, NULL, 0, NULL}
};
static PyObject*
PyObject *self;
PyObject *args;
{
+ NOTE(ARGUNUSED(self))
return (parser_do_parse(args, PyAST_EXPR));
} /* parser_expr() */
PyObject *self;
PyObject *args;
{
+ NOTE(ARGUNUSED(self))
return (parser_do_parse(args, PyAST_SUITE));
} /* parser_suite() */
PyObject *self;
PyObject *args;
{
+ NOTE(ARGUNUSED(self))
PyObject *ast = 0;
PyObject *tuple = 0;
PyObject *temp = 0;
/* check_terminal_tuple() already verified it's a string */
strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
if (strn != NULL)
- strcpy(strn, PyString_AS_STRING(temp));
+ (void) strcpy(strn, PyString_AS_STRING(temp));
Py_XDECREF(temp);
if (PyObject_Length(elem) == 3) {
#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
-#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
+#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
-#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
+#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
#define validate_star(ch) validate_terminal(ch, STAR, "*")
if (!res) {
char buffer[128];
- sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
+ (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
err_string(buffer);
}
return (res);
{
if (NCH(n) != num) {
char buff[60];
- sprintf(buff, "Illegal number of children for %s node.", name);
+ (void) sprintf(buff, "Illegal number of children for %s node.", name);
err_string(buff);
}
return (NCH(n) == num);
if (!res && !PyErr_Occurred()) {
char buffer[60];
- sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
+ (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
err_string(buffer);
}
return (res);
&& vfunc(CHILD(tree, 0)));
if (!res && !PyErr_Occurred())
- validate_numnodes(tree, 1, name);
+ (void) validate_numnodes(tree, 1, name);
else {
if (is_even(nch))
res = validate_comma(CHILD(tree, --nch));
&& validate_suite(CHILD(tree, nch - 1)));
}
else
- validate_numnodes(tree, 4, "class");
+ (void) validate_numnodes(tree, 4, "class");
if (res && (nch == 7)) {
res = (validate_lparen(CHILD(tree, 2))
&& validate_testlist(CHILD(tree, 3))
nch -= 3;
}
else if (!res && !PyErr_Occurred())
- validate_numnodes(tree, 4, "if");
+ (void) validate_numnodes(tree, 4, "if");
if ((nch % 4) != 0)
/* Will catch the case for nch < 4 */
res = validate_numnodes(tree, 0, "if");
res = validate_varargslist(CHILD(tree, 1));
}
else
- validate_numnodes(tree, 2, "parameters");
+ (void) validate_numnodes(tree, 2, "parameters");
return (res);
res = validate_stmt(CHILD(tree, i));
}
else if (nch < 4)
- validate_numnodes(tree, 4, "suite");
+ res = validate_numnodes(tree, 4, "suite");
}
return (res);
res = ((remaining == 2) || (remaining == 3)
|| (remaining == 5) || (remaining == 6));
if (!res)
- validate_numnodes(tree, 2, "varargslist");
+ (void) validate_numnodes(tree, 2, "varargslist");
else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
return ((remaining == 2)
&& validate_ntype(CHILD(tree, pos+1), NAME));
res = (validate_star(CHILD(tree, pos + 1))
&& validate_star(CHILD(tree, pos + 2)));
else
- validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
+ res = validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
}
}
}
&& validate_fplist(CHILD(tree, 1))
&& validate_rparen(CHILD(tree, 2)));
else
- validate_numnodes(tree, 1, "fpdef");
+ res = validate_numnodes(tree, 1, "fpdef");
}
return (res);
res = validate_node(CHILD(tree, 0));
else if (nch == 1) {
char buffer[60];
- sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
- TYPE(CHILD(tree, 0)));
+ (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
+ TYPE(CHILD(tree, 0)));
err_string(buffer);
}
return (res);
res = validate_node(tree);
else {
char buffer[60];
- sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
+ (void) sprintf(buffer, "Illegal compound statement type: %d.",
+ TYPE(tree));
err_string(buffer);
}
return (res);
--nch;
}
else if (!res && !PyErr_Occurred())
- validate_numnodes(tree, 1, "print_stmt");
+ (void) validate_numnodes(tree, 1, "print_stmt");
for (j = 1; res && (j < nch); j += 2)
res = (validate_test(CHILD(tree, j))
&& validate_ntype(CHILD(tree, j + 1), COMMA));
}
}
else
- validate_numnodes(tree, 2, "raise");
+ (void) validate_numnodes(tree, 2, "raise");
if (res && (nch == 4))
res = (validate_comma(CHILD(tree, 2))
&& validate_test(CHILD(tree, 3)));
char buffer[60];
if (TYPE(CHILD(tree, nch - 3)) != except_clause)
name = STR(CHILD(tree, nch - 3));
- sprintf(buffer, "Illegal number of children for try/%s node.", name);
+ (void) sprintf(buffer,
+ "Illegal number of children for try/%s node.", name);
err_string(buffer);
}
/* Skip past except_clause sections: */
|| (strcmp(STR(tree), "is") == 0));
if (!res) {
char buff[128];
- sprintf(buff, "Illegal operator: '%s'.", STR(tree));
+ (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
err_string(buff);
}
break;
if (res && (nch == 4))
res = validate_varargslist(CHILD(tree, 1));
else if (!res && !PyErr_Occurred())
- validate_numnodes(tree, 3, "lambdef");
+ (void) validate_numnodes(tree, 3, "lambdef");
return (res);
}
}
else
- validate_numnodes(tree, 2, "trailer");
+ (void) validate_numnodes(tree, 2, "trailer");
return (res);
int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
&& validate_ntype(tree, sliceop);
if (!res && !PyErr_Occurred()) {
- validate_numnodes(tree, 1, "sliceop");
- res = 0;
+ res = validate_numnodes(tree, 1, "sliceop");
}
if (res)
res = validate_colon(CHILD(tree, 0));
PyObject *self;
PyObject *args;
{
+ NOTE(ARGUNUSED(self))
PyObject *result = NULL;
PyObject *ast = NULL;
if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
goto finally;
- tuple = parser_ast2tuple(NULL, newargs);
+ tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs);
if (tuple != NULL) {
result = Py_BuildValue("O(O)", pickle_constructor, tuple);
Py_DECREF(tuple);
{"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
"Returns the pickle magic to allow ast objects to be pickled."},
- {0, 0, 0}
+ {NULL, NULL, 0, NULL}
};