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
16 #include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)!
17 #include <cStringIO.h>
21 PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState):
22 myThreadState(theThreadState),
26 mySaveThreadState = PyThreadState_Swap(myThreadState); // store previous current in save,
27 // set local in current
31 PyLockWrapper::~PyLockWrapper(){
32 PyThreadState_Swap(mySaveThreadState); // restore previous current (no need to get local,
33 PyEval_ReleaseLock(); // local thread state* already in _tstate
45 PyLockWrapper PyInterp_base::GetLockWrapper(){
50 // main python interpreter
52 //PyThreadState *PyInterp_base::_gtstate = 0; // force 0 before execution
53 int PyInterp_base::_argc = 1;
54 char* PyInterp_base::_argv[] = {""};
56 PyObject *PyInterp_base::builtinmodule = NULL;
60 * basic constructor here : herited classes constructors must call initalize() method
63 PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
67 PyInterp_base::~PyInterp_base()
69 PyLockWrapper aLock(_tstate);
70 //Py_EndInterpreter(_tstate);
75 * Must be called by herited classes constructors. initialize() calls virtuals methods
76 * initstate & initcontext, not defined here in base class. initstate & initcontext methods
77 * must be implemented in herited classes, following the Python interpreter policy
78 * (mono or multi interpreter...).
80 void PyInterp_base::initialize()
82 _history.clear(); // start a new list of user's commands
83 _ith = _history.begin();
86 // Here the global lock is released
88 // The lock will be acquired in initState. Make provision to release it on exit
89 PyReleaseLock aReleaseLock;
94 // used to interpret & compile commands
95 PyObjWrapper m(PyImport_ImportModule("codeop"));
101 // Create cStringIO to capture stdout and stderr
103 //PycStringIO = (PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
104 _vout = PycStringIO->NewOutput(128);
105 _verr = PycStringIO->NewOutput(128);
107 // All the initRun outputs are redirected to the standard output (console)
111 void PyInterp_base::init_python()
113 static PyThreadState *_gtstate = 0;
116 if (Py_IsInitialized())
119 Py_SetProgramName(_argv[0]);
120 Py_Initialize(); // Initialize the interpreter
121 PySys_SetArgv(_argc, _argv);
122 PyEval_InitThreads(); // Create (and acquire) the interpreter lock
123 _gtstate = PyEval_SaveThread(); // Release global thread state
125 // PyReleaseLock aReleaseLock;
126 // Py_Initialize(); // Initialize the interpreter
127 // PyEval_InitThreads(); // Initialize and acquire the global interpreter lock
128 // PySys_SetArgv(_argc,_argv); // initialize sys.argv
129 // _gtstate = PyThreadState_Get();
133 string PyInterp_base::getbanner()
135 string aBanner("Python ");
136 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
137 aBanner = aBanner + "\ntype help to get general information on environment\n";
142 int PyInterp_base::initRun()
144 PySys_SetObject("stderr",_verr);
145 PySys_SetObject("stdout",_vout);
147 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
148 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
150 //PyObject *m = PyImport_GetModuleDict();
152 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
153 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
160 * This function compiles a string (command) and then evaluates it in the dictionnary
161 * context if possible.
164 * 1 : incomplete text
165 * 0 : complete text executed with success
167 int compile_command(const char *command,PyObject *context)
169 PyObject *m = PyImport_AddModule("codeop");
170 if(!m){ // Fatal error. No way to go on.
174 PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
176 // Error encountered. It should be SyntaxError,
177 //so we don't write out traceback
178 PyObjWrapper exception, value, tb;
179 PyErr_Fetch(&exception, &value, &tb);
180 PyErr_NormalizeException(&exception, &value, &tb);
181 PyErr_Display(exception, value, NULL);
183 }else if (v == Py_None){
184 // Incomplete text we return 1 : we need a complete text to execute
187 // Complete and correct text. We evaluate it.
188 #if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
189 PyObjWrapper r(PyEval_EvalCode(v,context,context));
191 PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
194 // Execution error. We return -1
198 // The command has been successfully executed. Return 0
204 int PyInterp_base::run(const char *command)
208 ret = simpleRun("from Help import *");
213 ret = simpleRun("import salome");
218 ret = simpleRun("salome.salome_init()");
225 return simpleRun(command);
229 int PyInterp_base::simpleRun(const char *command)
231 if( !_atFirst && strcmp(command,"") != 0 ) {
232 _history.push_back(command);
233 _ith = _history.end();
236 // We come from C++ to enter Python world
237 // We need to acquire the Python global lock
238 //PyLockWrapper aLock(_tstate); // san - lock is centralized now
240 // Reset redirected outputs before treatment
241 PySys_SetObject("stderr",_verr);
242 PySys_SetObject("stdout",_vout);
244 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
245 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
247 int ier = compile_command(command,_g);
249 // Outputs are redirected on standards outputs (console)
250 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
251 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
256 const char * PyInterp_base::getPrevious()
258 if(_ith != _history.begin()){
260 return (*_ith).c_str();
263 return BEGIN_HISTORY_PY;
267 const char * PyInterp_base::getNext()
269 if(_ith != _history.end()){
272 if (_ith == _history.end())
273 return TOP_HISTORY_PY;
275 return (*_ith).c_str();
279 string PyInterp_base::getverr(){
280 //PyLockWrapper aLock(_tstate);
281 PyObjWrapper v(PycStringIO->cgetvalue(_verr));
282 string aRet(PyString_AsString(v));
287 string PyInterp_base::getvout(){
288 //PyLockWrapper aLock(_tstate);
289 PyObjWrapper v(PycStringIO->cgetvalue(_vout));
290 string aRet(PyString_AsString(v));