1 /* copyright 2003 Jim Bublitz <jbublitz@nwinternet.com>
2
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Library General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
17 */
18
19 #include <stdarg.h>
20 #include <string.h>
21
22 // this just gets rid of a warning when Python.h redefines it
23 #undef _POSIX_C_SOURCE
24
25 #include <pythonize.h>
26
27 #define debug 1
28
ObjectRef(ObjectRef * oi,PyObject * o)29 ObjectRef::ObjectRef (ObjectRef *oi, PyObject *o)
30 {
31 prevObject = oi;
32 object = o;
33 }
34
35
Pythonize()36 Pythonize::Pythonize ()
37 {
38 pythonInit = 1;
39 objects = nullptr;
40
41 if (debug) printf ("\n\nPythonize constructor -- pid = %i\n", getpid ());
42
43 if (!Py_IsInitialized ())
44 {
45 PyEval_InitThreads ();
46 Py_Initialize ();
47 if (!Py_IsInitialized ())
48 {
49 pythonInit = 0;
50 return;
51 }
52
53 if (debug) printf ("Python interpreter initialized!\n\n");
54
55 // free the lock
56 PyEval_ReleaseLock();
57 }
58 }
59
runScript(char * scriptPath)60 bool Pythonize::runScript (char *scriptPath)
61 {
62 FILE *f;
63 int res;
64
65 if (debug) printf ("Running script: %s\n", scriptPath);
66
67 if (scriptPath == nullptr || strlen (scriptPath) == 0) return false;
68
69 f = fopen (scriptPath, "r");
70 if (f == nullptr) return false;
71
72 res = PyRun_SimpleFile (f, scriptPath);
73
74 fclose (f);
75 return res == 0;
76 }
77
78
runFunction(PyObject * object,PyObject * args)79 PyObject * Pythonize::runFunction (PyObject *object, PyObject *args)
80 {
81
82 if (!PyCallable_Check (object))
83 return nullptr;
84
85 PyObject *res = PyObject_CallObject (object, args ? args : PyTuple_New (0));
86 Py_XINCREF (res);
87
88 return res;
89 }
90
runFunctionVoid(PyObject * object,PyObject * args)91 void * Pythonize::runFunctionVoid (PyObject *object, PyObject *args)
92 {
93
94 if (!PyCallable_Check (object))
95 return nullptr;
96
97 PyObject *pyRes = PyObject_CallObject (object, args ? args : PyTuple_New (0));
98 void *res = PyLong_AsVoidPtr (pyRes);
99
100 return res;
101 }
102
runString(char * str)103 bool Pythonize::runString (char *str)
104 {
105 if (str == nullptr || strlen (str) == 0) return false;
106
107 int res = PyRun_SimpleString (str);
108
109 return res == 0;
110 }
111
appendToSysPath(const char * newPath)112 bool Pythonize::appendToSysPath (const char* newPath)
113 {
114 if (newPath == nullptr || strlen (newPath) == 0) return false;
115
116 char *fmtString = "import sys\nif not '%s' in sys.path:\n\tsys.path.append ('%s')\n"; //print sys.path\n";
117 int length = strlen (fmtString) + 2*strlen (newPath) + 1;
118 char *line = new char [length];
119 if (!line) return false;
120 snprintf (line, length, fmtString, newPath, newPath);
121
122 int res = PyRun_SimpleString (line);
123
124 delete[] line;
125 return res == 0;
126 }
127
importModule(char * moduleName)128 PyObject *Pythonize::importModule (char *moduleName)
129 {
130 if (moduleName == nullptr || strlen (moduleName) == 0) return nullptr;
131
132 PyObject *module = PyImport_ImportModule (moduleName);
133
134 objects = new ObjectRef (objects, module);
135 if (!objects) return nullptr;
136
137 return module;
138 }
139
140
~Pythonize()141 Pythonize::~Pythonize ()
142 {
143
144 if (debug) printf ("Pythonize destructor\n");
145 ObjectRef *top;
146
147 while (objects)
148 {
149 top = objects;
150 objects = objects->prevObject;
151 delete top;
152 }
153 if (debug) printf (" --- Objects destroyed\n");
154
155 Py_Finalize();
156
157 if (debug) printf (" --- Py_Finalized\n");
158 }
159
160 //// XXX: disabled
161 //// The global Pythonize instance
162 //Pythonize *pyize = new Pythonize ();
163
164 extern "C"
165 {
166 Pythonize *_pythonize;
167
initialize()168 Pythonize *initialize ()
169 {
170 if (_pythonize) return _pythonize;
171
172 _pythonize = new Pythonize ();
173 if (!_pythonize || !_pythonize->getPythonInit ())
174 {
175 if (_pythonize) delete _pythonize;
176 return nullptr;
177 }
178
179 return _pythonize;
180 }
181
finalize()182 void finalize ()
183 {
184 if (_pythonize) {
185 if (debug) printf(" --- Pythonize finalize()\n");
186 delete _pythonize;
187 }
188 }
189
190 // adds a path to sys.path
appendToSysPath(const char * newPath)191 bool appendToSysPath (const char* newPath)
192 {
193 return _pythonize ? _pythonize->appendToSysPath (newPath) : false;
194 }
195
196 // imports a module into the interpreter
197 // or gets a PyObject for an already loaded module
importModule(char * moduleName)198 PyObject *importModule (char *moduleName)
199 {
200 return _pythonize ? _pythonize->importModule (moduleName) : nullptr;
201 }
202
203 // returns an object from a loaded module
204 // you must decref the object returned when done with it (new reference returned)
getNewObjectRef(PyObject * module,char * object)205 PyObject *getNewObjectRef (PyObject *module, char *object)
206 {
207 return _pythonize ? _pythonize->getNewObjectRef (module, object) : nullptr;
208 }
209
getPythonInit()210 bool getPythonInit ()
211 {
212 return _pythonize ? _pythonize->getPythonInit () : false;
213 }
214
215 // decrements the ref count of an object
decref(PyObject * object)216 void decref (PyObject *object)
217 {
218 Py_XDECREF (object);
219 }
220
221 // runs a script on the current sys.path
runScript(char * scriptPath)222 bool runScript (char *scriptPath)
223 {
224 return _pythonize ? _pythonize->runScript (scriptPath) : false;
225 }
226
227 // executes a string of Python in the interpreter
runString(char * str)228 bool runString (char *str)
229 {
230 return _pythonize ? _pythonize->runString (str) : false;
231 }
232
233 // runs a callable Python object
runFunction(PyObject * object,PyObject * args)234 PyObject *runFunction (PyObject *object, PyObject *args)
235 {
236 return _pythonize ? _pythonize->runFunction (object, args) : nullptr;
237 }
238 }
239