root/MGET/Branches/Jason/PythonPackage/src/GeoEco/AssimilatedModules/rpy/src-rpy-1.0.3/src/io.c @ 404

Revision 404, 6.3 KB (checked in by jjr8, 4 years ago)

This and the previous few revisions fix and implement:

* #264: Predict GAM and Predict GLM tools should check the left and bottom extents and the number of rows and columns rather than all four extents
* #265: The Raster Type search option does not work for batch processing tools that find rasters
* #284: Tools that do not have "Run Python script in process" checked run extremely slowly under ArcGIS 9.3
* #357: Add support for ArcGIS 9.3.1
* #358: When provided with raster layers, Predict GAM and Predict GLM tools fail with GDAL Error 4: `<raster>' does not exist in the file system, and is not recognised as a supported dataset name.
* #359: With ArcGIS 9.3.1, Predict GAM and Predict GLM tools fail with RPy_RException: Error: GDAL Error 5: Access window out of range in RasterIO()
* #360: All tools that invoke R leak memory
* #361: Python's logging package causes large memory leaks in "in process" MGET tools under ArcGIS 9.3

The ArcGIS 9.3 toolbox still needs to rebuilt and more testing needs to happen, but this revision represents a large amount of the total work required for MGET 0.7b1.

Line 
1/*
2 * $Id: io.c 393 2008-01-02 17:34:28Z warnes $
3 * Input/Output routines
4 */
5
6/* ***** BEGIN LICENSE BLOCK *****
7 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8 *
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/
13 *
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
17 * License.
18 *
19 * The Original Code is the RPy python module.
20 *
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.
24 *
25 * Contributor(s):
26 *    Gregory R. Warnes <greg@warnes.net> (Maintainer)
27 *
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.
39 *
40 * ***** END LICENSE BLOCK ***** */
41
42
43#include "RPy.h"
44
45#define ENTER_PY { PyThreadState* tstate = NULL;\
46    if (_PyThreadState_Current == NULL) {\
47       tstate = PyThreadState_New(my_interp);\
48       PyEval_AcquireThread(tstate);\
49    }
50
51#define LEAVE_PY  if (tstate) {\
52       PyEval_ReleaseThread(tstate);}\
53    }
54
55PyObject *rpy_output=NULL, *rpy_input=NULL, *rpy_showfiles=NULL;
56
57/* Show the traceback of an exception which occurred in a I/O process,
58   except when the error is a KeyboardInterrupt, in which case abort
59   the R interpreter */
60void
61RPy_ShowException()
62{
63  PyObject *err;
64
65  if ((err = PyErr_Occurred())) {
66    if (PyErr_GivenExceptionMatches(err, PyExc_KeyboardInterrupt)) {
67      interrupt_R(0);
68    }
69    else {
70      PyErr_WriteUnraisable(err);
71      PyErr_Clear();
72    }
73  }
74}
75
76
77void
78RPy_WriteConsole(char *buf, int len)
79{
80  PyOS_sighandler_t old_int;
81  PyObject *dummy;
82
83  /* It is necessary to restore the Python handler when using a Python
84     function for I/O. */
85  old_int = PyOS_getsig(SIGINT);
86  PyOS_setsig(SIGINT, python_sigint);
87  if (rpy_output) {
88    ENTER_PY
89    dummy = PyObject_CallFunction(rpy_output, "s", buf);
90    Py_XDECREF(dummy);
91    LEAVE_PY
92  }
93  signal(SIGINT, old_int);
94  RPy_ShowException();
95}
96
97#ifdef _WIN32
98int
99RPy_ReadConsole(char *prompt,
100                char *buf,
101                int len,
102                int addtohistory)
103#else
104int
105RPy_ReadConsole(char *prompt,
106                unsigned char *buf,
107                int len,
108                int addtohistory)
109#endif
110{
111  PyObject *input_data;
112  PyOS_sighandler_t old_int;
113
114  if (!rpy_input)
115    return 0;
116
117  old_int = PyOS_getsig(SIGINT);
118  PyOS_setsig(SIGINT, python_sigint);
119  ENTER_PY
120  start_events();
121  input_data = PyObject_CallFunction(rpy_input, "si", prompt, len);
122  stop_events();
123  LEAVE_PY
124
125  signal(SIGINT, old_int);
126
127  RPy_ShowException();
128
129  if (!input_data) {
130    PyErr_Clear();
131    return 0;
132  }
133  snprintf(buf, len, "%s", PyString_AsString(input_data));
134  Py_DECREF(input_data);
135  return 1;
136}
137
138int
139RPy_ShowFiles(int nfile, char **file, char **headers,
140              char *wtitle, int del, char *pager)
141{
142  PyObject *pyfiles, *pyheaders, *result, *f, *h;
143  PyOS_sighandler_t old_int;
144  int i;
145
146  if (rpy_showfiles==NULL)
147    return 0;
148
149  old_int = PyOS_getsig(SIGINT);
150  PyOS_setsig(SIGINT, python_sigint);
151
152  ENTER_PY
153
154  pyfiles = PyList_New(0);
155  pyheaders = PyList_New(0);
156  if (!(pyfiles && pyheaders)) {
157    return 0;
158  }
159 
160  for (i=0; i<nfile; i++) {
161    f = PyString_FromString(file[i]);
162    h = PyString_FromString(headers[i]);
163    PyList_Append(pyfiles, f);
164    PyList_Append(pyheaders, h);
165    Py_DECREF(f);
166    Py_DECREF(h);
167  }
168
169  result = PyObject_CallFunction(rpy_showfiles, "OOsi", pyfiles, pyheaders,
170                                 wtitle, del);
171  Py_DECREF(pyfiles);
172  Py_DECREF(pyheaders);
173
174  signal(SIGINT, old_int);
175  RPy_ShowException();
176
177  LEAVE_PY
178
179  if (!result) {
180    PyErr_Clear();
181    return 0;
182  }
183  Py_DECREF(result);
184  return 1;
185}
186
187PyObject *
188wrap_set(PyObject **var, char *name, PyObject *args)
189{
190  char *argformat;
191  PyObject *func;
192
193  argformat = (char *)PyMem_Malloc((strlen(name)+3)*sizeof(char));
194  if (!argformat)
195    return PyErr_NoMemory();
196  sprintf(argformat, "O:%s", name);
197  if (!PyArg_ParseTuple(args, argformat, &func)) {
198    PyMem_Free(argformat);
199    PyErr_SetString(PyExc_ValueError, "Invalid arguments");
200    return NULL;
201  }
202  PyMem_Free(argformat);
203
204  Py_XDECREF(*var);
205  Py_INCREF(func);
206  *var = func;
207  Py_INCREF(Py_None);
208  return Py_None;
209}
210
211PyObject *
212set_output(PyObject *self, PyObject *args)
213{
214  return wrap_set(&rpy_output, "set_rpy_output", args);
215}
216
217PyObject *
218set_input(PyObject *self, PyObject *args)
219{
220  return wrap_set(&rpy_input, "set_rpy_input", args);
221}
222
223PyObject *
224set_showfiles(PyObject *self, PyObject *args)
225{
226  return wrap_set(&rpy_showfiles, "set_rpy_showfiles", args);
227}
228
229PyObject *
230wrap_get(PyObject *o)
231{
232  if (o) {
233    Py_INCREF(o);
234    return o;
235  } else {
236    Py_INCREF(Py_None);
237    return Py_None;
238  }
239}
240
241PyObject *
242get_output(PyObject *self, PyObject *args)
243{
244  if (!PyArg_ParseTuple(args, ":get_rpy_output"))
245    return NULL;
246
247  return wrap_get(rpy_output);
248}
249
250PyObject *
251get_input(PyObject *self, PyObject *args)
252{
253  if (!PyArg_ParseTuple(args, ":get_rpy_input"))
254    return NULL;
255
256  return wrap_get(rpy_input);
257}
258
259PyObject *
260get_showfiles(PyObject *self, PyObject *args)
261{
262  if (!PyArg_ParseTuple(args, ":get_rpy_showfiles"))
263    return NULL;
264
265  return wrap_get(rpy_showfiles);
266}
267
268void
269init_io_routines(void)
270#ifdef _WIN32
271{
272  return;
273}
274#else
275{
276  R_Outputfile = NULL;
277  ptr_R_WriteConsole = RPy_WriteConsole;
278  ptr_R_ReadConsole = RPy_ReadConsole;
279  ptr_R_ShowFiles = RPy_ShowFiles;
280}
281#endif
Note: See TracBrowser for help on using the browser.