2
* $Id: rpymodule.c 299 2006-03-22 22:13:54Z warnes $
3
* Implementation of the module '_rpy' and the 'Robj' type.
6
/* ***** BEGIN LICENSE BLOCK *****
7
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
9
* The contents of this file are subject to the Mozilla Public License Version
10
* 1.1 (the "License"); you may not use this file except in compliance with
11
* the License. You may obtain a copy of the License at
12
* http://www.mozilla.org/MPL/
14
* Software distributed under the License is distributed on an "AS IS" basis,
15
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16
* for the specific language governing rights and limitations under the
19
* The Original Code is the RPy python module.
21
* The Initial Developer of the Original Code is Walter Moreira.
22
* Portions created by the Initial Developer are Copyright (C) 2002
23
* the Initial Developer. All Rights Reserved.
26
* Gregory R. Warnes <greg@warnes.net> (Maintainer)
28
* Alternatively, the contents of this file may be used under the terms of
29
* either the GNU General Public License Version 2 or later (the "GPL"), or
30
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31
* in which case the provisions of the GPL or the LGPL are applicable instead
32
* of those above. If you wish to allow use of your version of this file only
33
* under the terms of either the GPL or the LGPL, and not to allow others to
34
* use your version of this file under the terms of the MPL, indicate your
35
* decision by deleting the provisions above and replace them with the notice
36
* and other provisions required by the GPL or the LGPL. If you do not delete
37
* the provisions above, a recipient may use your version of this file under
38
* the terms of any one of the MPL, the GPL or the LGPL.
40
* ***** END LICENSE BLOCK ***** */
44
#define NONAMELESSUNION
49
/* Flag indicating whether Numeric is available in this session
51
* This is necessary Numeric may not available at run time, even if
52
* it was available at compile time.
54
static int use_numeric=0;
57
/* Local function definitions */
58
DL_EXPORT(void) INIT_RPY(void); /* Module initializer */
59
static PyObject *r_init(PyObject *self, /* Class initializer */
61
static PyObject *r_cleanup(void); /* Clean up R & release resources */
64
static void init_embedded_win32( void );
72
static PyObject *class_table;
73
static PyObject *proc_table;
74
static int default_mode;
75
static PyObject *r_lock;
76
PyObject *RPyExc_Exception;
78
static char RHOME[BUFSIZ];
79
static char RVERSION[BUFSIZ];
80
static char RVER[BUFSIZ];
81
static char RUSER[BUFSIZ];
83
/* Global interpreter */
84
PyInterpreterState *my_interp;
86
/* Signal whether R is running interactively */
95
static PyObject *Py_transpose;
98
/* Global list to protect R objects from garbage collection */
99
/* This is inspired in $R_SRC/src/main/memory.c */
100
static SEXP R_References;
103
RecursiveRelease(SEXP obj, SEXP list)
106
if (obj == CAR(list))
109
SETCDR(list, RecursiveRelease(obj, CDR(list)));
114
/* Robj methods. Following xxmodule.c from Python distro. */
117
Robj_dealloc(RobjObject *self)
119
/* Remove the object from the list of protected objects */
120
R_References = RecursiveRelease(self->R_obj, R_References);
121
SET_SYMVALUE(install("R.References"), R_References);
127
Robj_new(SEXP robj, int conversion)
130
self = PyObject_New(RobjObject, &Robj_Type);
137
/* Protect the R object */
138
R_References = CONS(robj, R_References);
139
SET_SYMVALUE(install("R.References"), R_References);
142
self->conversion = conversion;
148
Robj_tpnew(PyTypeObject *type, PyObject *args, PyObject *kwds)
152
self = type->tp_alloc(type, 0);
157
/* Type conversion routines. See documentation for details */
159
/* These are auxiliaries for a state machine for converting Python
160
list to the coarsest R vector type */
170
type_to_int(PyObject *obj)
172
if (PyBool_Check(obj))
174
else if (PyInt_Check(obj))
176
else if (PyFloat_Check(obj))
178
else if (PyComplex_Check(obj))
180
else if (PyNumber_Check(obj))
182
else if (PyString_Check(obj))
184
else if (Robj_Check(obj))
190
/* Make a R list or vector from a Python sequence */
192
seq_to_R(PyObject *obj)
198
/* This matrix defines what mode a vector should take given what
199
it already contains and a new item
201
E.g. Row 0 indicates that if we've seen an any, the vector will
202
always remain an any. Row 3 indicates that if we've seen a
203
float, then seeing an boolean, integer, or float will preserve
204
the vector as a float vector, while seeing a string or an Robj will
205
convert it into an any vector.
208
{0, 0, 0, 0, 0, 0, 0}, // any
209
{0, 1, 2, 3, 4, 0, 0}, // bool
210
{0, 2, 2, 3, 4, 0, 0}, // int
211
{0, 3, 3, 3, 4, 0, 0}, // float
212
{0, 4, 4, 4, 4, 0, 0}, // complex
213
{0, 0, 0, 0, 0, 5, 0}, // string
214
{0, 0, 0, 0, 0, 0, 6} // RObj
217
len = PySequence_Length(obj);
221
PROTECT(robj = NEW_LIST(len));
224
for (i=0; i<len; i++) {
225
if (!(it = PySequence_GetItem(obj, i)))
229
state = type_to_int(it);
231
state = fsm[state][type_to_int(it)];
233
if (!(rit = to_Robj(it)))
236
SET_VECTOR_ELT(robj, i, rit);
243
robj = AS_INTEGER(robj);
246
robj = AS_LOGICAL(robj);
249
robj = AS_NUMERIC(robj);
252
robj = AS_COMPLEX(robj);
255
robj = AS_CHARACTER(robj);
258
/* Otherwise, it's either an ANY_T or ROBJ_T - we want ANY */
270
/* Make a R named list or vector from a Python dictionary */
272
dict_to_R(PyObject *obj)
275
PyObject *keys, *values;
278
len = PyMapping_Length(obj);
282
/* If 'keys' succeed and 'values' fails this leaks */
283
if (!(keys = PyMapping_Keys(obj)))
285
if (!(values = PyMapping_Values(obj)))
288
if (!(robj = seq_to_R(values)))
290
if (!(names = seq_to_R(keys)))
293
SET_NAMES(robj, names);
307
/* Convert a Numeric array to a R array */
309
to_Rarray(PyObject *o)
311
PyObject *pytl, *nobj;
313
SEXP Rdims, tRdims, Rarray, e;
317
obj = (PyArrayObject *)o;
318
dims = obj->dimensions;
320
PROTECT(Rdims = allocVector(INTSXP, obj->nd));
321
PROTECT(tRdims = allocVector(INTSXP, obj->nd));
322
for (i=0; i<obj->nd; i++) {
328
INTEGER(Rdims)[i] = dims[(obj->nd)-i-1];
329
INTEGER(tRdims)[i] = (obj->nd)-i;
332
/* if (!(pytl = PyList_New(1))) */
333
/* goto exception; */
334
/* if (!(it = PyInt_FromLong(tl))) */
335
/* goto exception; */
336
/* if (PyList_SetItem(pytl, 0, it) < 0) */
337
/* goto exception; */
339
pytl = Py_BuildValue("[i]", tl);
340
obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj,
341
PyArray_NOTYPE, 0, 0);
342
nobj = PyArray_Reshape(obj, pytl);
348
PROTECT(Rarray = seq_to_R(nobj));
350
SET_DIM(Rarray, Rdims);
352
PROTECT(e = allocVector(LANGSXP, 3));
354
SETCAR(CDR(e), Rarray);
355
SETCAR(CDR(CDR(e)), tRdims);
356
PROTECT(Rarray = do_eval_expr(e));
367
/* Convert a Python object to a R object. An Robj is passed w/o
368
* modifications, an object which provides a '.as_r()' method, is
369
* passed as the result of that method */
371
to_Robj(PyObject *obj)
381
if (obj == Py_None) {
385
to_r_meth = PyObject_GetAttrString(obj, "as_r");
387
obj = PyObject_CallObject(to_r_meth, NULL);
388
Py_DECREF(to_r_meth);
398
PROTECT(robj = ((RobjObject *)obj)->R_obj);
400
else if (PyBool_Check(obj))
402
PROTECT(robj = NEW_LOGICAL(1));
403
LOGICAL_DATA(robj)[0] = (Py_True==obj);
405
else if (PyInt_Check(obj))
407
PROTECT(robj = NEW_INTEGER(1));
408
INTEGER_DATA(robj)[0] = (int) PyInt_AsLong(obj);
410
else if (PyFloat_Check(obj))
412
PROTECT(robj = NEW_NUMERIC(1));
413
NUMERIC_DATA(robj)[0] = PyFloat_AsDouble(obj);
415
else if (PyComplex_Check(obj))
417
PROTECT(robj = NEW_COMPLEX(1));
418
c = PyComplex_AsCComplex(obj);
419
COMPLEX_DATA(robj)[0].r = c.real;
420
COMPLEX_DATA(robj)[0].i = c.imag;
422
else if (PyString_Check(obj))
424
PROTECT(robj = NEW_STRING(1));
425
SET_STRING_ELT(robj, 0, COPY_TO_USER_STRING(PyString_AsString(obj)));
428
//else if (PyArray_Check(obj))
429
else if (use_numeric && PyArray_Check(obj))
431
PROTECT(robj = to_Rarray(obj));
434
else if ((PySequence_Check(obj)) &&
435
(PySequence_Size(obj) >= 0))
437
PROTECT(robj = seq_to_R(obj)); /* No labels */
439
else if ((PyMapping_Check(obj)) &&
440
(PyMapping_Size(obj) >= 0))
442
PROTECT(robj = dict_to_R(obj));
446
PyErr_Format(RPyExc_Exception, "cannot convert from type '%s'",
447
obj->ob_type->tp_name);
448
PROTECT(robj = NULL); /* Protected to avoid stack inbalance */
459
/* Convert a R named vector or list to a Python dictionary */
461
to_PyDict(PyObject *obj, SEXP names)
467
if ((len = PySequence_Length(obj)) < 0)
471
for (i=0; i<len; i++) {
472
if (!(it = PyList_GetItem(obj, i)))
475
name = CHAR(STRING_ELT(names, i));
476
if ((PyDict_SetItemString(dict, name, it)) < 0) {
484
/* We need to transpose the list because R makes array by the
487
ltranspose(PyObject *list, int *dims, int *strides,
488
int pos, int shift, int len)
493
if (!(nl = PyList_New(dims[pos])))
497
for (i=0; i<dims[pos]; i++) {
498
if (!(it = PyList_GetItem(list, i*strides[pos]+shift)))
501
if (PyList_SetItem(nl, i, it) < 0)
507
for (i=0; i<dims[pos]; i++) {
508
if (!(it = ltranspose(list, dims, strides, pos+1, shift, len)))
510
if (PyList_SetItem(nl, i, it) < 0)
512
shift += strides[pos];
518
/* Convert a Python list to a Python array (in the form of
519
* list of lists of ...) */
521
to_PyArray(PyObject *obj, int *dims, int l)
526
strides = (int *)PyMem_Malloc(l*sizeof(int));
531
for (i=0; i<l; i++) {
536
list = ltranspose(obj, dims, strides, 0, 0, l);
542
/* Convert a Python sequence to a Numeric array */
545
to_PyNumericArray(PyObject *seq, SEXP dim)
547
PyObject *array, *ret, *dims, *it;
550
array = PyArray_ContiguousFromObject(seq, PyArray_NOTYPE, 0,0);
555
dims = PyList_New(l);
556
for (i=0; i<l; i++) {
557
j = INTEGER(dim)[l-i-1];
564
if (!(it = PyInt_FromLong(j)))
566
if (PyList_SetItem(dims, i, it) < 0)
570
ret = PyArray_Reshape((PyArrayObject *)array, dims);
576
array = PyObject_CallFunction(Py_transpose, "O", ret);
582
/* Convert an R object to a 'basic' Python object (mode 2) */
583
/* NOTE: R vectors of length 1 will yield a python scalar */
585
to_Pyobj_basic(SEXP robj, PyObject **obj)
590
status = to_Pyobj_vector(robj, &tmp, BASIC_CONVERSION);
592
if(status==1 && PyList_Check(tmp) && PyList_Size(tmp) == 1)
594
*obj = PyList_GetItem(tmp, 0);
605
/* Convert an R object to a 'vector' Python object (mode 1) */
606
/* NOTE: R vectors of length 1 will yield a python list of length 1*/
608
to_Pyobj_vector(SEXP robj, PyObject **obj, int mode)
612
int len, *integers, i, type;
613
char *strings, *thislevel;
621
return -1; /* error */
623
if (robj == R_NilValue) {
626
return 1; /* succeed */
629
len = GET_LENGTH(robj);
630
tmp = PyList_New(len);
633
for (i=0; i<len; i++) {
637
integers = INTEGER(robj);
638
if(integers[i]==NA_INTEGER) /* watch out for NA's */
640
if (!(it = PyInt_FromLong(integers[i])))
644
else if (!(it = PyBool_FromLong(integers[i])))
648
integers = INTEGER(robj);
650
/* Watch for NA's! */
651
if(integers[i]==NA_INTEGER)
652
it = PyString_FromString(CHAR(NA_STRING));
655
thislevel = CHAR(STRING_ELT(GET_LEVELS(robj), integers[i]-1));
656
if (!(it = PyString_FromString(thislevel)))
661
if (!(it = PyInt_FromLong(integers[i])))
667
if (!(it = PyFloat_FromDouble(reals[i])))
671
complexes = COMPLEX(robj);
672
if (!(it = PyComplex_FromDoubles(complexes[i].r,
677
if(STRING_ELT(robj, i)==R_NaString)
678
it = PyString_FromString(CHAR(NA_STRING));
681
strings = CHAR(STRING_ELT(robj, i));
682
if (!(it = PyString_FromString(strings)))
687
if (!(it = to_Pyobj_with_mode(elt(robj, i), mode)))
691
if (!(it = to_Pyobj_with_mode(VECTOR_ELT(robj, i), mode)))
696
return 0; /* failed */
699
if (PyList_SetItem(tmp, i, it) < 0)
704
if (dim != R_NilValue) {
708
array = to_PyNumericArray(tmp, dim);
709
if (array) { /* If the conversion to Numeric succeed.. */
710
*obj = array; /* we are done */
717
len = GET_LENGTH(dim);
718
*obj = to_PyArray(tmp, INTEGER(dim), len);
723
names = GET_NAMES(robj);
724
if (names == R_NilValue)
727
*obj = to_PyDict(tmp, names);
733
/* Search a conversion procedure from the class attribute */
735
from_class_table(SEXP robj)
738
PyObject *lkey, *key, *fun;
741
PROTECT(rclass = GET_CLASS(robj));
744
if (rclass != R_NilValue) {
746
lkey = to_Pyobj_with_mode(rclass, BASIC_CONVERSION);
747
key = PyList_AsTuple(lkey);
754
fun = PyDict_GetItem(class_table, key);
759
for (i=0; i<GET_LENGTH(rclass); i++)
760
if ((fun = PyDict_GetItemString(class_table,
761
CHAR(STRING_ELT(rclass, i)))))
771
/* Search a conversion procedure from the proc table */
773
from_proc_table(SEXP robj, PyObject **fun)
775
PyObject *procs, *proc, *funs, *res, *obj;
779
procs = PyDict_Keys(proc_table);
780
funs = PyDict_Values(proc_table);
781
l = PyMapping_Size(proc_table);
783
obj = (PyObject *)Robj_new(robj, TOP_MODE);
786
for (i=0; i<l; i++) {
787
proc = PyList_GetItem(procs, i);
789
res = PyObject_CallFunction(proc, "O", obj);
794
k = PyObject_IsTrue(res);
797
*fun = PyList_GetItem(funs, i);
811
to_Pyobj_proc(SEXP robj, PyObject **obj)
813
PyObject *fun=NULL, *tmp;
816
i = from_proc_table(robj, &fun);
818
return -1; /* an error occurred */
821
return 0; /* conversion failed */
823
tmp = (PyObject *)Robj_new(robj, TOP_MODE);
824
*obj = PyObject_CallFunction(fun, "O", tmp);
827
return 1; /* conversion succeed */
830
/* Convert a Robj to a Python object via the class table (mode 3) */
831
/* See the docs for conversion rules */
833
to_Pyobj_class(SEXP robj, PyObject **obj)
837
fun = from_class_table(robj);
840
return 0; /* conversion failed */
842
tmp = (PyObject *)Robj_new(robj, TOP_MODE);
843
*obj = PyObject_CallFunction(fun, "O", tmp);
846
return 1; /* conversion succeed */
850
to_Pyobj_with_mode(SEXP robj, int mode)
857
case PROC_CONVERSION:
858
i = to_Pyobj_proc(robj, &obj);
859
if (i<0) return NULL;
861
case CLASS_CONVERSION:
862
i = to_Pyobj_class(robj, &obj);
863
if (i<0) return NULL;
865
case BASIC_CONVERSION:
866
i = to_Pyobj_basic(robj, &obj);
867
if (i<0) return NULL;
869
case VECTOR_CONVERSION:
870
i = to_Pyobj_vector(robj, &obj, mode=VECTOR_CONVERSION);
871
if (i<0) return NULL;
874
obj = (PyObject *)Robj_new(robj, TOP_MODE);
880
/* Convert a tuple to arguments for a R function */
882
make_args(int largs, PyObject *args, SEXP *e)
887
for (i=0; i<largs; i++) {
888
r = to_Robj(PyTuple_GetItem(args, i));
897
/* Implements the conversion rules for names. See the 'USING' file. We
898
don't care about '<-' because it doesn't appear in keywords. */
906
return NULL; /* assume prev PyString_AsString has failed */
908
r = (char *)PyMem_Malloc(l+1);
915
if ((l > 1) && (res[l-1] == '_') && (res[l-2] != '_'))
918
while ((r=strchr(r, '_')))
924
/* Convert a dict to keywords arguments for a R function */
926
make_kwds(int lkwds, PyObject *kwds, SEXP *e)
931
PyObject *citems=NULL, *it;
935
citems = PyMapping_Items(kwds);
938
for (i=0; i<lkwds; i++) {
939
it = PySequence_GetItem(citems, i);
942
r = to_Robj(PyTuple_GetItem(it, 1));
948
kwname = PyTuple_GetItem(it, 0);
951
if (!PyString_Check(kwname)) {
952
PyErr_SetString(PyExc_TypeError, "keywords must be strings");
955
s = dotter(PyString_AsString(kwname));
959
SET_TAG(*e, Rf_install(s));
972
/* This is the method to call when invoking an 'Robj' */
974
Robj_call(PyObject *self, PyObject *args, PyObject *kwds)
977
int largs, lkwds, conv;
982
largs = PyObject_Length(args);
984
lkwds = PyObject_Length(kwds);
985
if ((largs<0) || (lkwds<0))
988
/* A SEXP with the function to call and the arguments and keywords. */
989
PROTECT(exp = allocVector(LANGSXP, largs+lkwds+1));
991
SETCAR(e, ((RobjObject *)self)->R_obj);
994
if (!make_args(largs, args, &e)) {
998
if (!make_kwds(lkwds, kwds, &e)) {
1003
PROTECT(res = do_eval_expr(exp));
1009
if (default_mode < 0)
1010
conv = ((RobjObject *)self)->conversion;
1012
conv = default_mode;
1014
obj = to_Pyobj_with_mode(res, conv);
1017
PrintWarnings(); /* show any warning messages */
1022
/* Convert a sequence of (name, value) pairs to arguments to an R
1025
make_argl(int largl, PyObject *argl, SEXP *e)
1030
PyObject *it, *nobj, *value;
1032
if( !PySequence_Check(argl) ) goto fail_arg;
1034
for (i=0; i<largl; i++) {
1035
it = PySequence_GetItem(argl, i);
1036
if(!it) goto fail_arg;
1037
if( PySequence_Size(it) != 2 )
1042
nobj = PySequence_GetItem(it, 0);
1044
/* Name can be a string, None, or NULL, error otherwise. */
1045
if (PyString_Check(nobj))
1047
name = dotter(PyString_AsString(nobj));
1050
else if (nobj == Py_None)
1055
else if(nobj == NULL)
1065
/* Value can be anything. */
1066
value = PySequence_GetItem(it, 1);
1073
rvalue = to_Robj(value);
1078
/* Add parameter value to call */
1081
/* Add name (if present) */
1082
if (name && strlen(name)>0)
1084
SET_TAG(*e, Rf_install(name));
1088
/* Move index to new end of call */
1094
PyErr_SetString(PyExc_ValueError,
1095
"Argument must be a sequence of (\"name\", value) pairs.\n");
1100
/* Methods for the 'Robj' type */
1102
/* Explicitly call an R object with a list containing (name, value) *
1103
* argument pairs. 'name' can be None or '' to provide unnamed
1104
* arguments. This function is necessary when the *order* of named
1105
* arguments needs to be preserved.
1109
Robj_lcall(PyObject *self, PyObject *args)
1112
int largs, largl, conv;
1113
PyObject *obj, *argl;
1115
/* Check arguments, there should be *exactly one* unnamed sequence. */
1118
largs = PyObject_Length(args);
1122
if(largs != 1 || !PySequence_Check(args) )
1124
PyErr_SetString(PyExc_ValueError,
1125
"Argument must be a sequence of (\"name\", value) pairs.\n");
1129
// extract our one argument
1130
argl = PySequence_GetItem(args, 0);
1135
largl = PyObject_Length(argl);
1139
// A SEXP with the function to call and the arguments
1140
PROTECT(exp = allocVector(LANGSXP, largl+1));
1142
SETCAR(e, ((RobjObject *)self)->R_obj);
1145
// Add the arguments to the SEXP
1146
if (!make_argl(largl, argl, &e)) {
1152
PROTECT(res = do_eval_expr(exp));
1159
if (default_mode < 0)
1160
conv = ((RobjObject *)self)->conversion;
1162
conv = default_mode;
1164
obj = to_Pyobj_with_mode(res, conv);
1172
/* Without args return the value of the conversion flag. With an
1173
argument set the conversion flag to the truth value of the argument. */
1175
Robj_autoconvert(PyObject *self, PyObject *args, PyObject *kwds)
1179
static char *kwlist[] = {"val", 0};
1181
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:autoconvert", kwlist,
1185
if (conversion > TOP_MODE) {
1186
PyErr_SetString(PyExc_ValueError, "wrong mode");
1190
if (conversion == -2) {
1191
obj = PyInt_FromLong((long)((RobjObject *)self)->conversion);
1193
((RobjObject *)self)->conversion = conversion;
1202
Robj_as_py(PyObject *self, PyObject *args, PyObject *kwds)
1205
static char *kwlist[] = {"mode", 0};
1206
int conv=default_mode;
1208
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:as_py", kwlist,
1212
if (conv <= -2 || conv > TOP_MODE) {
1213
PyErr_SetString(PyExc_ValueError, "wrong mode");
1220
obj = to_Pyobj_with_mode(((RobjObject *)self)->R_obj, conv);
1224
static PyMethodDef Robj_methods[] = {
1225
{"autoconvert", (PyCFunction)Robj_autoconvert, METH_VARARGS|METH_KEYWORDS},
1226
{"local_mode", (PyCFunction)Robj_autoconvert, METH_VARARGS|METH_KEYWORDS},
1227
{"as_py", (PyCFunction)Robj_as_py, METH_VARARGS|METH_KEYWORDS},
1228
{"lcall", (PyCFunction)Robj_lcall, METH_VARARGS},
1229
{NULL, NULL} /* sentinel */
1232
/* Sequence protocol implementation */
1236
Robj_len(PyObject *a)
1240
PROTECT(e = allocVector(LANGSXP, 2));
1242
SETCAR(CDR(e), ((RobjObject *)a)->R_obj);
1244
if (!(robj = do_eval_expr(e))) {
1250
return INTEGER_DATA(robj)[0];
1255
Robj_ass_item(PyObject *a, int i, PyObject *v)
1259
PROTECT(e = allocVector(LANGSXP, 4));
1260
ri = NEW_INTEGER(1);
1261
INTEGER_DATA(ri)[0] = i+1;
1262
SETCAR(e, set_item);
1263
SETCAR(CDR(e), ((RobjObject *)a)->R_obj);
1264
SETCAR(CDR(CDR(e)), ri);
1265
SETCAR(CDR(CDR(CDR(e))), to_Robj(v));
1267
if (!(robj = do_eval_expr(e))) {
1272
((RobjObject *)a)->R_obj = robj;
1279
Robj_item(PyObject *a, int i)
1285
if ((len = Robj_len(a)) < 0)
1287
if (i >= len || i < 0) {
1288
PyErr_SetString(PyExc_IndexError, "R object index out of range");
1292
PROTECT(ri = NEW_INTEGER(1));
1293
INTEGER_DATA(ri)[0] = i+1;
1294
PROTECT(e = allocVector(LANGSXP, 3));
1295
SETCAR(e, get_item);
1296
SETCAR(CDR(e), ((RobjObject *)a)->R_obj);
1297
SETCAR(CDR(CDR(e)), ri);
1299
if (!(robj = do_eval_expr(e))) {
1306
/* If there is a default mode, use it; otherwise, use the top mode. */
1307
if (default_mode < 0)
1311
obj = to_Pyobj_with_mode(robj, c);
1315
/* We should implement sq_slice, sq_contains ... */
1316
static PySequenceMethods Robj_as_sequence = {
1317
(inquiry)Robj_len, /* sq_length */
1320
(intargfunc)Robj_item, /* sq_item */
1322
(intobjargproc)Robj_ass_item, /* sq_ass_item */
1323
0, /* sq_ass_slice */
1324
0, /* sq_contains */
1328
/* The 'Robj' table. When compiled under Python 2.2, the type 'Robj'
1333
Robj_getattr(RobjObject *self, char *name)
1335
return Py_FindMethod(Robj_methods, (PyObject *)self, name);
1339
PyTypeObject Robj_Type = {
1340
/* The ob_type field must be initialized in the module init function
1341
* to be portable to Windows without using C++. */
1342
#if defined(PRE_2_2) || defined(_WIN32) // Matjaz
1343
PyObject_HEAD_INIT(NULL)
1345
PyObject_HEAD_INIT(&PyType_Type)
1349
sizeof(RobjObject), /*tp_basicsize*/
1352
(destructor)Robj_dealloc, /*tp_dealloc*/
1355
(getattrfunc)Robj_getattr,
1363
&Robj_as_sequence, /*tp_as_sequence*/
1364
0, /*tp_as_mapping*/
1366
(ternaryfunc)Robj_call, /*tp_call*/
1368
#if defined(PRE_2_2) || defined(_WIN32)
1371
PyObject_GenericGetAttr, /*tp_getattro*/
1378
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1384
0, /*tp_richcompare*/
1385
0, /*tp_weaklistoffset*/
1388
Robj_methods, /*tp_methods*/
1395
0, /*tp_dictoffset*/
1400
PyType_GenericAlloc, /*tp_alloc*/
1402
Robj_tpnew, /*tp_new*/
1409
/* Module functions */
1411
/* Obtain an R object via its name. 'autoconvert' is the keyword to
1412
set the autoconversion flag. */
1414
get_fun(PyObject *self, PyObject *args, PyObject *kwds)
1417
int conversion=TOP_MODE;
1420
static char *kwlist[] = {"name", "autoconvert", 0};
1421
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:get", kwlist,
1422
&obj_str, &conversion))
1425
robj = get_fun_from_name(obj_str);
1429
return (PyObject *)Robj_new(robj, conversion);
1433
set_mode(PyObject *self, PyObject *args)
1437
if (!PyArg_ParseTuple(args, "i:set_mode", &i))
1440
if (i<-1 || i>TOP_MODE) {
1441
PyErr_SetString(PyExc_ValueError, "wrong mode");
1451
get_mode(PyObject *self, PyObject *args)
1453
if (!PyArg_ParseTuple(args, ":get_mode"))
1456
return PyInt_FromLong(default_mode);
1460
r_events(PyObject *self, PyObject *args, PyObject *kwds)
1470
static char *kwlist[] = {"usec", 0};
1471
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:r_events",
1476
Py_BEGIN_ALLOW_THREADS
1477
what = R_checkActivity(usec, 0);
1478
R_runHandlers(R_InputHandlers, what);
1479
Py_END_ALLOW_THREADS
1496
r_lock = PyDict_GetItemString(rpy_dict, "_r_lock");
1498
o = PyObject_CallMethod(r_lock, "acquire", NULL);
1511
r_lock = PyDict_GetItemString(rpy_dict, "_r_lock");
1513
o = PyObject_CallMethod(r_lock, "release", NULL);
1519
* Based on code from Rstd_CleanUp();
1520
* from src/unix/sys-std.c
1523
void r_finalize(void)
1525
unsigned char buf[1024];
1529
R_RunExitFinalizers();
1532
if((tmpdir = getenv("R_SESSION_TMPDIR"))) {
1533
snprintf((char *)buf, 1024, "rm -rf %s", tmpdir);
1534
R_system((char *)buf);
1537
PrintWarnings(); /* from device close and .Last */
1538
R_gc(); /* Remove any remaining R objects from memory */
1554
PyObject *multiarray, *dict;
1559
multiarray = PyImport_ImportModule("multiarray");
1561
dict = PyModule_GetDict(multiarray);
1563
Py_transpose = PyDict_GetItemString(dict, "transpose");
1570
r_init(PyObject *self, PyObject *args)
1575
if (!PyArg_ParseTuple(args, "i:r_init", &i))
1592
PyErr_SetString(PyExc_RuntimeError, "Only one R object may be instantiated per session");
1597
/* List of functions defined in the module */
1598
static PyMethodDef rpy_methods[] = {
1599
{"get_fun", (PyCFunction)get_fun, METH_VARARGS | METH_KEYWORDS},
1600
{"set_mode", (PyCFunction)set_mode, METH_VARARGS},
1601
{"get_mode", (PyCFunction)get_mode, METH_VARARGS},
1602
{"set_output", (PyCFunction)set_output, METH_VARARGS},
1603
{"set_input", (PyCFunction)set_input, METH_VARARGS},
1604
{"set_showfiles", (PyCFunction)set_showfiles, METH_VARARGS},
1605
{"get_output", (PyCFunction)get_output, METH_VARARGS},
1606
{"get_input", (PyCFunction)get_input, METH_VARARGS},
1607
{"get_showfiles", (PyCFunction)get_showfiles, METH_VARARGS},
1608
{"r_events", (PyCFunction)r_events, METH_VARARGS | METH_KEYWORDS},
1609
{"r_cleanup", (PyCFunction)r_cleanup, METH_NOARGS},
1610
{"r_init", (PyCFunction)r_init, METH_VARARGS},
1611
{NULL, NULL} /* sentinel */
1615
static void char_message( char *s )
1618
R_WriteConsole(s, strlen(s));
1621
static int char_yesnocancel( char *s )
1627
RPyBusy( int which )
1629
/* set a busy cursor ... in which = 1, unset if which = 0 */
1633
RPyDoNothing( void )
1637
/* initialise embedded R; based on rproxy_impl.c from the R distribution */
1639
init_embedded_win32( void ) {
1646
snprintf( Rversion, 25, "%s.%s", R_MAJOR, R_MINOR );
1647
if( strcmp( getDLLVersion(), Rversion ) != 0 ) {
1648
PyErr_SetString( PyExc_ImportError, "R.DLL version does not match" );
1657
index = strlen(RUSER) - 1;
1659
if (RUSER[index] == '/' || RUSER[index] == '\\')
1660
RUSER[index] = '\0';
1663
Rp->CharacterMode = LinkDLL;
1665
Rp->ReadConsole = (blah1) RPy_ReadConsole; // Matjaz
1666
Rp->WriteConsole = (blah2) RPy_WriteConsole; // Matjaz
1668
Rp->CallBack = (blah3) RPyDoNothing;
1669
#if R_VERSION < 0x20100
1670
Rp->message = char_message;
1671
Rp->yesnocancel = char_yesnocancel;
1674
Rp->ShowMessage = char_message;
1675
Rp->YesNoCancel = char_yesnocancel;
1681
/* run as "interactive", so server won't be killed after an error */
1682
Rp->R_Slave = Rp->R_Verbose = 0;
1683
Rp->R_Interactive = TRUE;
1684
Rp->RestoreAction = SA_RESTORE; /* no restore */
1685
Rp->SaveAction = SA_NOSAVE; /* no save */
1687
#if R_VERSION < 0x20000 // pre-R-2.0.0
1689
Rp->CommandLineArgs = NULL;
1690
Rp->NumCommandLineArgs = 0;
1692
R_set_command_line_arguments(0, NULL);
1694
R_SetParams(Rp); /* so R_ShowMessage is set */
1704
/* Initialization function for the module */
1709
PyOS_sighandler_t old_int;
1711
char *defaultargv[] = {"rpy", "-q", "--vanilla"};
1712
PyOS_sighandler_t old_usr1, old_usr2;
1716
/* Get path and version information from environment */
1717
strncpy(RHOME, getenv("RPY_RHOME"), BUFSIZ);
1718
strncpy(RVERSION, getenv("RPY_RVERSION"), BUFSIZ);
1719
strncpy(RVER, getenv("RPY_RVER"), BUFSIZ);
1720
strncpy(RUSER, getenv("RPY_RUSER"), BUFSIZ);
1722
if( !strlen(RHOME) || !strlen(RVERSION) || !strlen(RVER) || !strlen(RUSER))
1724
PyErr_Format(RPyExc_Exception,
1725
"Unable to load R path or version information");
1729
Robj_Type.ob_type = &PyType_Type;
1730
#if defined( _WIN32 ) && ! defined( PRE_2_2 )
1731
Robj_Type.tp_getattro = PyObject_GenericGetAttr;
1732
Robj_Type.tp_alloc = PyType_GenericAlloc;
1735
//m = Py_InitModule(MacroQuote(RPY_SHNAME), rpy_methods);
1736
m = Py_InitModule(RPY_SHNAME, rpy_methods);
1737
d = PyModule_GetDict(m);
1739
/* Save this interpreter */
1740
PyEval_InitThreads();
1741
my_interp = PyThreadState_Get()->interp;
1743
/* Save the Python signal handlers. If R inserts its handlers, we
1744
cannot return to the Python interpreter. */
1745
old_int = PyOS_getsig(SIGINT);
1746
python_sigint = old_int;
1748
old_usr1 = PyOS_getsig(SIGUSR1);
1749
old_usr2 = PyOS_getsig(SIGUSR2);
1753
init_embedded_win32();
1755
Rf_initEmbeddedR( sizeof(defaultargv) / sizeof(defaultargv[0]),
1759
/* Restore Python handlers */
1760
PyOS_setsig(SIGINT, old_int);
1762
PyOS_setsig(SIGUSR1, old_usr1);
1763
PyOS_setsig(SIGUSR2, old_usr2);
1766
/* The new exception */
1767
RPyExc_Exception = PyErr_NewException("rpy.RException", NULL, NULL);
1768
if (RPyExc_Exception)
1769
PyDict_SetItemString(d, "RException", RPyExc_Exception);
1771
// The conversion table
1772
class_table = PyDict_New();
1773
proc_table = PyDict_New();
1774
PyDict_SetItemString(d, "__class_table__", class_table);
1775
PyDict_SetItemString(d, "__proc_table__", proc_table);
1777
// The globals R objects for the sequence protocol
1778
get_item = get_fun_from_name("[");
1779
set_item = get_fun_from_name("[<-");
1780
length = get_fun_from_name("length");
1782
// Function to transpose arrays
1783
aperm = get_fun_from_name("aperm");
1785
// Initialize the list of protected objects
1786
R_References = R_NilValue;
1787
SET_SYMVALUE(install("R.References"), R_References);
1789
// Initialize the default mode
1792
// Check whether R is interactive or no
1793
interact = do_eval_fun("interactive");
1794
R_interact = INTEGER(interact)[0];
1801
rpy = PyImport_ImportModule("rpy");
1802
rpy_dict = PyModule_GetDict(rpy);
1803
// r_lock = PyDict_GetItemString(rpy_dict, "_r_lock");
1804
// PyObject_Print(r_lock, stderr, Py_PRINT_RAW);
1807
if( Py_AtExit( r_finalize ) )
1809
fprintf(stderr, "Warning: Unable to set R finalizer.");