Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TPyROOTApplication.cxx
Go to the documentation of this file.
1 // Author: Wim Lavrijsen, February 2006
2 
3 // Bindings
4 #include "PyROOT.h"
5 #include "TPyROOTApplication.h"
6 #include "Utility.h"
7 
8 // ROOT
9 #include "TROOT.h"
10 #include "TInterpreter.h"
11 #include "TSystem.h"
12 #include "TBenchmark.h"
13 #include "TStyle.h"
14 #include "TError.h"
15 #include "Getline.h"
16 #ifdef R__WIN32
17 #include "TVirtualX.h"
18 #endif
19 
20 // Standard
21 #include <string.h>
22 
23 
24 //______________________________________________________________________________
25 // Setup interactive application for python
26 // ========================================
27 //
28 // The TPyROOTApplication sets up the nuts and bolts for interactive ROOT use
29 // from python, closely following TRint. Note that not everything is done here,
30 // some bits (such as e.g. the use of exception hook for shell escapes) are more
31 // easily done in python and you'll thus find them ROOT.py
32 //
33 // The intended use of this class is from python only. It is used by default in
34 // ROOT.py, so if you do not want to have a TApplication derived object created
35 // for you, you'll need to load libPyROOT.so instead.
36 //
37 // The static InitXYZ functions are used in conjunction with TPyROOTApplication
38 // in ROOT.py, but they can be used independently.
39 //
40 // NOTE: This class will receive the command line arguments from sys.argv. A
41 // distinction between arguments for TApplication and user arguments can be
42 // made by using "-" or "--" as a separator on the command line.
43 
44 
45 //- data ---------------------------------------------------------------------
46 ClassImp(PyROOT::TPyROOTApplication);
47 
48 
49 //- constructors/destructor --------------------------------------------------
50 PyROOT::TPyROOTApplication::TPyROOTApplication(
51  const char* acn, int* argc, char** argv, Bool_t /*bLoadLibs*/ ) :
52  TApplication( acn, argc, argv )
53 {
54 // The following code is redundant with ROOT6 and the PCH: the headers are
55 // available to the interpreter.
56 // // Create a TApplication derived for use with interactive ROOT from python. A
57 // // set of standard, often used libs is loaded if bLoadLibs is true (default).
58 //
59 // if ( bLoadLibs ) // note that this section could be programmed in python
60 // {
61 // // follow TRint to minimize differences with root.exe (note: changed <pair>
62 // // to <utility> for Cling, which is correct)
63 // ProcessLine( "#include <iostream>", kTRUE );
64 // ProcessLine( "#include <string>", kTRUE ); // for std::string iostream.
65 // ProcessLine( "#include <vector>", kTRUE ); // needed because they're used within the
66 // ProcessLine( "#include <utility>", kTRUE ); // core ROOT dicts and CINT won't be able
67 // // to properly unload these files
68 // }
69 
70 #ifdef WIN32
71  // switch win32 proxy main thread id
72  if (gVirtualX)
73  ProcessLine("((TGWin32 *)gVirtualX)->SetUserThreadId(0);", kTRUE);
74 #endif
75 
76 // save current interpreter context
77  gInterpreter->SaveContext();
78  gInterpreter->SaveGlobalsContext();
79 
80 // prevent crashes on accessing history
81  Gl_histinit( (char*)"-" );
82 
83 // prevent ROOT from exiting python
84  SetReturnFromRun( kTRUE );
85 }
86 
87 
88 //- static public members ----------------------------------------------------
89 Bool_t PyROOT::TPyROOTApplication::CreatePyROOTApplication( Bool_t bLoadLibs )
90 {
91 // Create a TPyROOTApplication. Returns false if gApplication is not null.
92 
93  if ( ! gApplication ) {
94  // retrieve arg list from python, translate to raw C, pass on
95  PyObject* argl = PySys_GetObject( const_cast< char* >( "argv" ) );
96 
97  int argc = 1;
98  if ( argl && 0 < PyList_Size( argl ) ) argc = (int)PyList_GET_SIZE( argl );
99  char** argv = new char*[ argc ];
100  for ( int i = 1; i < argc; ++i ) {
101  char* argi = const_cast< char* >( PyROOT_PyUnicode_AsString( PyList_GET_ITEM( argl, i ) ) );
102  if ( strcmp( argi, "-" ) == 0 || strcmp( argi, "--" ) == 0 ) {
103  // stop collecting options, the remaining are for the python script
104  argc = i; // includes program name
105  break;
106  }
107  argv[ i ] = argi;
108  }
109 #if PY_VERSION_HEX < 0x03000000
110  if ( Py_GetProgramName() && strlen( Py_GetProgramName() ) != 0 )
111  argv[ 0 ] = Py_GetProgramName();
112  else
113  argv[ 0 ] = (char*)"python";
114 #else
115 // TODO: convert the wchar_t*
116  argv[ 0 ] = (char*)"python";
117 #endif
118 
119  gApplication = new TPyROOTApplication( "PyROOT", &argc, argv, bLoadLibs );
120  delete[] argv; // TApplication ctor has copied argv, so done with it
121 
122  return kTRUE;
123  }
124 
125  return kFALSE;
126 }
127 
128 ////////////////////////////////////////////////////////////////////////////////
129 /// Setup the basic ROOT globals gBenchmark, gStyle, gProgname, if not already
130 /// set. Always returns true.
131 
132 Bool_t PyROOT::TPyROOTApplication::InitROOTGlobals()
133 {
134  if ( ! gBenchmark ) gBenchmark = new TBenchmark();
135  if ( ! gStyle ) gStyle = new TStyle();
136 
137  if ( ! gProgName ) // should have been set by TApplication
138 #if PY_VERSION_HEX < 0x03000000
139  gSystem->SetProgname( Py_GetProgramName() );
140 #else
141 // TODO: convert the wchar_t*
142  gSystem->SetProgname( "python" );
143 #endif
144 
145  return kTRUE;
146 }
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 /// Install ROOT message handler which will turn ROOT error message into
150 /// python exceptions. Always returns true.
151 
152 Bool_t PyROOT::TPyROOTApplication::InitROOTMessageCallback()
153 {
154  SetErrorHandler( (ErrorHandlerFunc_t)&Utility::ErrMsgHandler );
155  return kTRUE;
156 }