00001 // Author: Wim Lavrijsen, February 2006 00002 00003 // Bindings 00004 #include "PyROOT.h" 00005 #include "TPyROOTApplication.h" 00006 #include "Utility.h" 00007 00008 // ROOT 00009 #include "TROOT.h" 00010 #include "TInterpreter.h" 00011 #include "TSystem.h" 00012 #include "TBenchmark.h" 00013 #include "TStyle.h" 00014 #include "TError.h" 00015 #include "Getline.h" 00016 #include "TVirtualX.h" 00017 00018 // CINT 00019 #include "Api.h" 00020 00021 // Standard 00022 #include <string.h> 00023 00024 00025 //______________________________________________________________________________ 00026 // Setup interactive application for python 00027 // ======================================== 00028 // 00029 // The TPyROOTApplication sets up the nuts and bolts for interactive ROOT use 00030 // from python, closely following TRint. Note that not everything is done here, 00031 // some bits (such as e.g. the use of exception hook for shell escapes) are more 00032 // easily done in python and you'll thus find them ROOT.py 00033 // 00034 // The intended use of this class is from python only. It is used by default in 00035 // ROOT.py, so if you do not want to have a TApplication derived object created 00036 // for you, you'll need to load libPyROOT.so instead. 00037 // 00038 // The static InitXYZ functions are used in conjunction with TPyROOTApplication 00039 // in ROOT.py, but they can be used independently. 00040 // 00041 // NOTE: This class will receive the command line arguments from sys.argv. A 00042 // distinction between arguments for TApplication and user arguments can be 00043 // made by using "-" or "--" as a separator on the command line. 00044 00045 00046 //- data --------------------------------------------------------------------- 00047 ClassImp(PyROOT::TPyROOTApplication) 00048 00049 00050 //- constructors/destructor -------------------------------------------------- 00051 PyROOT::TPyROOTApplication::TPyROOTApplication( 00052 const char* acn, int* argc, char** argv, bool bLoadLibs ) : 00053 TApplication( acn, argc, argv ) 00054 { 00055 // Create a TApplication derived for use with interactive ROOT from python. A 00056 // set of standard, often used libs is loaded if bLoadLibs is true (default). 00057 00058 if ( bLoadLibs ) // note that this section could be programmed in python 00059 { 00060 // follow TRint to minimize differences with CINT 00061 ProcessLine( "#include <iostream>", kTRUE ); 00062 ProcessLine( "#include <_string>", kTRUE ); // for std::string iostream. 00063 ProcessLine( "#include <vector>", kTRUE ); // needed because they're used within the 00064 ProcessLine( "#include <pair>", kTRUE ); // core ROOT dicts and CINT won't be able 00065 // to properly unload these files 00066 00067 // following RINT, these are now commented out (rely on auto-loading) 00068 // // the following libs are also useful to have, make sure they are loaded... 00069 // gROOT->LoadClass("TMinuit", "Minuit"); 00070 // gROOT->LoadClass("TPostScript", "Postscript"); 00071 // gROOT->LoadClass("THtml", "Html"); 00072 } 00073 00074 #ifdef WIN32 00075 // switch win32 proxy main thread id 00076 if (gVirtualX) 00077 ProcessLine("((TGWin32 *)gVirtualX)->SetUserThreadId(0);", kTRUE); 00078 #endif 00079 00080 // save current interpreter context 00081 gInterpreter->SaveContext(); 00082 gInterpreter->SaveGlobalsContext(); 00083 00084 // prevent crashes on accessing histor 00085 Gl_histinit( (char*)"-" ); 00086 00087 // prevent ROOT from exiting python 00088 SetReturnFromRun( kTRUE ); 00089 } 00090 00091 00092 //- static public members ---------------------------------------------------- 00093 Bool_t PyROOT::TPyROOTApplication::CreatePyROOTApplication( Bool_t bLoadLibs ) 00094 { 00095 // Create a TPyROOTApplication. Returns false if gApplication is not null. 00096 00097 if ( ! gApplication ) { 00098 // retrieve arg list from python, translate to raw C, pass on 00099 PyObject* argl = PySys_GetObject( const_cast< char* >( "argv" ) ); 00100 00101 int argc = argl ? PyList_Size( argl ) : 1; 00102 char** argv = new char*[ argc ]; 00103 for ( int i = 1; i < argc; ++i ) { 00104 char* argi = PyROOT_PyUnicode_AsString( PyList_GET_ITEM( argl, i ) ); 00105 if ( strcmp( argi, "-" ) == 0 || strcmp( argi, "--" ) == 0 ) { 00106 // stop collecting options, the remaining are for the python script 00107 argc = i; // includes program name 00108 break; 00109 } 00110 argv[ i ] = argi; 00111 } 00112 #if PY_VERSION_HEX < 0x03000000 00113 argv[ 0 ] = Py_GetProgramName(); 00114 #else 00115 // TODO: convert the wchar_t* 00116 argv[ 0 ] = (char*)"python"; 00117 #endif 00118 00119 gApplication = new TPyROOTApplication( "PyROOT", &argc, argv, bLoadLibs ); 00120 delete[] argv; // TApplication ctor has copied argv, so done with it 00121 00122 return kTRUE; 00123 } 00124 00125 return kFALSE; 00126 } 00127 00128 //____________________________________________________________________________ 00129 Bool_t PyROOT::TPyROOTApplication::InitROOTGlobals() 00130 { 00131 // Setup the basic ROOT globals gBenchmark, gStyle, gProgname, if not already 00132 // set. Always returns true. 00133 00134 if ( ! gBenchmark ) gBenchmark = new TBenchmark(); 00135 if ( ! gStyle ) gStyle = new TStyle(); 00136 00137 if ( ! gProgName ) // should have been set by TApplication 00138 #if PY_VERSION_HEX < 0x03000000 00139 gSystem->SetProgname( Py_GetProgramName() ); 00140 #else 00141 // TODO: convert the wchar_t* 00142 gSystem->SetProgname( "python" ); 00143 #endif 00144 00145 return kTRUE; 00146 } 00147 00148 //____________________________________________________________________________ 00149 Bool_t PyROOT::TPyROOTApplication::InitCINTMessageCallback() 00150 { 00151 // Install CINT message callback which will turn CINT error message into 00152 // python exceptions. Always returns true. 00153 00154 G__set_errmsgcallback( (void*)&Utility::ErrMsgCallback ); 00155 return kTRUE; 00156 } 00157 00158 //____________________________________________________________________________ 00159 Bool_t PyROOT::TPyROOTApplication::InitROOTMessageCallback() 00160 { 00161 // Install ROOT message handler which will turn ROOT error message into 00162 // python exceptions. Always returns true. 00163 00164 SetErrorHandler( (ErrorHandlerFunc_t)&Utility::ErrMsgHandler ); 00165 return kTRUE; 00166 }