Revision: 419 http://rpy.svn.sourceforge.net/rpy/?rev=419&view=rev Author: lgautier Date: 2008-03-08 01:03:12 -0800 (Sat, 08 Mar 2008)
Log Message: ----------- - check SEXP not NULL anywhere possible (not sure it makes sense everywhere, so it might be relaxed later on) - code indentation/layout - cleared warning about possibly undefined variable when parsing named arguments All together, this seem to suppress some of the segfaults. Modified Paths: -------------- trunk/sandbox/rpy_nextgen/rinterface/rinterface.c Modified: trunk/sandbox/rpy_nextgen/rinterface/rinterface.c =================================================================== --- trunk/sandbox/rpy_nextgen/rinterface/rinterface.c 2008-03-04 19:08:49 UTC (rev 418) +++ trunk/sandbox/rpy_nextgen/rinterface/rinterface.c 2008-03-08 09:03:12 UTC (rev 419) @@ -116,7 +116,7 @@ /* Representation of R objects (instances) as instances in Python. */ typedef struct { - PyObject_HEAD + PyObject_HEAD SEXP sexp; } SexpObject; @@ -251,7 +251,8 @@ { if (self->sexp) R_ReleaseObject(self->sexp); - self->ob_type->tp_free((PyObject*)self); + //self->ob_type->tp_free((PyObject*)self); + PyObject_Del(self); } @@ -260,6 +261,10 @@ { //FIXME: make sure this is making any sense SEXP sexp = ((SexpObject *)self)->sexp; + if (! sexp) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL;; + } return PyString_FromFormat("<%s - Python:\%p / R:\%p>", self->ob_type->tp_name, self, @@ -270,7 +275,12 @@ static PyObject* Sexp_typeof(PyObject *self) { - return PyInt_FromLong(TYPEOF(((SexpObject*)self)->sexp)); + SEXP sexp =((SexpObject*)self)->sexp; + if (! sexp) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL;; + } + return PyInt_FromLong(TYPEOF(sexp)); } PyDoc_STRVAR(Sexp_typeof_doc, "\n\ @@ -344,7 +354,7 @@ /* Evaluate a SEXP. It must be constructed by hand. It raises a Python exception if an error ocurred in the evaluation */ SEXP do_eval_expr(SEXP expr_R) { - SEXP res_R; + SEXP res_R = NULL; int error = 0; PyOS_sighandler_t old_int; @@ -396,6 +406,7 @@ { SEXP call_R, c_R, res_R; int largs, lkwds; + SEXP tmp_R; largs = lkwds = 0; if (args) @@ -410,11 +421,15 @@ /* A SEXP with the function to call and the arguments and keywords. */ PROTECT(c_R = call_R = allocList(largs+lkwds+1)); SET_TYPEOF(c_R, LANGSXP); - SETCAR(c_R, ((SexpObject *)self)->sexp); + tmp_R = ((SexpObject *)self)->sexp; + if (! tmp_R) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + goto fail; + } + SETCAR(c_R, tmp_R); c_R = CDR(c_R); int arg_i; - SEXP tmp_R; PyObject *tmp_obj; int is_SexpObject; for (arg_i=0; arg_i<largs; arg_i++) { @@ -425,6 +440,10 @@ goto fail; } tmp_R = ((SexpObject *)tmp_obj)->sexp; + if (! tmp_R) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + goto fail; + } SETCAR(c_R, tmp_R); c_R = CDR(c_R); } @@ -435,34 +454,48 @@ if (kwds) { citems = PyMapping_Items(kwds); - } - for (arg_i=0; arg_i<lkwds; arg_i++) { - tmp_obj = PySequence_GetItem(citems, arg_i); - if (! tmp_obj) { - PyErr_Format(PyExc_ValueError, "No un-named item %i !?", arg_i); - goto fail; - } - argName = PyTuple_GetItem(tmp_obj, 0); - if (! PyString_Check(argName)) { - PyErr_SetString(PyExc_TypeError, "keywords must be strings"); - goto fail; - } - argValue = PyTuple_GetItem(tmp_obj, 1); - is_SexpObject = PyObject_TypeCheck(argValue, &Sexp_Type); - if (! is_SexpObject) { - PyErr_Format(PyExc_ValueError, "All parameters must be of type Sexp_Type."); - goto fail; - } - Py_DECREF(tmp_obj); - tmp_R = ((SexpObject *)argValue)->sexp; - SETCAR(c_R, tmp_R); - argNameString = PyString_AsString(argName); - SET_TAG(c_R, install(argNameString)); + + for (arg_i=0; arg_i<lkwds; arg_i++) { + tmp_obj = PySequence_GetItem(citems, arg_i); + if (! tmp_obj) { + PyErr_Format(PyExc_ValueError, "No un-named item %i !?", arg_i); + + Py_XDECREF(citems); + goto fail; + } + argName = PyTuple_GetItem(tmp_obj, 0); + if (! PyString_Check(argName)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + + Py_XDECREF(citems); + goto fail; + } + argValue = PyTuple_GetItem(tmp_obj, 1); + is_SexpObject = PyObject_TypeCheck(argValue, &Sexp_Type); + if (! is_SexpObject) { + PyErr_Format(PyExc_ValueError, + "All parameters must be of type Sexp_Type."); + + Py_XDECREF(citems); + goto fail; + } + Py_DECREF(tmp_obj); + tmp_R = ((SexpObject *)argValue)->sexp; + if (! tmp_R) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + + Py_XDECREF(citems); + goto fail; + } + SETCAR(c_R, tmp_R); + argNameString = PyString_AsString(argName); + SET_TAG(c_R, install(argNameString)); //printf("PyMem_Free..."); //PyMem_Free(argNameString); - c_R = CDR(c_R); + c_R = CDR(c_R); + } + Py_XDECREF(citems); } - Py_XDECREF(citems); //FIXME: R_GlobalContext ? PROTECT(res_R = do_eval_expr(call_R)); @@ -481,7 +514,6 @@ fail: printf("failed.\n"); - Py_XDECREF(citems); Py_DECREF(tmp_obj); UNPROTECT(1); return NULL; @@ -494,7 +526,13 @@ static SexpObject* Sexp_closureEnv(PyObject *self) { - SEXP closureEnv = CLOENV(((SexpObject*)self)->sexp); + SEXP closureEnv, sexp; + sexp = ((SexpObject*)self)->sexp; + if (! sexp) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL; + } + closureEnv = CLOENV(sexp); return newSexpObject(closureEnv); } PyDoc_STRVAR(Sexp_closureEnv_doc, @@ -583,7 +621,12 @@ { Py_ssize_t len; //FIXME: sanity checks. - len = (Py_ssize_t)GET_LENGTH(((SexpObject *)object)->sexp); + SEXP sexp = ((SexpObject *)object)->sexp; + if (! sexp) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL; + } + len = (Py_ssize_t)GET_LENGTH(sexp); return len; } @@ -594,6 +637,12 @@ PyObject* res; R_len_t i_R; SEXP *sexp = &(((SexpObject *)object)->sexp); + + if (! sexp) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL; + } + /* R is still with int for indexes */ if (i >= R_LEN_T_MAX) { PyErr_Format(PyExc_IndexError, "Index value exceeds what R can handle."); @@ -729,13 +778,17 @@ EnvironmentSexp_findVar(PyObject *self, PyObject *args) { char *name; - SEXP res_R; + SEXP res_R = NULL; if (!PyArg_ParseTuple(args, "s", &name)) { return NULL; } const SEXP rho_R = ((SexpObject *)self)->sexp; + if (! rho_R) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL; + } if (rho_R == R_EmptyEnv) { PyErr_Format(PyExc_LookupError, "Fatal error: R_UnboundValue."); @@ -765,7 +818,7 @@ EnvironmentSexp_subscript(PyObject *self, PyObject *key) { char *name; - SEXP res_R; + SEXP res_R = NULL; if (!PyString_Check(key)) { PyErr_Format(PyExc_ValueError, "Keys must be string objects."); @@ -775,6 +828,10 @@ name = PyString_AsString(key); SEXP rho_R = ((SexpObject *)self)->sexp; + if (! rho_R) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL; + } res_R = findVarInFrame(rho_R, install(name)); if (res_R != R_UnboundValue) { @@ -788,7 +845,6 @@ Not all R environment are hash tables, and this may\ influence performances when doing repeated lookups."); -//FIXME: Is this still needed ? static PyMappingMethods EnvironmentSexp_mappignMethods = { 0, /* mp_length */ EnvironmentSexp_subscript, /* mp_subscript */ @@ -922,7 +978,11 @@ { SexpObject *object; SEXP sexp_ok, env_R; - + + if (! sexp) { + PyErr_Format(PyExc_ValueError, "NULL SEXP."); + return NULL; + } //FIXME: let the possibility to manipulate un-evaluated promises ? if (TYPEOF(sexp) == PROMSXP) { env_R = PRENV(sexp); @@ -938,7 +998,8 @@ case CLOSXP: case BUILTINSXP: case SPECIALSXP: - object = (SexpObject *)_PyObject_New(&ClosureSexp_Type); + object = (SexpObject *)PyObject_New(SexpObject, + &ClosureSexp_Type); break; //FIXME: BUILTINSXP and SPECIALSXP really like CLOSXP ? case REALSXP: @@ -947,16 +1008,20 @@ case CPLXSXP: case VECSXP: case STRSXP: - object = (SexpObject *)_PyObject_New(&VectorSexp_Type); + object = (SexpObject *)PyObject_New(SexpObject, + &VectorSexp_Type); break; case ENVSXP: - object = (SexpObject *)_PyObject_New(&EnvironmentSexp_Type); + object = (SexpObject *)PyObject_New(SexpObject, + &EnvironmentSexp_Type); break; case S4SXP: - object = (SexpObject *)_PyObject_New(&S4Sexp_Type); + object = (SexpObject *)PyObject_New(SexpObject, + &S4Sexp_Type); break; default: - object = (SexpObject *)_PyObject_New(&Sexp_Type); + object = (SexpObject *)PyObject_New(SexpObject, + &Sexp_Type); break; } if (!object) { @@ -964,6 +1029,7 @@ PyErr_NoMemory(); return NULL; } + //PyObject_Init(&object, &ClosureSexp_Type); object->sexp = sexp_ok; //FIXME: Increment reference ? //Py_INCREF(object); @@ -1028,10 +1094,12 @@ if((item = PyObject_Str(PySequence_Fast_GET_ITEM(seq_object, i)))) { SEXP str_R = mkChar(PyString_AS_STRING(item)); if (!str_R) { + Py_DECREF(item); PyErr_NoMemory(); sexp = NULL; break; } + Py_DECREF(item); SET_STRING_ELT(sexp, i, str_R); } else { @@ -1045,11 +1113,13 @@ if((item = PySequence_Fast_GET_ITEM(seq_object, i))) { int is_SexpObject = PyObject_TypeCheck(item, &Sexp_Type); if (! is_SexpObject) { + Py_DECREF(item); PyErr_Format(PyExc_ValueError, "All elements of the list must be of " "type 'Sexp_Type'."); return NULL; } SET_ELEMENT(sexp, i, ((SexpObject *)item)->sexp); + Py_DECREF(item); } } //FIXME: add complex @@ -1170,14 +1240,16 @@ Py_INCREF(ErrorObject); PyModule_AddObject(m, "RobjectNotFound", ErrorObject); - globalEnv = (SexpObject *)_PyObject_New(&EnvironmentSexp_Type); + globalEnv = (SexpObject *)PyObject_New(SexpObject, + &EnvironmentSexp_Type); globalEnv->sexp = R_EmptyEnv; if (PyDict_SetItemString(d, "globalEnv", (PyObject *)globalEnv) < 0) return; //FIXME: DECREF ? Py_DECREF(globalEnv); - baseNameSpaceEnv = (SexpObject*)_PyObject_New(&EnvironmentSexp_Type); + baseNameSpaceEnv = (SexpObject*)PyObject_New(SexpObject, + &EnvironmentSexp_Type); baseNameSpaceEnv->sexp = R_EmptyEnv; if (PyDict_SetItemString(d, "baseNameSpaceEnv", (PyObject *)baseNameSpaceEnv) < 0) return; @@ -1224,7 +1296,8 @@ /* Rinternals.h */ - SexpObject *na_string = (SexpObject *)_PyObject_New(&VectorSexp_Type); + SexpObject *na_string = (SexpObject *)PyObject_New(SexpObject, + &VectorSexp_Type); na_string->sexp = NA_STRING; if (PyDict_SetItemString(d, "NA_STRING", (PyObject *)na_string) < 0) return; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ rpy-list mailing list rpy-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rpy-list