2
* $Id: R_eval.c 363 2007-11-12 23:27:48Z warnes $
3
* Evaluation of R expressions.
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 ***** */
42
* This program is free software; you can redistribute it and/or modify
43
* it under the terms of the GNU General Public License as published by
44
* the Free Software Foundation; either version 2 of the License, or
45
* (at your option) any later version.
47
* This program is distributed in the hope that it will be useful,
48
* but WITHOUT ANY WARRANTY; without even the implied warranty of
49
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50
* GNU General Public License for more details.
52
* You should have received a copy of the GNU General Public License
53
* along with this program; if not, write to the Free Software
54
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
57
* Evaluation of R expressions.
59
* $Id: R_eval.c 363 2007-11-12 23:27:48Z warnes $
65
/* The Python original SIGINT handler */
66
PyOS_sighandler_t python_sigint;
68
/* Indicates whether the R interpreter was interrupted by a SIGINT */
71
/* Abort the current R computation due to a SIGINT */
72
void interrupt_R(int signum)
79
/* Evaluate a SEXP. It must be constructed by hand. It raises a Python
80
exception if an error ocurred in the evaluation */
81
SEXP do_eval_expr(SEXP e) {
84
PyOS_sighandler_t old_int;
86
/* Enable our handler for SIGINT inside the R
87
interpreter. Otherwise, we cannot stop R calculations, since
88
SIGINT is only processed between Python bytecodes. Also, save the
89
Python SIGINT handler because it is necessary to temporally
90
restore it in user defined I/O Python functions. */
94
old_int = PyOS_getsig(SIGBREAK);
96
old_int = PyOS_getsig(SIGINT);
98
python_sigint = old_int;
100
signal(SIGINT, interrupt_R);
103
res = R_tryEval(e, R_GlobalEnv, &error);
106
PyOS_setsig(SIGBREAK, old_int);
108
PyOS_setsig(SIGINT, old_int);
115
PyErr_SetNone(PyExc_KeyboardInterrupt);
118
PyErr_SetString(RPy_RException, get_last_error_msg());
126
/* Evaluate a function given by a name (without arguments) */
127
SEXP do_eval_fun(char *name) {
130
fun = get_fun_from_name(name);
135
PROTECT(exp = allocVector(LANGSXP, 1));
138
PROTECT(res = do_eval_expr(exp));
144
* Get an R **function** object by its name. When not found, an exception is
145
* raised. The checking of the length of the identifier is needed to
146
* avoid R raising an error causing Python to dump core.
148
SEXP get_fun_from_name(char *ident) {
151
/* For R not to throw an error, we must check the identifier is
152
neither null nor greater than MAXIDSIZE */
154
PyErr_SetString(RPy_Exception, "attempt to use zero-length variable name");
157
if (strlen(ident) > MAXIDSIZE) {
158
PyErr_SetString(RPy_Exception, "symbol print-name too long");
162
#if R_VERSION < 0x20000
163
obj = Rf_findVar(Rf_install(ident), R_GlobalEnv);
166
* For R-2.0.0 and later, it is necessary to use findFun to get
167
* functions. Unfortunately, calling findFun on an undefined name
172
* 1) Call findVar on the name
174
* 2) If something has the name, call findFun
176
* 3) Raise an error if either step 1 or 2 fails.
178
obj = Rf_findVar(Rf_install(ident), R_GlobalEnv);
180
if (obj != R_UnboundValue)
181
obj = Rf_findFun(Rf_install(ident), R_GlobalEnv);
184
if (obj == R_UnboundValue) {
185
PyErr_Format(RPy_Exception, "R Function \"%s\" not found", ident);
191
/* Obtain the text of the last R error message */
192
const char *get_last_error_msg() {
195
msg = do_eval_fun("geterrmessage");
196
return CHARACTER_VALUE(msg);