Salome HOME
INT PAL 0052660: Plot2D Viewer: Plot2d_Curve can't be selected
[modules/gui.git] / src / PyInterp / PyInterp_Interp.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : PyInterp_Interp.cxx
24 //  Author : Christian CAREMOLI, Paul RASCLE, Adrien BRUNETON
25 //  Module : SALOME
26 //
27 #include "PyInterp_Interp.h"  // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
28 #include "PyInterp_Utils.h"
29 #include <pythread.h>
30
31 #include <cStringIO.h>
32 #include <structmember.h>
33
34 #include <string>
35 #include <vector>
36 #include <map>
37 #include <iostream>
38 #include <algorithm>
39
40 #define TOP_HISTORY_PY   "--- top of history ---"
41 #define BEGIN_HISTORY_PY "--- begin of history ---"
42
43 /*
44   The following functions are used to hook the Python
45   interpreter output.
46 */
47
48 static void
49 PyStdOut_dealloc(PyStdOut *self)
50 {
51   PyObject_Del(self);
52 }
53
54 static PyObject*
55 PyStdOut_write(PyStdOut *self, PyObject *args)
56 {
57   char *c;
58   int l;
59   if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
60     return NULL;
61   if(self->_cb==NULL) {
62     if ( self->_iscerr )
63       std::cerr << c ;
64     else
65       std::cout << c ;
66   }
67   else {
68     self->_cb(self->_data,c);
69   }
70   Py_INCREF(Py_None);
71   return Py_None;
72 }
73
74 static PyObject*
75 PyStdOut_flush(PyStdOut *self)
76 {
77   Py_INCREF(Py_None);
78   return Py_None;
79 }
80
81 static PyMethodDef PyStdOut_methods[] = {
82   {"write",  (PyCFunction)PyStdOut_write,  METH_VARARGS, PyDoc_STR("write(string) -> None")},
83   {"flush",  (PyCFunction)PyStdOut_flush,  METH_NOARGS,  PyDoc_STR("flush() -> None")},
84   {NULL,    NULL}   /* sentinel */
85 };
86
87 static PyMemberDef PyStdOut_memberlist[] = {
88   {(char*)"softspace", T_INT,  offsetof(PyStdOut, softspace), 0,
89    (char*)"flag indicating that a space needs to be printed; used by print"},
90   {NULL} /* Sentinel */
91 };
92
93 static PyTypeObject PyStdOut_Type = {
94   /* The ob_type field must be initialized in the module init function
95    * to be portable to Windows without using C++. */
96   PyObject_HEAD_INIT(NULL)
97   0,                            /*ob_size*/
98   "PyOut",                      /*tp_name*/
99   sizeof(PyStdOut),             /*tp_basicsize*/
100   0,                            /*tp_itemsize*/
101   /* methods */
102   (destructor)PyStdOut_dealloc, /*tp_dealloc*/
103   0,                            /*tp_print*/
104   0,                            /*tp_getattr*/
105   0,                            /*tp_setattr*/
106   0,                            /*tp_compare*/
107   0,                            /*tp_repr*/
108   0,                            /*tp_as_number*/
109   0,                            /*tp_as_sequence*/
110   0,                            /*tp_as_mapping*/
111   0,                            /*tp_hash*/
112   0,                            /*tp_call*/
113   0,                            /*tp_str*/
114   PyObject_GenericGetAttr,      /*tp_getattro*/
115   /* softspace is writable:  we must supply tp_setattro */
116   PyObject_GenericSetAttr,      /* tp_setattro */
117   0,                            /*tp_as_buffer*/
118   Py_TPFLAGS_DEFAULT,           /*tp_flags*/
119   0,                            /*tp_doc*/
120   0,                            /*tp_traverse*/
121   0,                            /*tp_clear*/
122   0,                            /*tp_richcompare*/
123   0,                            /*tp_weaklistoffset*/
124   0,                            /*tp_iter*/
125   0,                            /*tp_iternext*/
126   PyStdOut_methods,             /*tp_methods*/
127   PyStdOut_memberlist,          /*tp_members*/
128   0,                            /*tp_getset*/
129   0,                            /*tp_base*/
130   0,                            /*tp_dict*/
131   0,                            /*tp_descr_get*/
132   0,                            /*tp_descr_set*/
133   0,                            /*tp_dictoffset*/
134   0,                            /*tp_init*/
135   0,                            /*tp_alloc*/
136   0,                            /*tp_new*/
137   0,                            /*tp_free*/
138   0,                            /*tp_is_gc*/
139 };
140
141 #define PyStdOut_Check(v)  ((v)->ob_type == &PyStdOut_Type)
142
143 static PyStdOut* newPyStdOut( bool iscerr )
144 {
145   PyStdOut *self;
146   self = PyObject_New(PyStdOut, &PyStdOut_Type);
147   if (self == NULL)
148     return NULL;
149   self->softspace = 0;
150   self->_cb = NULL;
151   self->_iscerr = iscerr;
152   return self;
153 }
154
155 /*!
156   \class PyInterp_Interp
157   \brief Generic embedded Python interpreter.
158 */
159
160 int   PyInterp_Interp::_argc   = 1;
161 char* PyInterp_Interp::_argv[] = {(char*)""};
162
163 /*!
164   \brief Basic constructor.
165
166   After construction the interpreter instance successor classes
167   must call virtual method initalize().
168 */
169 PyInterp_Interp::PyInterp_Interp():
170   _vout(0), _verr(0), _local_context(0), _global_context(0)
171 {
172 }
173
174
175
176 /*!
177   \brief Destructor.
178 */
179 PyInterp_Interp::~PyInterp_Interp()
180 {
181   destroy();
182 }
183
184 /*!
185   \brief Initialize embedded interpreter.
186
187   This method shoud be called after construction of the interpreter.
188   The method initialize() calls virtuals methods
189   - initPython()  to initialize global Python interpreter
190   - initContext() to initialize interpreter internal context
191   - initRun()     to prepare interpreter for running commands
192   which should be implemented in the successor classes, according to the
193   embedded Python interpreter policy (mono or multi interpreter, etc).
194 */
195 void PyInterp_Interp::initialize()
196 {
197   _history.clear();       // start a new list of user's commands
198   _ith = _history.begin();
199
200   initPython();  // This also inits the multi-threading for Python (but w/o acquiring GIL)
201
202   //initState(); // [ABN] OBSOLETE
203
204   // ---- The rest of the initialisation process is done hodling the GIL
205   PyLockWrapper lck;
206
207   initContext();
208
209   // used to interpret & compile commands - this is really imported here
210   // and only added again (with PyImport_AddModule) later on
211   PyObjWrapper m(PyImport_ImportModule("codeop"));
212   if(!m) {
213     PyErr_Print();
214     return;
215   }
216
217   // Create python objects to capture stdout and stderr
218   _vout=(PyObject*)newPyStdOut( false ); // stdout
219   _verr=(PyObject*)newPyStdOut( true );  // stderr
220
221   // All the initRun outputs are redirected to the standard output (console)
222   initRun();
223 }
224
225 void PyInterp_Interp::destroy()
226 {
227   PyLockWrapper lck;
228   closeContext();
229 }
230
231 /*!
232   \brief Initialize Python interpreter.
233
234   In case if Python is not initialized, it sets program name, initializes the single true Python
235   interpreter, sets program arguments, and initializes threads.
236   Otherwise, does nothing. This is important for light SALOME configuration,
237   as in full SALOME this is done at SalomeApp level.
238   \sa SalomeApp_PyInterp class and main() in SALOME_Session_Server
239  */
240 void PyInterp_Interp::initPython()
241 {
242   if (!Py_IsInitialized()){
243     // Python is not initialized
244     Py_SetProgramName(_argv[0]);
245     Py_Initialize(); // Initialize the interpreter
246     PySys_SetArgv(_argc, _argv);
247
248     PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
249     PyEval_ReleaseLock();
250   }
251 }
252
253 /*!
254   \brief Get embedded Python interpreter banner.
255   \return banner string
256  */
257 std::string PyInterp_Interp::getbanner() const
258 {
259   PyLockWrapper lck;
260   std::string aBanner("Python ");
261   aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
262   aBanner = aBanner + "\ntype help to get general information on environment\n";
263   return aBanner;
264 }
265
266 /*!
267   \brief Initialize run command.
268
269   This method is used to prepare interpreter for running
270   Python commands.
271
272   \return \c true on success and \c false on error
273 */
274 bool PyInterp_Interp::initRun()
275 {
276   return true;
277 }
278
279 /*!
280  * Initialize context dictionaries. GIL is held already.
281  * The code executed in an embedded interpreter is expected to be run at the module
282  * level, in which case local and global context have to be the same dictionary.
283  * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
284  * for an explanation.
285  */
286 bool PyInterp_Interp::initContext()
287 {
288   PyObject *m = PyImport_AddModule("__main__");  // interpreter main module (module context)
289   if(!m){
290     PyErr_Print();
291     return false;
292   }
293   _global_context = PyModule_GetDict(m);          // get interpreter global variable context
294   Py_INCREF(_global_context);
295   _local_context = _global_context;
296
297   int ret = PyRun_SimpleString("import salome_iapp;salome_iapp.IN_SALOME_GUI=True");
298
299   return ret == 0;
300 }
301
302 /*!
303  * Destroy context dictionaries. GIL is held already.
304  */
305 void PyInterp_Interp::closeContext()
306 {
307   Py_XDECREF(_global_context);
308   // both _global and _local point to the same Python object:
309   // Py_XDECREF(_local_context);
310 }
311
312 /*!
313   \brief Compile Python command and evaluate it in the
314          python dictionary contexts if possible. This is not thread-safe.
315          This is the caller's responsability to make this thread-safe.
316   \internal
317   \param command Python command string
318   \return -1 on fatal error, 1 if command is incomplete and 0
319          if command is executed successfully
320  */
321 static int run_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
322 {
323   PyObject *m = PyImport_AddModule("codeop");
324   if(!m) { // Fatal error. No way to go on.
325     PyErr_Print();
326     return -1;
327   }
328
329 //  PyObjWrapper v(Py_CompileString(command, "<salome_input>", Py_file_input));
330   PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
331   if(!v) {
332     // Error encountered. It should be SyntaxError,
333     //so we don't write out traceback
334     PyObjWrapper exception, value, tb;
335     PyErr_Fetch(&exception, &value, &tb);
336     PyErr_NormalizeException(&exception, &value, &tb);
337     PyErr_Display(exception, value, NULL);
338     return -1;
339   }
340   else if (v == Py_None) {
341     // Incomplete text we return 1 : we need a complete text to execute
342     return 1;
343   }
344   else {
345     PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,global_ctxt, local_ctxt));
346     if(!r) {
347       // Execution error. We return -1
348       PyErr_Print();
349       return -1;
350     }
351     // The command has been successfully executed. Return 0
352     return 0;
353   }
354 }
355
356 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
357     if(from.empty())
358         return;
359     size_t start_pos = 0;
360     while((start_pos = str.find(from, start_pos)) != std::string::npos) {
361         str.replace(start_pos, from.length(), to);
362         start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
363     }
364 }
365 /*!
366   \brief Compile Python command and evaluate it in the
367          python dictionary context if possible. Command might correspond to
368          the execution of a script with optional arguments.
369          In this case, command is:
370          execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
371   \internal
372   \param command Python command string
373   \param context Python context (dictionary)
374   \return -1 on fatal error, 1 if command is incomplete and 0
375          if command is executed successfully
376  */
377 static int compile_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
378 {
379   // First guess if command is execution of a script with args, or a simple Python command
380   std::string singleCommand = command;
381   std::string commandArgs = "";
382
383   std::size_t pos = std::string(command).find("args:");
384   if (pos != std::string::npos) {
385     commandArgs = singleCommand.substr(pos+5);
386     commandArgs = commandArgs.substr(0, commandArgs.length()-3);
387     singleCommand = singleCommand.substr(0, pos-1)+"\")";
388   }
389
390   if (commandArgs.empty()) {
391     // process command: expression
392     // process command: execfile(r"/absolute/path/to/script.py") (no args)
393     return run_command(singleCommand.c_str(), global_ctxt, local_ctxt);
394   }
395   else {
396     // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
397     std::string script = singleCommand.substr(11); // remove leading execfile(r"
398     script = script.substr(0, script.length()-2); // remove trailing ")
399
400     std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
401     std::string preCommandEnd = "];";
402     replaceAll(commandArgs, ",", "\",\"");
403     commandArgs = "\""+commandArgs+"\"";
404     std::string completeCommand = preCommandBegin+"\""+script+"\","+commandArgs+preCommandEnd+singleCommand+";sys.argv=save_argv";
405     return run_command(completeCommand.c_str(), global_ctxt, local_ctxt);
406   }
407 }
408
409 /*!
410   \brief Run Python command - the command has to fit on a single line (no \n!).
411   Use ';' if you need multiple statements evaluated at once.
412   \param command Python command
413   \return command status
414 */
415 int PyInterp_Interp::run(const char *command)
416 {
417   beforeRun();
418   int ret = simpleRun(command);
419   afterRun();
420   return ret;
421 }
422
423 /**
424  * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
425  * to acquire GIL if needed.
426  */
427 int PyInterp_Interp::beforeRun()
428 {
429   return 0;
430 }
431
432 /**
433  * Called after a command is run (when calling run() method). Not thread-safe. Caller's responsability
434  * to acquire GIL if needed.
435  */
436 int PyInterp_Interp::afterRun()
437 {
438   return 0;
439 }
440
441 /*!
442   \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
443   \param command Python command
444   \param addToHistory if \c true (default), the command is added to the commands history
445   \return command status
446 */
447 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
448 {
449   if( addToHistory && strcmp(command,"") != 0 ) {
450     _history.push_back(command);
451     _ith = _history.end();
452   }
453
454   // Current stdout and stderr are saved
455   PyObject * oldOut = PySys_GetObject((char*)"stdout");
456   PyObject * oldErr = PySys_GetObject((char*)"stderr");
457   // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
458   Py_INCREF(oldOut);
459   Py_INCREF(oldErr);
460
461   // Redirect outputs to SALOME Python console before treatment
462   PySys_SetObject((char*)"stderr",_verr);
463   PySys_SetObject((char*)"stdout",_vout);
464
465   int ier = compile_command(command, _global_context, _local_context);
466
467   // Outputs are redirected to what they were before
468   PySys_SetObject((char*)"stdout",oldOut);
469   PySys_SetObject((char*)"stderr",oldErr);
470
471   return ier;
472 }
473
474 /*!
475   \brief Get previous command in the commands history.
476   \return previous command
477 */
478 const char * PyInterp_Interp::getPrevious()
479 {
480   if(_ith != _history.begin()){
481     _ith--;
482     return (*_ith).c_str();
483   }
484   else
485     return BEGIN_HISTORY_PY;
486 }
487
488 /*!
489   \brief Get next command in the commands history.
490   \return next command
491 */
492 const char * PyInterp_Interp::getNext()
493 {
494   if(_ith != _history.end()){
495     _ith++;
496   }
497   if (_ith == _history.end())
498     return TOP_HISTORY_PY;
499   else
500     return (*_ith).c_str();
501 }
502
503 /*!
504   \brief Set Python standard output device hook.
505   \param cb callback function
506   \param data callback function parameters
507 */
508 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
509 {
510   ((PyStdOut*)_vout)->_cb=cb;
511   ((PyStdOut*)_vout)->_data=data;
512 }
513
514 /*!
515   \brief Set Python standard error device hook.
516   \param cb callback function
517   \param data callback function parameters
518 */
519 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
520 {
521   ((PyStdOut*)_verr)->_cb=cb;
522   ((PyStdOut*)_verr)->_data=data;
523 }