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
[email protected]
https://lists.sourceforge.net/lists/listinfo/rpy-list