1 /*
2 Copyright (C) 2001 Kai Sterker <kai.sterker@gmail.com>
3 Part of the Adonthell Project <http://adonthell.nongnu.org>
4
5 Adonthell is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 Adonthell is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Adonthell. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20 /**
21 * @file python_class.cc
22 * @author Kai Sterker <kai.sterker@gmail.com>
23 *
24 * @brief Declares the python class.
25 *
26 *
27 */
28
29 #include "python_class.h"
30 #include "game.h"
31 #include <iostream>
32
33 PyObject *data::globals;
34 PyObject *python::module;
35
36 // defined in py_adonthell_wrap.cc
37 PyObject *get_py_obj (void *instance, const char* class_name);
38
39 using namespace std;
40
41 /*
42 * Start Python
43 */
init()44 void python::init ()
45 {
46 Py_Initialize ();
47 }
48
49 /**
50 * Stop Python
51 */
cleanup()52 void python::cleanup ()
53 {
54 // Cleanup the global namespace of python interpreter
55 // Note that we don't have to DECREF data::globals, because they're a
56 // borrowed reference of py_module.
57 Py_XDECREF (module);
58 Py_Finalize ();
59 }
60
61 /*
62 * Insert a string into the module search path.
63 */
insert_path(char * name)64 void python::insert_path( char *name )
65 {
66 char buf[256];
67
68 sprintf ( buf, "import sys ; sys.path.insert(0, \"%s\")", name );
69 PyRun_SimpleString ( buf );
70 }
71
72 /*
73 * Some convenience functions
74 */
75
76 /*
77 * Executes the Python statements in the string
78 */
exec_string(const char * s)79 void python::exec_string(const char * s)
80 {
81 PyRun_SimpleString(s);
82 }
83
84 /*
85 * Execute the file given by 'filename'
86 */
exec_file(string filename)87 bool python::exec_file (string filename)
88 {
89 PyObject *mod = python::import_module (filename);
90
91 if (!mod)
92 {
93 cerr << "exec_file: " << filename << " load failed: " << endl;
94 show_traceback ();
95
96 return false;
97 }
98
99 Py_DECREF (mod);
100
101 return true;
102 }
103
104 /*
105 * Dump any error information to stderr
106 */
show_traceback(void)107 void python::show_traceback(void)
108 {
109 if ( PyErr_Occurred() )
110 {
111 PyErr_Print();
112 fflush (stderr);
113 }
114 }
115
116 /* Import a module, return module ptr */
import_module(string filename)117 PyObject *python::import_module (string filename)
118 {
119 PyObject *result = PyImport_ImportModule ((char *) filename.c_str ());
120
121 #ifdef PY_DEBUG
122 show_traceback ();
123 #endif
124 return result;
125 }
126
127 // Make a C++ instance available to Python
pass_instance(void * instance,const char * class_name)128 PyObject *python::pass_instance (void *instance, const char *class_name)
129 {
130 string class_ptr = string(class_name) + "*";
131 return get_py_obj (instance, class_ptr.c_str());
132 }
133
get_tuple(igzstream & file)134 PyObject * python::get_tuple (igzstream & file)
135 {
136 PyObject * tuple;
137 u_int32 l;
138 l << file;
139
140 tuple = PyTuple_New (l);
141
142 for (u_int32 i = 0; i < l; i++)
143 {
144 string ms;
145 u_int32 j;
146 char c;
147
148 c << file;
149 switch (c)
150 {
151 case 's':
152 ms << file;
153 // Stolen reference
154 PyTuple_SetItem (tuple, i, PyString_FromString (ms.c_str ()));
155 break;
156
157 case 'i':
158 j << file;
159 // Stolen reference
160 PyTuple_SetItem (tuple, i, PyInt_FromLong (j));
161 break;
162 }
163 }
164 return tuple;
165 }
166
put_tuple(PyObject * tuple,ogzstream & file)167 void python::put_tuple (PyObject * tuple, ogzstream & file)
168 {
169 u_int32 l = PyTuple_Size (tuple);
170 l >> file;
171 for (u_int32 i = 0; i < l; i++)
172 {
173 // Borrowed reference
174 PyObject * item = PyTuple_GetItem (tuple, i);
175
176 // Check for the type of this object
177 // String?
178 if (PyString_Check (item))
179 {
180 's' >> file;
181 string s = python::as_string (item);
182 s >> file;
183 }
184
185 // Integer?
186 else if (PyInt_Check (item))
187 {
188 'i' >> file;
189 u_int32 li = PyInt_AsLong (item);
190 li >> file;
191 }
192 }
193 }
194
as_string(PyObject * s)195 string python::as_string(PyObject *s)
196 {
197 #if PY_MAJOR_VERSION >= 3
198 PyObject *byteArr = PyUnicode_AsUTF8String(s);
199 char* str = PyBytes_AsString(byteArr);
200 #else
201 char* str = PyString_AsString(s);
202 #endif
203 if (str)
204 {
205 string result(str);
206 #if PY_MAJOR_VERSION >= 3
207 Py_DECREF(byteArr);
208 #endif
209 return result;
210 }
211 #if PY_MAJOR_VERSION >= 3
212 Py_DECREF(byteArr);
213 #endif
214 return string("");
215 }
216