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),
25 #if defined(USE_GILSTATE)
26 if (myThreadState->interp == PyInterp_base::_interp) {
27 _savestate = PyGILState_Ensure();
29 PyEval_AcquireThread(myThreadState);
32 PyEval_AcquireThread(myThreadState);
36 PyLockWrapper::~PyLockWrapper()
38 #if defined(USE_GILSTATE)
39 if (myThreadState->interp == PyInterp_base::_interp) {
40 PyGILState_Release(_savestate);
42 PyEval_ReleaseThread(myThreadState);
45 PyEval_ReleaseThread(myThreadState);
57 PyLockWrapper PyInterp_base::GetLockWrapper(){
62 // main python interpreter (static attributes)
64 int PyInterp_base::_argc = 1;
65 char* PyInterp_base::_argv[] = {""};
67 PyObject *PyInterp_base::builtinmodule = NULL;
69 PyThreadState *PyInterp_base::_gtstate = NULL;
70 PyInterpreterState *PyInterp_base::_interp = NULL;
74 * basic constructor here : herited classes constructors must call initalize() method
77 PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
81 PyInterp_base::~PyInterp_base()
87 * Must be called by herited classes constructors. initialize() calls virtuals methods
88 * initstate & initcontext, not defined here in base class. initstate & initcontext methods
89 * must be implemented in herited classes, following the Python interpreter policy
90 * (mono or multi interpreter...).
92 void PyInterp_base::initialize()
94 _history.clear(); // start a new list of user's commands
95 _ith = _history.begin();
98 // Here the global lock is released
102 PyLockWrapper aLock= GetLockWrapper();
106 // used to interpret & compile commands
107 PyObjWrapper m(PyImport_ImportModule("codeop"));
113 // Create cStringIO to capture stdout and stderr
115 if (PycStringIO) { // CTH11627 : additional check
116 _vout = PycStringIO->NewOutput(128);
117 _verr = PycStringIO->NewOutput(128);
120 // All the initRun outputs are redirected to the standard output (console)
124 void PyInterp_base::init_python()
127 if (Py_IsInitialized())
130 // Python is not initialized
131 Py_SetProgramName(_argv[0]);
132 Py_Initialize(); // Initialize the interpreter
133 PySys_SetArgv(_argc, _argv);
134 PyEval_InitThreads(); // Create (and acquire) the interpreter lock
135 _interp = PyThreadState_Get()->interp;
136 _gtstate = PyEval_SaveThread(); // Release global thread state
139 string PyInterp_base::getbanner()
141 // Should we take the lock ?
142 // PyEval_RestoreThread(_tstate);
143 string aBanner("Python ");
144 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
145 aBanner = aBanner + "\ntype help to get general information on environment\n";
146 //PyEval_SaveThread();
151 int PyInterp_base::initRun()
153 PySys_SetObject("stderr",_verr);
154 PySys_SetObject("stdout",_vout);
156 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
157 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
159 //PyObject *m = PyImport_GetModuleDict();
161 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
162 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
169 * This function compiles a string (command) and then evaluates it in the dictionnary
170 * context if possible.
173 * 1 : incomplete text
174 * 0 : complete text executed with success
176 int compile_command(const char *command,PyObject *context)
178 PyObject *m = PyImport_AddModule("codeop");
179 if(!m){ // Fatal error. No way to go on.
183 PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
185 // Error encountered. It should be SyntaxError,
186 //so we don't write out traceback
187 PyObjWrapper exception, value, tb;
188 PyErr_Fetch(&exception, &value, &tb);
189 PyErr_NormalizeException(&exception, &value, &tb);
190 PyErr_Display(exception, value, NULL);
192 }else if (v == Py_None){
193 // Incomplete text we return 1 : we need a complete text to execute
196 // Complete and correct text. We evaluate it.
197 //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
198 // PyObjWrapper r(PyEval_EvalCode(v,context,context));
200 PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
203 // Execution error. We return -1
207 // The command has been successfully executed. Return 0
213 int PyInterp_base::run(const char *command)
217 ret = simpleRun("from Help import *");
222 ret = simpleRun("import salome");
227 ret = simpleRun("salome.salome_init(0,1)");
234 return simpleRun(command);
238 int PyInterp_base::simpleRun(const char *command)
240 if( !_atFirst && strcmp(command,"") != 0 ) {
241 _history.push_back(command);
242 _ith = _history.end();
245 // We come from C++ to enter Python world
246 // We need to acquire the Python global lock
247 //PyLockWrapper aLock(_tstate); // san - lock is centralized now
249 // Reset redirected outputs before treatment
250 PySys_SetObject("stderr",_verr);
251 PySys_SetObject("stdout",_vout);
253 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
254 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
256 int ier = compile_command(command,_g);
258 // Outputs are redirected on standards outputs (console)
259 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
260 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
266 const char * PyInterp_base::getPrevious()
268 if(_ith != _history.begin()){
270 return (*_ith).c_str();
273 return BEGIN_HISTORY_PY;
277 const char * PyInterp_base::getNext()
279 if(_ith != _history.end()){
282 if (_ith == _history.end())
283 return TOP_HISTORY_PY;
285 return (*_ith).c_str();
289 string PyInterp_base::getverr(){
290 //PyLockWrapper aLock(_tstate);
291 PyObjWrapper v(PycStringIO->cgetvalue(_verr));
292 string aRet(PyString_AsString(v));
297 string PyInterp_base::getvout(){
298 //PyLockWrapper aLock(_tstate);
299 PyObjWrapper v(PycStringIO->cgetvalue(_vout));
300 string aRet(PyString_AsString(v));