Adonthell  0.4
python_class.cc
Go to the documentation of this file.
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  */
44 void python::init ()
45 {
46  Py_Initialize ();
47 }
48 
49 /**
50  * Stop Python
51  */
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  */
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  */
79 void python::exec_string(const char * s)
80 {
81  PyRun_SimpleString(s);
82 }
83 
84 /*
85  * Execute the file given by 'filename'
86  */
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  */
108 {
109  if ( PyErr_Occurred() )
110  {
111  PyErr_Print();
112  fflush (stderr);
113  }
114 }
115 
116 /* Import a module, return module ptr */
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
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 
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 
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 
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 }
Class to write data from a Gzip compressed file.
Definition: fileops.h:227
static bool exec_file(string filename)
Executes a Python script.
Definition: python_class.cc:87
PyObject * globals
Global namespace to use in scripts.
Definition: python_class.cc:33
Class to read data from a Gzip compressed file.
Definition: fileops.h:135
Definition: str_hash.h:71
Declares the game class.
static void put_tuple(PyObject *tuple, ogzstream &file)
Save a Python tuple into a file.
#define u_int32
32 bits long unsigned integer
Definition: types.h:41
static void show_traceback(void)
Dumps any error information to stderr.
static PyObject * get_tuple(igzstream &file)
Loads a Python tuple previously saved with put_tuple ().
static PyObject * import_module(string filename)
Imports a Python module.
static PyObject * pass_instance(void *instance, const char *class_name)
Magic function that makes any C object available to Python!
Defines the python class. This file is named this way so it doesn&#39;t conflicts with Python...
static void insert_path(char *name)
Adds a directory to Python&#39;s include path.
Definition: python_class.cc:64
static void exec_string(const char *s)
Execute Python statements contained in a string.
Definition: python_class.cc:79
static void cleanup()
Cleanup Python.
Definition: python_class.cc:52
static void init()
Initialise Python and insert the Adonthell include paths.
Definition: python_class.cc:44