1 // SALOME SALOMEGUI : implementation of desktop and GUI kernel
3 // Copyright (C) 2003 CEA/DEN, EDF R&D
7 // File : PyInterp_base.cxx
8 // Author : Christian CAREMOLI, Paul RASCLE, EDF
13 #include "PyInterp_base.h"
14 #include "utilities.h"
17 #include <cStringIO.h>
21 extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
23 static PyThreadState *savedThreadState = NULL;
26 * We have our own routines which are identical to the SIP routines
27 * to not depend from SIP software evolutions
30 extern "C" void salomeAcquireLock()
32 MESSAGE("salomeAcquireLock");
33 PyEval_RestoreThread(savedThreadState);
34 savedThreadState = NULL;
37 extern "C" void salomeReleaseLock()
39 MESSAGE("salomeReleaseLock");
40 savedThreadState = PyEval_SaveThread();
43 extern "C" int salomeCondAcquireLock()
45 MESSAGE("salomeCondAcquireLock");
46 if(savedThreadState != NULL)
49 * If savedThreadState is not NULL, Python global lock is not already acquired
51 * and return 1 to the caller
54 //MESSAGE("We got it (the lock)");
58 * If savedThreadState is NULL, Python global lock is already acquired
59 * We don't acquire or release it
60 * We return 0 to the caller
61 * CAUTION : it's only true when there is no event programming running (Tkinter, PyQt)
66 extern "C" void salomeCondReleaseLock(int rellock)
68 MESSAGE("salomeCondReleaseLock");
73 // main python interpreter
75 PyThreadState *PyInterp_base::_gtstate=0; // force 0 before execution
76 int PyInterp_base::_argc=1;
77 char* PyInterp_base::_argv[] = {""};
79 PyObject *PyInterp_base::builtinmodule=NULL;
80 PyObject *PyInterp_base::salome_shared_modules_module=NULL;
84 SCRUTE(PyInterp_base::_gtstate);
85 if (PyInterp_base::_gtstate) return;
86 Py_Initialize(); // Initialize the interpreter
87 PyEval_InitThreads(); // Create (and acquire) the interpreter lock
88 PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv); // initialize sys.argv
89 PyInterp_base::_gtstate = PyThreadState_Get();
90 SCRUTE(PyInterp_base::_gtstate);
93 // * Import __builtin__ module and store it to use it with all sub-interpreters
94 // * This hack could be used with event programming (PyQt) to avoid errors
95 // * encountered with incoherent builtins
98 // PyInterp_base::builtinmodule =PyImport_ImportModule("__builtin__");
99 // SCRUTE(PyInterp_base::builtinmodule->ob_refcnt);
102 * Import salome_shared_modules module and store it to use it with all sub-interpreters
105 PyInterp_base::salome_shared_modules_module =PyImport_ImportModule("salome_shared_modules");
106 SCRUTE(PyInterp_base::salome_shared_modules_module->ob_refcnt);
112 * This function compiles a string (command) and then evaluates it in the dictionnary
113 * context if possible.
116 * 1 : incomplete text
117 * 0 : complete text executed with success
120 int compile_command(const char *command,PyObject *context)
125 m=PyImport_AddModule("codeop");
129 * Fatal error. No way to go on.
134 v= PyObject_CallMethod(m,"compile_command","s",command);
138 * Error encountered. It could be SyntaxError
143 else if (v == Py_None)
146 * Incomplete text we return 1 : we need a complete text to execute
153 * Complete and correct text. We evaluate it.
155 r = PyEval_EvalCode(v,context,context);
160 * Execution error. We return -1
167 * The command has been successfully executed. Return 0
174 * basic constructor here : herited classes constructors must call initalize() method
178 PyInterp_base::PyInterp_base():_tstate(0),_vout(0),_verr(0),_g(0),_atFirst(true)
180 MESSAGE("PyInterp_base::PyInterp_base()");
183 PyInterp_base::~PyInterp_base()
185 MESSAGE("PyInterp_base::~PyInterp_base()");
187 PyThreadState_Swap(_tstate);
188 Py_EndInterpreter(_tstate);
193 * Must be called by herited classes constructors. initialize() calls virtuals methods
194 * initstate & initcontext, not defined here in base class. initstate & initcontext methods
195 * must be implemented in herited classes, following the Python interpreter policy
196 * (mono or multi interpreter...).
198 void PyInterp_base::initialize()
200 MESSAGE("PyInterp_base::initialize()");
203 _history.clear(); // start a new list of user's commands
204 _ith = _history.begin();
212 m=PyImport_ImportModule("codeop"); // used to interpret & compile commands
215 MESSAGE("Problem...");
224 * Create cStringIO to capture stdout and stderr
227 PycStringIO=(PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
228 _vout=PycStringIO->NewOutput(128);
229 _verr=PycStringIO->NewOutput(128);
231 // All the initRun outputs are redirected to the standard output (console)
234 // We go out of Python world to enter the C++ world. Release the Python global lock
240 string PyInterp_base::getbanner()
242 MESSAGE("PyInterp_base::getbanner()");
243 string banner = "Python ";
244 banner = banner + Py_GetVersion() + " on " + Py_GetPlatform() ;
245 banner = banner + "\ntype help to get general information on environment\n";
246 return banner.c_str();
249 int PyInterp_base::initRun()
251 MESSAGE("PyInterp_base::initRun()");
252 PySys_SetObject("stderr",_verr);
253 PySys_SetObject("stdout",_vout);
255 PyObject *v = PyObject_CallMethod(_verr,"reset","");
257 v = PyObject_CallMethod(_vout,"reset","");
262 m = PyImport_GetModuleDict();
264 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
265 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
267 MESSAGE(this->getvout());
268 MESSAGE(this->getverr());
273 void PyInterp_base::enter()
275 MESSAGE("PyInterp_base::enter()");
277 PyThreadState_Swap(_tstate);
280 void PyInterp_base::quit()
282 MESSAGE("PyInterp_base::quit()");
286 void PyInterp_base::basicRun(const char *command)
291 code=Py_CompileString((char *)command,"PyInterp_base",Py_file_input);
295 * Caught an error : SyntaxError
302 r = PyEval_EvalCode(code,_g,_g);
307 * Caught an error during execution
318 int PyInterp_base::run(const char *command)
325 ret = this->simpleRun("from Help import *");
326 MESSAGE(this->getvout())
327 MESSAGE(this->getverr())
328 if (ret != 0) return ret;
329 ret = this->simpleRun("import salome");
330 MESSAGE(this->getvout());
331 MESSAGE(this->getverr())
332 if (ret != 0) return ret;
334 ret = this->simpleRun(command);
338 int PyInterp_base::simpleRun(const char *command)
341 PyObject *v,*m,*r,*g;
344 string s_com = command;
346 if (s_com.size() > 0)
348 _history.push_back(s_com);
349 _ith = _history.end();
350 SCRUTE(_history.back());
355 // We come from C++ to enter Python world
356 // We need to acquire the Python global lock
358 // Restore the sub interpreter thread state : this._tstate
359 PyThreadState_Swap(_tstate);
362 Reset redirected outputs before treatment
364 PySys_SetObject("stderr",_verr);
365 PySys_SetObject("stdout",_vout);
367 v = PyObject_CallMethod(_verr,"reset","");
369 v = PyObject_CallMethod(_vout,"reset","");
372 ier=compile_command(command,_g);
374 // Outputs are redirected on standards outputs (console)
375 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
376 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
378 // We go back to the C++ world. Release the lock.
383 static string vout_buffer;
384 static string verr_buffer;
386 char * PyInterp_base::getverr()
388 MESSAGE("PyInterp_base::getverr");
390 v=PycStringIO->cgetvalue(_verr);
391 verr_buffer=PyString_AsString(v);
393 return (char *)verr_buffer.c_str();
396 char * PyInterp_base::getvout()
398 MESSAGE("PyInterp_base::getvout");
400 v=PycStringIO->cgetvalue(_vout);
401 vout_buffer=PyString_AsString(v);
403 return (char *)vout_buffer.c_str();
406 const char * PyInterp_base::getPrevious()
408 MESSAGE("PyInterp_base::getPrevious");
409 if (_ith != _history.begin())
412 return (*_ith).c_str();
415 return BEGIN_HISTORY_PY;
418 const char * PyInterp_base::getNext()
420 MESSAGE("PyInterp_base::getNext");
421 if (_ith != _history.end())
425 if (_ith == _history.end())
426 return TOP_HISTORY_PY;
428 return (*_ith).c_str();