/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* Input/Output routines
*
* $Id: io.c,v 1.3 2004/01/08 16:18:56 warnes Exp $
*
*/
#include "RPy.h"
#define ENTER_PY { PyThreadState* tstate = NULL;\
if (_PyThreadState_Current == NULL) {\
tstate = PyThreadState_New(my_interp);\
PyEval_AcquireThread(tstate);\
}
#define LEAVE_PY if (tstate) {\
PyEval_ReleaseThread(tstate);}\
}
PyObject *rpy_output, *rpy_input, *rpy_showfiles;
/* Show the traceback of an exception which occurred in a I/O process,
except when the error is a KeyboardInterrupt, in which case abort
the R interpreter */
void
RPy_ShowException()
{
PyObject *err;
if ((err = PyErr_Occurred())) {
if (PyErr_GivenExceptionMatches(err, PyExc_KeyboardInterrupt)) {
interrupt_R(0);
}
else {
PyErr_WriteUnraisable(err);
PyErr_Clear();
}
}
}
void
RPy_WriteConsole(char *buf, int len)
{
PyOS_sighandler_t old_int;
PyObject *dummy;
/* It is necessary to restore the Python handler when using a Python
function for I/O. */
old_int = PyOS_getsig(SIGINT);
PyOS_setsig(SIGINT, python_sigint);
if (rpy_output) {
ENTER_PY
dummy = PyObject_CallFunction(rpy_output, "s", buf);
Py_XDECREF(dummy);
LEAVE_PY
}
signal(SIGINT, old_int);
RPy_ShowException();
}
#ifdef _WIN32
int
RPy_ReadConsole(char *prompt,
char *buf,
int len, int addtohistory)
#else
int
RPy_ReadConsole(char *prompt,
unsigned char *buf,
int len, int addtohistory)
#endif
{
PyObject *input_data;
PyOS_sighandler_t old_int;
if (!rpy_input)
return 0;
old_int = PyOS_getsig(SIGINT);
PyOS_setsig(SIGINT, python_sigint);
ENTER_PY
start_events();
input_data = PyObject_CallFunction(rpy_input, "si", prompt, len);
stop_events();
LEAVE_PY
signal(SIGINT, old_int);
RPy_ShowException();
if (!input_data) {
PyErr_Clear();
return 0;
}
snprintf(buf, len, "%s", PyString_AsString(input_data));
Py_DECREF(input_data);
return 1;
}
int
RPy_ShowFiles(int nfile, char **file, char **headers,
char *wtitle, int del, char *pager)
{
PyObject *pyfiles, *pyheaders, *result, *f, *h;
PyOS_sighandler_t old_int;
int i;
if (!rpy_showfiles)
return 0;
old_int = PyOS_getsig(SIGINT);
PyOS_setsig(SIGINT, python_sigint);
ENTER_PY
pyfiles = PyList_New(0);
pyheaders = PyList_New(0);
if (!(pyfiles && pyheaders)) {
return 0;
}
for (i=0; i<nfile; i++) {
f = PyString_FromString(file[i]);
h = PyString_FromString(headers[i]);
PyList_Append(pyfiles, f);
PyList_Append(pyheaders, h);
Py_DECREF(f);
Py_DECREF(h);
}
result = PyObject_CallFunction(rpy_showfiles, "OOsi", pyfiles, pyheaders,
wtitle, del);
Py_DECREF(pyfiles);
Py_DECREF(pyheaders);
signal(SIGINT, old_int);
RPy_ShowException();
LEAVE_PY
if (!result) {
PyErr_Clear();
return 0;
}
Py_DECREF(result);
return 1;
}
PyObject *
wrap_set(PyObject **var, char *name, PyObject *args)
{
char *argformat;
PyObject *func;
argformat = (char *)PyMem_Malloc((strlen(name)+3)*sizeof(char));
sprintf(argformat, "O:%s", name);
if (!PyArg_ParseTuple(args, argformat, &func))
return NULL;
Py_INCREF(func);
*var = func;
Py_INCREF(Py_None);
return Py_None;
}
PyObject *
set_output(PyObject *self, PyObject *args)
{
return wrap_set(&rpy_output, "set_rpy_output", args);
}
PyObject *
set_input(PyObject *self, PyObject *args)
{
return wrap_set(&rpy_input, "set_rpy_input", args);
}
PyObject *
set_showfiles(PyObject *self, PyObject *args)
{
return wrap_set(&rpy_showfiles, "set_rpy_showfiles", args);
}
PyObject *
wrap_get(PyObject *o)
{
if (o) {
return o;
} else {
Py_INCREF(Py_None);
return Py_None;
}
}
PyObject *
get_output(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":get_rpy_output"))
return NULL;
return wrap_get(rpy_output);
}
PyObject *
get_input(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":get_rpy_input"))
return NULL;
return wrap_get(rpy_input);
}
PyObject *
get_showfiles(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":get_rpy_showfiles"))
return NULL;
return wrap_get(rpy_showfiles);
}
void
init_io_routines(PyObject *d)
#ifdef _WIN32
{ return; }
#else
{
R_Outputfile = NULL;
ptr_R_WriteConsole = RPy_WriteConsole;
ptr_R_ReadConsole = RPy_ReadConsole;
ptr_R_ShowFiles = RPy_ShowFiles;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1