![]() |
|
|
Generated: 8 Jan 2009 |
00001 // $Id: PythonScriptingSvc.cpp,v 1.18 2008/10/27 21:12:08 marcocle Exp $ 00002 00003 // Include Files 00004 #include "GaudiKernel/MsgStream.h" 00005 #include "GaudiKernel/ISvcLocator.h" 00006 #include "GaudiKernel/SvcFactory.h" 00007 #include "GaudiKernel/SmartIF.h" 00008 00009 #include "PythonScriptingSvc.h" 00010 #ifdef _POSIX_C_SOURCE 00011 #undef _POSIX_C_SOURCE 00012 #endif 00013 #include "Python.h" 00014 #include <fstream> 00015 #include <sstream> 00016 00017 // Special for Unixes 00018 #if defined(linux) 00019 #include "dlfcn.h" 00020 #endif 00021 00022 // Instantiation of a static factory class used by clients to create 00023 // instances of this service 00024 DECLARE_SERVICE_FACTORY(PythonScriptingSvc) 00025 00026 //---------------------------------------------------------------------------------- 00027 PythonScriptingSvc::PythonScriptingSvc( const std::string& name, ISvcLocator* svc ) 00028 //---------------------------------------------------------------------------------- 00029 : Service(name, svc) { 00030 // Declare the startup script Property 00031 declareProperty( "StartupScript", m_startupScript = "" ); 00032 } 00033 00034 //---------------------------------------------------------------------------------- 00035 PythonScriptingSvc::~PythonScriptingSvc() { } 00036 //---------------------------------------------------------------------------------- 00037 00038 //---------------------------------------------------------------------------------- 00039 StatusCode PythonScriptingSvc::initialize() 00040 //---------------------------------------------------------------------------------- 00041 { 00042 // initialize the Service Base class 00043 StatusCode sc = Service::initialize(); 00044 if ( sc.isFailure() ) return sc; 00045 00046 MsgStream log( msgSvc(), name() ); 00047 00048 // Setup startup script. If none is explicitiy specified, then 00049 // use the ApplicationMgr JobOptionsPath property as long as 00050 // the JobOptionsType property is set to "NONE". 00051 if( m_startupScript == "" ) { 00052 SmartIF<IProperty> prpMgr(IID_IProperty, serviceLocator()); 00053 if ( prpMgr.isValid() ) { 00054 StringProperty tmp; 00055 tmp.assign(prpMgr->getProperty("JobOptionsType")); 00056 if ( tmp.value( ) == "NONE" ) { 00057 tmp.assign(prpMgr->getProperty("JobOptionsPath")); 00058 m_startupScript = tmp; 00059 } 00060 } 00061 } 00062 00063 char* progName[] = { const_cast<char*>("GaudiPython") }; 00064 00065 // Initialize the Python interpreter. Required. 00066 Py_Initialize(); 00067 // Set argv for Tkinter (needs program name) 00068 PySys_SetArgv( 1, progName ); 00069 // Get the Python version 00070 std::string fullversion = Py_GetVersion(); 00071 std::string version( fullversion, 0, fullversion.find_first_of(' ')); 00072 std::string vers(version, 0, version.find_first_of('.',version.find_first_of('.')+1)); 00073 log << MSG::INFO << "Python version: [" << vers << "]" << endmsg; 00074 00075 #if defined(linux) 00076 // This is hack to make global the python symbols 00077 // which are needed by the other python modules 00078 // (eg. readline, math, etc,) libraries. 00079 std::string libname = "libpython" + vers + ".so"; 00080 dlopen(libname.c_str(), RTLD_GLOBAL | RTLD_LAZY); 00081 #endif 00082 00083 00084 // Startup commands 00085 PyRun_SimpleString( "from gaudimodule import *" ); 00086 PyRun_SimpleString( "g = AppMgr()" ); 00087 // backward compatibility with SIPython 00088 PyRun_SimpleString( "theApp = g" ); 00089 PyRun_SimpleString( "def Service(n): return g.service(n)" ); 00090 PyRun_SimpleString( "def Algorithm(n): return g.algorithm(n)" ); 00091 PyRun_SimpleString( "def Property(n): return g.service(n)" ); 00092 // For command-line completion (unix only) 00093 #if !defined( _WIN32 ) 00094 PyRun_SimpleString( "import rlcompleter"); 00095 PyRun_SimpleString( "rlcompleter.readline.parse_and_bind('tab: complete')"); 00096 #endif 00097 return StatusCode::SUCCESS; 00098 } 00099 00100 //---------------------------------------------------------------------------------- 00101 StatusCode PythonScriptingSvc::finalize() 00102 //---------------------------------------------------------------------------------- 00103 { 00104 // Finalize this specific service 00105 StatusCode sc = Service::finalize(); 00106 if ( sc.isFailure() ) { 00107 return sc; 00108 } 00109 00110 // Shutdown the Python interpreter 00111 Py_Finalize(); 00112 return StatusCode::SUCCESS; 00113 } 00114 00115 //---------------------------------------------------------------------------------- 00116 StatusCode PythonScriptingSvc::queryInterface( const InterfaceID& riid, void** ppvInterface ) 00117 //---------------------------------------------------------------------------------- 00118 { 00119 if ( IID_IRunable == riid ) { 00120 *ppvInterface = (IRunable*)this; 00121 addRef(); 00122 return StatusCode::SUCCESS; 00123 } 00124 else return Service::queryInterface(riid, ppvInterface); 00125 } 00126 00127 //---------------------------------------------------------------------------------- 00128 StatusCode PythonScriptingSvc::run() 00129 //---------------------------------------------------------------------------------- 00130 { 00131 MsgStream log( msgSvc(), name() ); 00132 if ( m_startupScript != "" ) { 00133 std::ifstream file(m_startupScript.c_str()); 00134 std::stringstream stream; 00135 if( file ) { 00136 char ch; 00137 while( file.get(ch) ) stream.put(ch); 00138 PyRun_SimpleString( const_cast<char*>(stream.str().c_str()) ); 00139 file.close(); 00140 } 00141 else { 00142 log << MSG::WARNING << "Python startup file " << m_startupScript << " not found" << endmsg; 00143 } 00144 } 00145 PyRun_InteractiveLoop(stdin, "\0"); 00146 return StatusCode::SUCCESS; 00147 } 00148