// -*- C++ -*- // // This file is part of the Coriolis Software. // Copyright (c) UPMC 2008-2015, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | // | V L S I B a c k e n d D a t a - B a s e | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./hurricane/viewer/Script.cpp" | // +-----------------------------------------------------------------+ #if !defined(__PYTHON_MODULE__) #include #include #include "hurricane/Error.h" #include "hurricane/Cell.h" #include "hurricane/isobar/PyCell.h" #include "hurricane/viewer/PyCellViewer.h" #include "hurricane/viewer/Script.h" namespace Isobar { using std::string; using Hurricane::Cell; using Hurricane::CellViewer; // ------------------------------------------------------------------- // Class : "Isobar::Script". vector Script::_pathes; void Script::addPath ( const string& path ) { _pathes.push_back ( path ); } void Script::removePath ( const string& path ) { vector::iterator ipath = _pathes.begin(); for ( ; ipath != _pathes.end() ; ++ipath ) { if ( (*ipath) == path ) { _pathes.erase ( ipath ); return; } } } Script::Script ( const string& name ) : _initModuleNames() , _initModules () , _moduleName (name) , _sysModule (NULL) , _hurricaneModule(NULL) , _userModule (NULL) , _pyFunction (NULL) , _pyArgs (NULL) , _pyKw (NULL) , _pyResult (NULL) , _globalState (NULL) , _subInterpreter (NULL) , _flags (0) { } Script::~Script () { finalize(); } Script* Script::create ( const std::string& name ) { Script* script = new Script ( name ); return script; } void Script::destroy () { delete this; } void Script::setUserModuleName ( const std::string& name ) { finalize(); _moduleName = name; } bool Script::addInitModuleName ( std::string name ) { for ( auto moduleName : _initModuleNames ) { if (name == moduleName) return false; } _initModuleNames.push_back( name ); return true; } PyObject* Script::getFunction ( std::string function ) { if (not _userModule) return NULL; PyObject* pyFunction = PyObject_GetAttrString( _userModule, const_cast(function.c_str()) ); if ( (pyFunction == NULL) or not PyCallable_Check(pyFunction) ) return NULL; return pyFunction; } bool Script::runFunction ( const std::string& function, Cell* cell, unsigned int flags ) { bool returnCode = true; initialize(); _pyFunction = PyObject_GetAttrString( _userModule, const_cast(function.c_str()) ); if ( (_pyFunction == NULL) or not PyCallable_Check(_pyFunction) ) { finalize(); throw Error( "Python module %s doesn't contains any %s function." , _moduleName.c_str(),function.c_str()); } _pyArgs = PyTuple_New( 0 ); _pyResult = PyObject_Call( _pyFunction, _pyArgs, _pyKw ); _pyArgs = NULL; _pyKw = NULL; if (_pyResult == NULL) { cerr << "Something has gone slightly wrong" << endl; } if (PyErr_Occurred()) { PyErr_Print(); returnCode = false; } finalize(); return returnCode; } PyObject* Script::callFunction ( const std::string& function, PyObject* pyArgs ) { if (_userModule == NULL) { if (PyErr_Occurred()) PyErr_Print(); return NULL; } _pyFunction = PyObject_GetAttrString( _userModule, const_cast(function.c_str()) ); if ( (_pyFunction == NULL) or not PyCallable_Check(_pyFunction) ) { cerr << Error( "Python module %s doesn't contains any %s function." , _moduleName.c_str(),function.c_str()) << endl; return NULL; } _pyResult = PyObject_Call( _pyFunction, pyArgs, NULL ); if (_pyResult == NULL) { cerr << "Something has gone slightly wrong" << endl; return NULL; } if (PyErr_Occurred()) PyErr_Print(); return _pyResult; } PyObject* Script::_importSys ( unsigned int flags ) { _sysModule = _importModule( "sys", flags ); PyObject* path = PyObject_GetAttrString( _sysModule, "path" ); if (path == NULL) { if (flags & NoThrow) return NULL; throw Error("Script::_importSys(): No \"sys.path\" attribute."); } vector::iterator ipath = _pathes.begin(); for ( ; ipath != _pathes.end() ; ++ipath ) { PyObject* element = PyString_FromString( const_cast((*ipath).c_str()) ); PyList_Insert( path, 0, element ); } return _sysModule; } PyObject* Script::_importModule ( const string& moduleName, unsigned int flags ) { if (not Py_IsInitialized()) { if (flags & NoThrow) return NULL; throw Error( "Script::_importModule(): Called before Py_Initialize() while importing <%s>." , moduleName.c_str() ); } PyObject* module = PyImport_ImportModule( const_cast(moduleName.c_str()) ); if (module == NULL) { if (PyErr_Occurred()) { PyErr_Print(); } if (flags & NoThrow) return NULL; throw Error( "Script::_importModule(): Unable to load module <%s>.",moduleName.c_str() ); } return module; } bool Script::initialize ( unsigned int flags ) { if (Py_IsInitialized()) { // Python is already running. Launch a sub-interpreter. _globalState = PyThreadState_Get(); _subInterpreter = Py_NewInterpreter(); } else Py_Initialize(); if (not Py_IsInitialized()) { if (flags & NoThrow) return false; throw Error( "Script::initialize(): Unable to initialize the Python interpreter (<%s>)." , _moduleName.c_str()); } _flags |= Initialized; _importSys ( flags ); for ( auto moduleName : _initModuleNames ) _initModules.push_back( _importModule(moduleName,flags) ); _importHurricane( flags ); _importUser ( flags ); return true; } void Script::finalize () { if (not Py_IsInitialized()) return; if (not (_flags & Initialized)) return; _flags &= ~Initialized; if (_subInterpreter != NULL) { Py_EndInterpreter(_subInterpreter); PyThreadState_Swap(_globalState); _subInterpreter = NULL; } else { if ( _userModule != NULL ) { Py_DECREF ( _userModule ); } if ( _hurricaneModule != NULL ) { Py_DECREF ( _hurricaneModule ); } if ( _sysModule != NULL ) { Py_DECREF ( _sysModule ); } if ( _pyResult != NULL ) { Py_DECREF ( _pyResult ); } if ( _pyArgs != NULL ) { Py_DECREF ( _pyArgs ); } if ( _pyFunction != NULL ) { Py_DECREF ( _pyFunction ); } for ( size_t i=0 ; i<_initModules.size() ; ++i ) { if (_initModules[i]) { Py_DECREF( _initModules[i] ); _initModules[i] = NULL; } } _initModules.clear(); Py_Finalize (); _userModule = NULL; _sysModule = NULL; _hurricaneModule = NULL; _pyFunction = NULL; _pyArgs = NULL; _pyResult = NULL; } } void Script::addKwArgument ( const char* key, PyObject* object ) { if (_pyKw == NULL) _pyKw = PyDict_New(); PyObject* pyKey = PyString_FromString( key ); if (PyDict_Contains(_pyKw,pyKey) == 1) { cerr << Error( "Script::addKwArgument(): Attempt to add twice key %s (nothing done)." , key ) << endl; return; } PyDict_SetItem( _pyKw, pyKey, object ); } } // End of Isobar namespace. #endif