]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Porting to Qt4
authorvsr <vsr@opencascade.com>
Tue, 15 May 2007 10:36:00 +0000 (10:36 +0000)
committervsr <vsr@opencascade.com>
Tue, 15 May 2007 10:36:00 +0000 (10:36 +0000)
src/PyInterp/Makefile.am
src/PyInterp/PyInterp.h
src/PyInterp/PyInterp.pro [new file with mode: 0644]
src/PyInterp/PyInterp_Dispatcher.cxx
src/PyInterp/PyInterp_Dispatcher.h
src/PyInterp/PyInterp_Interp.cxx [new file with mode: 0644]
src/PyInterp/PyInterp_Interp.h [new file with mode: 0644]
src/PyInterp/PyInterp_Watcher.h
src/PyInterp/PyInterp_base.cxx [deleted file]
src/PyInterp/PyInterp_base.h [deleted file]

index 9a783f209a1b7a9a091b3c1248cb1b4f06113105..7a451b4adfc1024b4a82a3019b8bb3516e30c1f9 100755 (executable)
@@ -27,13 +27,13 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 lib_LTLIBRARIES = libPyInterp.la
 
-salomeinclude_HEADERS= \
-       PyInterp.h \
-       PyInterp_base.h \
+salomeinclude_HEADERS=         \
+       PyInterp.h              \
+       PyInterp_Interp.h       \
        PyInterp_Dispatcher.h
 
-dist_libPyInterp_la_SOURCES= \
-       PyInterp_base.cxx \
+dist_libPyInterp_la_SOURCES=   \
+       PyInterp_Interp.cxx     \
        PyInterp_Dispatcher.cxx
 
 MOC_FILES= PyInterp_Watcher_moc.cxx
index af9536fd88e7e9c2caafeca55e30800b27b9dfdb..4f2777d0002013fa17383d5bb216c78fa35b800d 100755 (executable)
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-#if !defined ( _PYINTERP_H )
-#define _PYINTERP_H
+//  File   : PyInterp.h
+//  Author : Vadim SANDLER
+//  Module : SALOME
+
+#if !defined ( PYINTERP_H )
+#define PYINTERP_H
 
 // ========================================================
 // set dllexport type for Win platform 
-#ifdef WNT
-
-#ifdef PYINTERP_EXPORTS
-#define PYINTERP_EXPORT __declspec(dllexport)
-#else
-#define PYINTERP_EXPORT __declspec(dllimport)
-#endif
-
-#else   // WNT
-
-#define PYINTERP_EXPORT
-
-#endif  // WNT
+#ifdef WIN32
+# ifdef PYINTERP_EXPORTS
+#  define PYINTERP_EXPORT __declspec(dllexport)
+# else
+#  define PYINTERP_EXPORT __declspec(dllimport)
+# endif
+#else   // WIN32
+# define PYINTERP_EXPORT
+#endif  // WIN32
 
 // ========================================================
 // little trick - if we do not have debug python libraries
@@ -53,9 +53,9 @@
 
 // ========================================================
 // avoid warning messages
-#ifdef WNT
+#ifdef WIN32
 #pragma warning (disable : 4786)
 #pragma warning (disable : 4251)
 #endif
 
-#endif // _PYINTERP_H
+#endif // PYINTERP_H
diff --git a/src/PyInterp/PyInterp.pro b/src/PyInterp/PyInterp.pro
new file mode 100644 (file)
index 0000000..4c35c06
--- /dev/null
@@ -0,0 +1,33 @@
+TEMPLATE = lib
+TARGET = PyInterp
+DESTDIR = ../../lib
+MOC_DIR = ../../moc
+OBJECTS_DIR = ../../obj/$$TARGET
+
+PYTHONVER=2.4
+PYTHONHOME=$$(PYTHONHOME)
+PYTHONINC=$${PYTHONHOME}/include/python$${PYTHONVER}
+PYTHONLIB=$${PYTHONHOME}/lib
+
+INCLUDEPATH += ../../include $${PYTHONINC}
+unix:LIBS  += -L$${PYTHONLIB} -lpython$${PYTHONVER}
+win32:LIBS += /LIBPATH:$${PYTHONLIB}
+
+CONFIG -= debug release debug_and_release
+CONFIG += qt thread debug dll shared
+
+win32:DEFINES += WIN32
+DEFINES += PYINTERP_EXPORTS
+
+HEADERS  = PyInterp.h
+HEADERS += PyInterp_Dispatcher.h
+HEADERS += PyInterp_Watcher.h
+HEADERS += PyInterp_Interp.h
+
+SOURCES  = PyInterp_Dispatcher.cxx
+SOURCES += PyInterp_Interp.cxx
+
+includes.files = $$HEADERS
+includes.path = ../../include
+
+INSTALLS += includes
index dd029a25bd64a04e6086e128134b982267c980a6..e3adb001d7f0ee33789b683ef02856a4784bc994 100755 (executable)
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
-//
 //  File   : PyInterp_Dispatcher.cxx
 //  Author : Sergey ANIKIN, OCC
 //  Module : GUI
-//  $Header$
-
 
-#include <PyInterp_base.h>
-#include <PyInterp_Dispatcher.h>
-#include <PyInterp_Watcher.h>
+#include "PyInterp_Dispatcher.h"   // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+#include "PyInterp_Interp.h"
+#include "PyInterp_Watcher.h"
 
-#include <qapplication.h>
-#include <qobject.h>
+#include <QObject>
+#include <QCoreApplication>
 
-//#include <utilities.h>
 using namespace std;
 
 PyInterp_Dispatcher* PyInterp_Dispatcher::myInstance = 0;
@@ -40,11 +35,16 @@ void PyInterp_Request::process()
 {
   safeExecute();
 
-  myMutex.lock();
-  //if ( !IsSync() && getListener() && getEvent() )
-  if ( getListener() && getEvent() )
-    postEvent();
-  myMutex.unlock();
+  bool isSync = IsSync();
+
+  if ( !isSync )
+    myMutex.lock();
+
+  if ( listener() )
+    processEvent( listener() );
+
+  if ( !isSync )
+    myMutex.unlock();
 }
 
 void PyInterp_Request::safeExecute()
@@ -65,23 +65,22 @@ QEvent* PyInterp_Request::createEvent() const
   return new PyInterp_Event( PyInterp_Event::NOTIFY, (PyInterp_Request*)this );
 }
 
-QEvent* PyInterp_Request::getEvent()
+void PyInterp_Request::processEvent( QObject* o )
 {
-  //if ( !myEvent && !IsSync() )
-  if ( !myEvent )
-    myEvent = createEvent();
-  return myEvent;
-}
+  if ( !o )
+    return;
 
-void PyInterp_Request::postEvent()
-{
-#if QT_VERSION >= 0x030303
-//  MESSAGE("*** PyInterp_Request::postEvent(): for Qt 3.3.3")
-  QApplication::postEvent( getListener(), getEvent() );
-#else
-//  MESSAGE("*** PyInterp_Request::postEvent(): for Qt 3.0.5")
-  QThread::postEvent( getListener(), getEvent() );
-#endif
+  QEvent* e = createEvent();
+  if ( !e )
+    return;
+
+  if ( !IsSync() )
+    QCoreApplication::postEvent( o, e );
+  else
+  {
+    QCoreApplication::sendEvent( o, e );
+    delete e;
+  }
 }
 
 void PyInterp_Request::setListener( QObject* o )
@@ -123,8 +122,9 @@ PyInterp_Dispatcher::~PyInterp_Dispatcher()
   // Clear the request queue
   myQueueMutex.lock();
 
-  for ( std::list<PyInterp_Request*>::iterator it = myQueue.begin(); it != myQueue.end(); ++it )
-    PyInterp_Request::Destroy( *it );
+  QListIterator<RequestPtr> it( myQueue );
+  while ( it.hasNext() )
+    PyInterp_Request::Destroy( it.next() );
   myQueue.clear();
 
   myQueueMutex.unlock();
@@ -138,7 +138,7 @@ PyInterp_Dispatcher::~PyInterp_Dispatcher()
 
 bool PyInterp_Dispatcher::IsBusy() const
 {
-  return running();
+  return isRunning();
 }
 
 void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest )
@@ -149,11 +149,12 @@ void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest )
   //if ( theRequest->IsSync() && !IsBusy() ) // synchronous processing - nothing is done if dispatcher is busy!
   if ( theRequest->IsSync() ) // synchronous processing - nothing is done if dispatcher is busy!
     processRequest( theRequest );
-  else { // asynchronous processing
+  else // asynchronous processing
+  {
     myQueueMutex.lock();
-    myQueue.push_back( theRequest );
-    if ( theRequest->getListener() )
-      QObject::connect( theRequest->getListener(), SIGNAL( destroyed( QObject* ) ), myWatcher, SLOT( onDestroyed( QObject* ) ) );
+    myQueue.enqueue( theRequest );
+    if ( theRequest->listener() )
+      QObject::connect( theRequest->listener(), SIGNAL( destroyed( QObject* ) ), myWatcher, SLOT( onDestroyed( QObject* ) ) );
     myQueueMutex.unlock();  
 
     if ( !IsBusy() )
@@ -171,7 +172,7 @@ void PyInterp_Dispatcher::run()
 
   while( myQueue.size() ) {
 //    MESSAGE("*** PyInterp_Dispatcher::run(): next request taken from the queue")
-    aRequest = myQueue.front();
+    aRequest = myQueue.head();
 
     // let other threads append their requests to the end of the queue
     myQueueMutex.unlock();
@@ -183,8 +184,8 @@ void PyInterp_Dispatcher::run()
     // prepare for removal of the first request in the queue
     myQueueMutex.lock();
     // IMPORTANT: the first item could have been removed by objectDestroyed() --> we have to check it
-    if ( myQueue.front() == aRequest ) // It's still here --> remove it
-      myQueue.pop_front();
+    if ( myQueue.head() == aRequest ) // It's still here --> remove it
+      myQueue.dequeue();
 
 //    MESSAGE("*** PyInterp_Dispatcher::run(): request processed")
   }
@@ -203,13 +204,16 @@ void PyInterp_Dispatcher::objectDestroyed( const QObject* o )
   // prepare for modification of the queue
   myQueueMutex.lock();
 
-  for ( std::list<RequestPtr>::iterator it = myQueue.begin(); it != myQueue.end(); ++it ){
-    if ( o == (*it)->getListener() ){
-      (*it)->setListener( 0 ); // to prevent event posting
-      it = myQueue.erase( it );
+  QMutableListIterator<RequestPtr> it( myQueue );
+  while ( it.hasNext() )
+  {
+    RequestPtr r = it.next();
+    if ( o == r->listener() )
+    {
+      r->setListener( 0 ); // to prevent event posting
+      it.remove();
     }
   }
 
   myQueueMutex.unlock();
 }
-
index 311c9e66f70499cd95bdfecd73662c27e92f5e32..511fbbdb41542a9966c284f7b597301afc46dd4a 100755 (executable)
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
-//
 //  File   : PyInterp_Dispatcher.h
 //  Author : Sergey Anikin, OCC
 //  Module : SALOME
 
-#ifndef _PYINTERP_DISPATCHER_H_
-#define _PYINTERP_DISPATCHER_H_
-
-#include "PyInterp.h"
+#ifndef PYINTERP_DISPATCHER_H
+#define PYINTERP_DISPATCHER_H
 
-#include <qthread.h>
-#include <qevent.h>
+#include "PyInterp.h"   // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
 
-#include <list>
+#include <QMutex>
+#include <QThread>
+#include <QEvent>
+#include <QQueue>
 
 class QObject;
 
-class PyInterp_base;
+class PyInterp_Interp;
 class PyInterp_Watcher;
 class PyInterp_Dispatcher;
 
@@ -46,12 +44,12 @@ class PYINTERP_EXPORT PyInterp_Request
   PyInterp_Request( const PyInterp_Request& );
 
 protected:
-  virtual         ~PyInterp_Request() {}; 
+  virtual ~PyInterp_Request() {};
   // protected destructor - to control deletion of requests
 
 public:
   PyInterp_Request( QObject* listener, bool sync = false )
-    : myIsSync( sync ), myListener( listener ), myEvent( 0 ) {};
+    : myIsSync( sync ), myListener( listener ) {};
 
   static void     Destroy( PyInterp_Request* );
   // Deletes a request
@@ -69,36 +67,35 @@ protected:
   virtual QEvent* createEvent() const;
   // This method can be overridden to customize notification event creation
 
+  virtual void    processEvent( QObject* );
+
 private:
   void            process();
-  QObject*        getListener() const { return myListener; }
+  QObject*        listener() const { return myListener; }
   void            setListener( QObject* );
-  QEvent*         getEvent();
-  void            postEvent();
 
 private:
+  QMutex          myMutex;
   bool            myIsSync;
   QObject*        myListener;
-  QEvent*         myEvent;
-  QMutex          myMutex;
 };
 
 class PYINTERP_EXPORT PyInterp_LockRequest : public PyInterp_Request
 {
 public:
-  PyInterp_LockRequest( PyInterp_base* interp, QObject* listener = 0, bool sync = false )
+  PyInterp_LockRequest( PyInterp_Interp* interp, QObject* listener = 0, bool sync = false )
     : PyInterp_Request( listener, sync ), myInterp( interp ) {}
 
 protected:
-  PyInterp_base*  getInterp() const { return myInterp; }
+  PyInterp_Interp*  getInterp() const { return myInterp; }
 
-  virtual void    safeExecute();
+  virtual void      safeExecute();
 
 private:
-  PyInterp_base*  myInterp;
+  PyInterp_Interp*  myInterp;
 };
 
-class PYINTERP_EXPORT PyInterp_Event : public QCustomEvent
+class PYINTERP_EXPORT PyInterp_Event : public QEvent
 {
   PyInterp_Event();
   PyInterp_Event( const PyInterp_Event& );
@@ -107,7 +104,7 @@ public:
   enum { NOTIFY = QEvent::User + 5000, OK, ERROR, INCOMPLETE, LAST };
 
   PyInterp_Event( int type, PyInterp_Request* request )
-    : QCustomEvent( (QEvent::Type)type ), myRequest( request ) {}
+    : QEvent( (QEvent::Type)type ), myRequest( request ) {}
 
   virtual ~PyInterp_Event();
 
@@ -138,7 +135,7 @@ private:
 private:
   typedef PyInterp_Request*   RequestPtr;
 
-  std::list<RequestPtr>       myQueue;
+  QQueue<RequestPtr>          myQueue;
   QMutex                      myQueueMutex;
   PyInterp_Watcher*           myWatcher;
 
@@ -147,4 +144,4 @@ private:
   friend class PyInterp_Watcher;
 };
 
-#endif
+#endif // PYINTERP_DISPATCHER_H
diff --git a/src/PyInterp/PyInterp_Interp.cxx b/src/PyInterp/PyInterp_Interp.cxx
new file mode 100644 (file)
index 0000000..75503c3
--- /dev/null
@@ -0,0 +1,330 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library is distributed in the hope that it will be useful 
+// but WITHOUT ANY WARRANTY; without even the implied warranty of 
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : PyInterp_Interp.cxx
+//  Author : Christian CAREMOLI, Paul RASCLE, EDF
+//  Module : SALOME
+
+#include "PyInterp_Interp.h"  // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+
+#include <cStringIO.h>
+
+#include <string>
+#include <vector>
+
+using namespace std;
+
+#define TOP_HISTORY_PY   "--- top of history ---"
+#define BEGIN_HISTORY_PY "--- begin of history ---"
+
+PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): 
+  myThreadState(theThreadState),
+  mySaveThreadState(0)
+{
+  if (myThreadState->interp == PyInterp_Interp::_interp)
+    _savestate = PyGILState_Ensure();
+  else
+    PyEval_AcquireThread(myThreadState);
+}
+
+PyLockWrapper::~PyLockWrapper()
+{
+  if (myThreadState->interp == PyInterp_Interp::_interp)
+    PyGILState_Release(_savestate);
+  else
+    PyEval_ReleaseThread(myThreadState);
+}
+
+PyLockWrapper PyInterp_Interp::GetLockWrapper()
+{
+  return _tstate;
+}
+
+/*!
+  \class PyInterp_Interp
+  \brief Generic embedded Python interpreter.
+*/
+
+int   PyInterp_Interp::_argc   = 1;
+char* PyInterp_Interp::_argv[] = {""};
+PyObject*           PyInterp_Interp::builtinmodule = NULL;
+PyThreadState*      PyInterp_Interp::_gtstate      = NULL;
+PyInterpreterState* PyInterp_Interp::_interp       = NULL;
+
+/*!
+  \brief Basic constructor.
+  
+  After construction the interpreter instance successor classes 
+  must call virtual method initalize().
+*/
+PyInterp_Interp::PyInterp_Interp(): 
+  _tstate(0), _vout(0), _verr(0), _g(0)
+{
+}
+
+/*!
+  \brief Destructor.
+*/
+PyInterp_Interp::~PyInterp_Interp()
+{
+}
+
+/*!
+  \brief Initialize embedded interpreter.
+  
+  This method shoud be called after construction of the interpreter.
+  The method initialize() calls virtuals methods
+  - initPython()  to initialize global Python interpreter
+  - initState()   to initialize embedded interpreter state
+  - initContext() to initialize interpreter internal context
+  - initRun()     to prepare interpreter for running commands
+  which should be implemented in the successor classes, according to the
+  embedded Python interpreter policy (mono or multi interpreter, etc).
+*/
+void PyInterp_Interp::initialize()
+{
+  _history.clear();       // start a new list of user's commands 
+  _ith = _history.begin();
+
+  initPython();
+  // Here the global lock is released
+
+  initState();
+
+  PyLockWrapper aLock = GetLockWrapper();
+
+  initContext();
+
+  // used to interpret & compile commands
+  PyObjWrapper m(PyImport_ImportModule("codeop"));
+  if(!m) {
+    PyErr_Print();
+    return;
+  }
+
+  // Create cStringIO to capture stdout and stderr
+  PycString_IMPORT;
+  if (PycStringIO) { // CTH11627 : additional check
+    _vout = PycStringIO->NewOutput(128);
+    _verr = PycStringIO->NewOutput(128);
+  }
+
+  // All the initRun outputs are redirected to the standard output (console)
+  initRun();
+}
+
+/*!
+  \brief Initialize Python interpreter.
+
+  Set program name, initialize interpreter, set program arguments,
+  initiaize threads.
+ */
+void PyInterp_Interp::initPython()
+{
+  if (Py_IsInitialized())
+    return;
+
+  // Python is not initialized
+  Py_SetProgramName(_argv[0]);
+  Py_Initialize(); // Initialize the interpreter
+  PySys_SetArgv(_argc, _argv);
+  PyEval_InitThreads(); // Create (and acquire) the interpreter lock
+  _interp = PyThreadState_Get()->interp;
+  _gtstate = PyEval_SaveThread(); // Release global thread state
+}
+
+/*!
+  \brief Get embedded Python interpreter banner.
+  \return banner string
+ */
+string PyInterp_Interp::getbanner()
+{
+ // Should we take the lock ?
+ // PyEval_RestoreThread(_tstate);
+  string aBanner("Python ");
+  aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
+  aBanner = aBanner + "\ntype help to get general information on environment\n";
+  //PyEval_SaveThread();
+  return aBanner;
+}
+
+/*!
+  \brief Initialize run command.
+  This method is used to prepare interpreter for running 
+  Python commands.
+  
+  \return \c true on success and \c false on error
+*/
+bool PyInterp_Interp::initRun()
+{
+  PySys_SetObject("stderr",_verr);
+  PySys_SetObject("stdout",_vout);
+
+  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
+  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
+
+  //PyObject *m = PyImport_GetModuleDict();
+  
+  PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
+  PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
+
+  return true;
+}
+
+/*!
+  \brief Compile Python command and evaluate it in the 
+         python dictionary context if possible.
+  \internal
+  \param command Python command string
+  \param context Python context (dictionary)
+  \return -1 on fatal error, 1 if command is incomplete and 0
+         if command is executed successfully
+ */
+static int compile_command(const char *command,PyObject *context)
+{
+  PyObject *m = PyImport_AddModule("codeop");
+  if(!m) { // Fatal error. No way to go on.
+    PyErr_Print();
+    return -1;
+  }
+  PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
+  if(!v) {
+    // Error encountered. It should be SyntaxError,
+    //so we don't write out traceback
+    PyObjWrapper exception, value, tb;
+    PyErr_Fetch(&exception, &value, &tb);
+    PyErr_NormalizeException(&exception, &value, &tb);
+    PyErr_Display(exception, value, NULL);
+    return -1;
+  }
+  else if (v == Py_None) {
+    // Incomplete text we return 1 : we need a complete text to execute
+    return 1;
+  }
+  else {
+    // Complete and correct text. We evaluate it.
+    //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+    //    PyObjWrapper r(PyEval_EvalCode(v,context,context));
+    //#else
+    PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
+    //#endif
+    if(!r) {
+      // Execution error. We return -1
+      PyErr_Print();
+      return -1;
+    }
+    // The command has been successfully executed. Return 0
+    return 0;
+  }
+}
+
+/*!
+  \brief Run Python command.
+  \param command Python command
+  \return command status
+*/
+int PyInterp_Interp::run(const char *command)
+{
+  beforeRun();
+  return simpleRun(command);
+}
+
+/*!
+  \brief Run Python command (used internally).
+  \param command Python command
+  \param addToHistory if \c true (default), the command is added to the commands history
+  \return command status
+*/
+int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
+{
+  if( addToHistory && strcmp(command,"") != 0 ) {
+    _history.push_back(command);
+    _ith = _history.end();
+  }
+
+  // We come from C++ to enter Python world
+  // We need to acquire the Python global lock
+  //PyLockWrapper aLock(_tstate); // san - lock is centralized now
+
+  // Reset redirected outputs before treatment
+  PySys_SetObject("stderr",_verr);
+  PySys_SetObject("stdout",_vout);
+
+  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
+  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
+
+  int ier = compile_command(command,_g);
+
+  // Outputs are redirected on standards outputs (console)
+  PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
+  PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
+
+  return ier;
+}
+
+/*!
+  \brief Get previous command in the commands history.
+  \return previous command
+*/
+const char * PyInterp_Interp::getPrevious()
+{
+  if(_ith != _history.begin()){
+    _ith--;
+    return (*_ith).c_str();
+  }
+  else
+    return BEGIN_HISTORY_PY;
+}
+
+/*!
+  \brief Get next command in the commands history.
+  \return next command
+*/
+const char * PyInterp_Interp::getNext()
+{
+  if(_ith != _history.end()){
+    _ith++;
+  }
+  if (_ith == _history.end())
+    return TOP_HISTORY_PY;
+  else
+    return (*_ith).c_str();
+}
+
+/*!
+  \brief Get standard error output.
+  \return standard error output
+*/
+string PyInterp_Interp::getverr(){ 
+  //PyLockWrapper aLock(_tstate);
+  PyObjWrapper v(PycStringIO->cgetvalue(_verr));
+  string aRet(PyString_AsString(v));
+  return aRet;
+}
+
+/*!
+  \brief Get standard output.
+  \return standard output
+*/
+string PyInterp_Interp::getvout(){  
+  //PyLockWrapper aLock(_tstate);
+  PyObjWrapper v(PycStringIO->cgetvalue(_vout));
+  string aRet(PyString_AsString(v));
+  return aRet;
+}
diff --git a/src/PyInterp/PyInterp_Interp.h b/src/PyInterp/PyInterp_Interp.h
new file mode 100644 (file)
index 0000000..e68d0d9
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library is distributed in the hope that it will be useful 
+// but WITHOUT ANY WARRANTY; without even the implied warranty of 
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : PyInterp_Interp.h
+//  Author : Christian CAREMOLI, Paul RASCLE, EDF
+//  Module : SALOME
+
+#ifndef PYINTERP_INTERP_H
+#define PYINTERP_INTERP_H
+
+#include "PyInterp.h"   // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+
+#include <list>
+#include <string>
+
+class PYINTERP_EXPORT PyLockWrapper
+{
+  PyThreadState* myThreadState;
+  PyThreadState* mySaveThreadState;
+  PyGILState_STATE _savestate;
+public:
+  PyLockWrapper(PyThreadState* theThreadState);
+  ~PyLockWrapper();
+};
+
+class PYINTERP_EXPORT PyInterp_Interp
+{
+public:
+  static int _argc;
+  static char* _argv[];
+  static PyObject *builtinmodule;
+  static PyThreadState *_gtstate;
+  static PyInterpreterState *_interp;
+  
+  PyInterp_Interp();
+  virtual ~PyInterp_Interp();
+  
+  void initialize();
+
+  virtual int run(const char *command); 
+
+  PyLockWrapper GetLockWrapper();
+
+  std::string getbanner(); 
+  std::string getverr();
+  std::string getvout();  
+
+  const char * getPrevious();
+  const char * getNext();    
+
+protected:
+  PyThreadState * _tstate;
+  PyObject * _vout;
+  PyObject * _verr;
+  PyObject * _g;
+  PyObject * _codeop;
+  std::list<std::string> _history;
+  std::list<std::string>::iterator _ith;
+
+  virtual int beforeRun() { return 0; }
+  int simpleRun(const char* command, const bool addToHistory = true);
+
+  virtual bool initRun();
+  virtual void initPython();
+  virtual bool initState() = 0;
+  virtual bool initContext() = 0;  
+};
+
+class PYINTERP_EXPORT PyObjWrapper
+{
+  PyObject* myObject;
+public:
+  PyObjWrapper(PyObject* theObject) : myObject(theObject) {}
+  PyObjWrapper() : myObject(0) {}
+  virtual ~PyObjWrapper() { Py_XDECREF(myObject); }
+
+  operator PyObject*()    { return myObject;  }
+  PyObject* operator->()  { return myObject;  }
+  PyObject* get()         { return myObject;  }
+  bool operator!()        { return !myObject; }
+  bool operator==(PyObject* theObject) { return myObject == theObject; }
+  PyObject** operator&()  { return &myObject; }
+  PyObjWrapper& operator=(PyObjWrapper* theObjWrapper)
+  {
+    Py_XDECREF(myObject);
+    myObject = theObjWrapper->myObject;
+    return *this;
+  }
+};
+
+#endif // PYINTERP_INTERP_H
index 551eca7d023738a7086cc7b9761ecd4f959f2bb5..1d50f5bf8392564f05e7d617cd3e183eb1326d2b 100755 (executable)
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-#ifndef _PYINTERP_WATCHER_H_
-#define _PYINTERP_WATCHER_H_
+//  File   : PyInterp_Watcher.h
+//  Author : Sergey Anikin, OCC
+//  Module : SALOME
 
-#include <PyInterp.h>
+#ifndef PYINTERP_WATCHER_H
+#define PYINTERP_WATCHER_H
 
-#include <PyInterp_Dispatcher.h>
+#include "PyInterp.h"   // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
 
-#include <qobject.h>
+#include "PyInterp_Dispatcher.h"
+
+#include <QObject>
 
 // Private class that keeps track of destructions of request listeners
 class PYINTERP_EXPORT PyInterp_Watcher : public QObject
@@ -38,4 +42,4 @@ public slots:
   void onDestroyed( QObject* o ) { PyInterp_Dispatcher::Get()->objectDestroyed( o ); }
 };
 
-#endif // _PYINTERP_WATCHER_H_
+#endif // PYINTERP_WATCHER_H
diff --git a/src/PyInterp/PyInterp_base.cxx b/src/PyInterp/PyInterp_base.cxx
deleted file mode 100644 (file)
index 7225855..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-// 
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either 
-// version 2.1 of the License.
-// 
-// This library is distributed in the hope that it will be useful 
-// but WITHOUT ANY WARRANTY; without even the implied warranty of 
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public  
-// License along with this library; if not, write to the Free Software 
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
-//
-//  File   : PyInterp_base.cxx
-//  Author : Christian CAREMOLI, Paul RASCLE, EDF
-//  Module : SALOME
-//  $Header$
-
-
-#include <string>
-#include <vector>
-
-#include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)!
-#include <cStringIO.h>
-
-using namespace std;
-
-PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): 
-  myThreadState(theThreadState),
-  mySaveThreadState(0)
-{
-#if defined(USE_GILSTATE)
-  if (myThreadState->interp == PyInterp_base::_interp) {
-    _savestate = PyGILState_Ensure();
-  } else {
-    PyEval_AcquireThread(myThreadState);
-  }
-#else 
-  PyEval_AcquireThread(myThreadState);
-#endif
-}
-
-PyLockWrapper::~PyLockWrapper()
-{
-#if defined(USE_GILSTATE)
-  if (myThreadState->interp == PyInterp_base::_interp) {
-    PyGILState_Release(_savestate);
-  } else {
-    PyEval_ReleaseThread(myThreadState);
-  }
-#else 
-  PyEval_ReleaseThread(myThreadState);
-#endif
-}
-
-class PyReleaseLock{
-public:
-  ~PyReleaseLock(){
-    PyEval_ReleaseLock();
-  }
-};
-
-
-PyLockWrapper PyInterp_base::GetLockWrapper(){
-  return _tstate;
-}
-
-
-// main python interpreter (static attributes)
-
-int PyInterp_base::_argc = 1;
-char* PyInterp_base::_argv[] = {""};
-
-PyObject *PyInterp_base::builtinmodule = NULL;
-
-PyThreadState *PyInterp_base::_gtstate = NULL;
-PyInterpreterState *PyInterp_base::_interp = NULL;
-
-
-/*!
- * basic constructor here : herited classes constructors must call initalize() method
- * defined here.
- */
-PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
-{
-}
-
-PyInterp_base::~PyInterp_base()
-{
-}
-
-
-/*!
- * Must be called by herited classes constructors. initialize() calls virtuals methods
- * initstate & initcontext, not defined here in base class. initstate & initcontext methods
- * must be implemented in herited classes, following the Python interpreter policy
- * (mono or multi interpreter...).
- */
-void PyInterp_base::initialize()
-{
-  _history.clear();       // start a new list of user's commands 
-  _ith = _history.begin();
-
-  init_python();
-  // Here the global lock is released
-
-  initState();
-
-  PyLockWrapper aLock= GetLockWrapper();
-
-  initContext();
-
-  // used to interpret & compile commands
-  PyObjWrapper m(PyImport_ImportModule("codeop"));
-  if(!m){
-    PyErr_Print();
-    return;
-  }
-
-  // Create cStringIO to capture stdout and stderr
-  PycString_IMPORT;
-  if (PycStringIO) { // CTH11627 : additional check
-    _vout = PycStringIO->NewOutput(128);
-    _verr = PycStringIO->NewOutput(128);
-  }
-
-  // All the initRun outputs are redirected to the standard output (console)
-  initRun();
-}
-
-void PyInterp_base::init_python()
-{
-  _atFirst = false;
-  if (Py_IsInitialized())
-    return;
-
-  // Python is not initialized
-  Py_SetProgramName(_argv[0]);
-  Py_Initialize(); // Initialize the interpreter
-  PySys_SetArgv(_argc, _argv);
-  PyEval_InitThreads(); // Create (and acquire) the interpreter lock
-  _interp = PyThreadState_Get()->interp;
-  _gtstate = PyEval_SaveThread(); // Release global thread state
-}
-
-string PyInterp_base::getbanner()
-{
- // Should we take the lock ?
- // PyEval_RestoreThread(_tstate);
-  string aBanner("Python ");
-  aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
-  aBanner = aBanner + "\ntype help to get general information on environment\n";
-  //PyEval_SaveThread();
-  return aBanner;
-}
-
-
-int PyInterp_base::initRun()
-{
-  PySys_SetObject("stderr",_verr);
-  PySys_SetObject("stdout",_vout);
-
-  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
-  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
-
-  //PyObject *m = PyImport_GetModuleDict();
-  
-  PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
-  PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
-
-  return 0;
-}
-
-
-/*!
- * This function compiles a string (command) and then evaluates it in the dictionnary
- * context if possible.
- * Returns :
- * -1 : fatal error 
- *  1 : incomplete text
- *  0 : complete text executed with success
- */
-int compile_command(const char *command,PyObject *context)
-{
-  PyObject *m = PyImport_AddModule("codeop");
-  if(!m){ // Fatal error. No way to go on.
-    PyErr_Print();
-    return -1;
-  }
-  PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
-  if(!v){
-    // Error encountered. It should be SyntaxError,
-    //so we don't write out traceback
-    PyObjWrapper exception, value, tb;
-    PyErr_Fetch(&exception, &value, &tb);
-    PyErr_NormalizeException(&exception, &value, &tb);
-    PyErr_Display(exception, value, NULL);
-    return -1;
-  }else if (v == Py_None){
-    // Incomplete text we return 1 : we need a complete text to execute
-    return 1;
-  }else{
-    // Complete and correct text. We evaluate it.
-    //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
-    //    PyObjWrapper r(PyEval_EvalCode(v,context,context));
-    //#else
-    PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
-    //#endif
-    if(!r){
-      // Execution error. We return -1
-      PyErr_Print();
-      return -1;
-    }
-    // The command has been successfully executed. Return 0
-    return 0;
-  }
-}
-
-
-int PyInterp_base::run(const char *command)
-{
-  if(_atFirst){
-    int ret = 0;
-    ret = simpleRun("from Help import *");
-    if (ret) { 
-      _atFirst = false;
-      return ret;
-    }
-    ret = simpleRun("import salome");
-    if (ret) { 
-      _atFirst = false;
-      return ret;
-    }
-    ret = simpleRun("salome.salome_init(0,1)");
-    if (ret) { 
-      _atFirst = false;
-      return ret;
-    }
-    _atFirst = false;
-  }
-  return simpleRun(command);
-}
-
-
-int PyInterp_base::simpleRun(const char *command)
-{
-  if( !_atFirst && strcmp(command,"") != 0 ) {
-    _history.push_back(command);
-    _ith = _history.end();
-  }
-
-  // We come from C++ to enter Python world
-  // We need to acquire the Python global lock
-  //PyLockWrapper aLock(_tstate); // san - lock is centralized now
-
-  // Reset redirected outputs before treatment
-  PySys_SetObject("stderr",_verr);
-  PySys_SetObject("stdout",_vout);
-
-  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
-  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
-
-  int ier = compile_command(command,_g);
-
-  // Outputs are redirected on standards outputs (console)
-  PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
-  PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
-
-  return ier;
-}
-
-
-const char * PyInterp_base::getPrevious()
-{
-  if(_ith != _history.begin()){
-    _ith--;
-    return (*_ith).c_str();
-  }
-  else
-    return BEGIN_HISTORY_PY;
-}
-
-
-const char * PyInterp_base::getNext()
-{
-  if(_ith != _history.end()){
-    _ith++;
-  }
-  if (_ith == _history.end())
-    return TOP_HISTORY_PY;
-  else
-    return (*_ith).c_str();
-}
-
-
-string PyInterp_base::getverr(){ 
-  //PyLockWrapper aLock(_tstate);
-  PyObjWrapper v(PycStringIO->cgetvalue(_verr));
-  string aRet(PyString_AsString(v));
-  return aRet;
-}
-
-
-string PyInterp_base::getvout(){  
-  //PyLockWrapper aLock(_tstate);
-  PyObjWrapper v(PycStringIO->cgetvalue(_vout));
-  string aRet(PyString_AsString(v));
-  return aRet;
-}
diff --git a/src/PyInterp/PyInterp_base.h b/src/PyInterp/PyInterp_base.h
deleted file mode 100644 (file)
index 7193165..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-// 
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either 
-// version 2.1 of the License.
-// 
-// This library is distributed in the hope that it will be useful 
-// but WITHOUT ANY WARRANTY; without even the implied warranty of 
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public  
-// License along with this library; if not, write to the Free Software 
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-//  SALOME SALOMEGUI : implementation of desktop and GUI kernel
-//
-//  File   : PyInterp_base.h
-//  Author : Christian CAREMOLI, Paul RASCLE, EDF
-//  Module : SALOME
-
-#ifndef _PYINTERP_BASE_H_
-#define _PYINTERP_BASE_H_
-
-#include "PyInterp.h"
-
-#include <list>
-#include <string>
-#include <iostream>
-
-// include order important!
-// pthread then python then qt
-//#include <pthread.h>  // must be before Python.h !
-
-#include <Python.h>   // must be before qt includes ...
-#include <compile.h>   // Python include needed for versions before 2.4. Included in Python.h now.
-#include <eval.h>   // Python include needed for versions before 2.4. Included in Python.h now.
-
-//#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
-//extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
-//#endif
-
-/* For 2.3, use the PyGILState_ calls */
-#if (PY_VERSION_HEX >= 0x02030000)
-#define USE_GILSTATE
-#endif
-
-#define TOP_HISTORY_PY "--- top of history ---"
-#define BEGIN_HISTORY_PY "--- begin of history ---"
-
-class PYINTERP_EXPORT PyLockWrapper
-{
-  PyThreadState* myThreadState;
-  PyThreadState* mySaveThreadState;
-#if defined(USE_GILSTATE)
-  PyGILState_STATE _savestate ;
-#endif
- public:
-  PyLockWrapper(PyThreadState* theThreadState);
-  ~PyLockWrapper();
-};
-
-class PYINTERP_EXPORT PyInterp_base{
- public:
-  static int _argc;
-  static char* _argv[];
-  static PyObject *builtinmodule;
-  static PyThreadState *_gtstate;
-  static PyInterpreterState *_interp;
-  
-  PyInterp_base();
-  ~PyInterp_base();
-  
-  virtual void initialize();
-  virtual void init_python();
-  // init_python() made virtual to:
-  // 1. Remove dependency on KERNEL in light SALOME configuration
-  // 2. Allow redefinition of this method in SalomeApp_PyInterp class (it should be empty there and rely on KERNEL_PYTHON)
-
-  virtual int run(const char *command); 
-
-  PyLockWrapper GetLockWrapper();
-
-  std::string getbanner(); 
-  std::string getverr();
-  std::string getvout();  
-
-  const char * getPrevious();
-  const char * getNext();    
-
- protected:
-  PyThreadState * _tstate;
-  PyObject * _vout;
-  PyObject * _verr;
-  PyObject * _g;
-  PyObject * _codeop;
-  std::list<std::string> _history;
-  std::list<std::string>::iterator _ith;
-  bool _atFirst;
-
-  int simpleRun(const char* command);
-  int initRun();
-
-  virtual bool initState() = 0;
-  virtual bool initContext() = 0;  
-};
-
-
-class PYINTERP_EXPORT PyObjWrapper{
-  PyObject* myObject;
-public:
-  PyObjWrapper(PyObject* theObject): myObject(theObject) {}
-  PyObjWrapper(): myObject(0) {}
-  operator PyObject*(){
-    return myObject;
-  }
-  PyObject* operator->(){
-    return myObject;
-  }
-  PyObject* get(){
-    return myObject;
-  }
-  bool operator!(){
-    return !myObject;
-  }
-  bool operator==(PyObject* theObject){
-    return myObject == theObject;
-  }
-  PyObject** operator&(){
-    return &myObject;
-  }
-  PyObjWrapper& operator=(PyObjWrapper* theObjWrapper){
-    Py_XDECREF(myObject);
-    myObject = theObjWrapper->myObject;
-    return *this;
-  }
-  virtual ~PyObjWrapper(){ 
-    Py_XDECREF(myObject);
-  }
-};
-
-#endif