Logo ROOT   6.12/07
Reference Guide
TAlienPackage.cxx
Go to the documentation of this file.
1 // @(#)root/alien:$Id$
2 // Author: Lucia Jancurova/Andreas-Joachim Peters 1/10/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "Riostream.h"
13 #include "TSystem.h"
14 #include "TGridResult.h"
15 #include "TFile.h"
16 #include "TObjString.h"
17 #include "TObjArray.h"
18 #include "TError.h"
19 #include "TAlienPackage.h"
20 
21 //////////////////////////////////////////////////////////////////////////
22 // //
23 // TAlienPackage //
24 // //
25 // Class providing package management functionality like the AliEn //
26 // Package Management System. //
27 // Allows to setup software packages on a local desktop like in the //
28 // GRID environment and to execute the contained programs. //
29 // Registered Dependencies are automatically resolved and missing //
30 // packages are automatically installed. //
31 // Currently there is no support for 'source' packages. //
32 // The desired platform has to be specified in the constructor. //
33 // The default constructor takes packages from the global package //
34 // section in AliEn. If you want to install a user package, you have to //
35 // set the AliEn package directory to your local package directory using//
36 // 'package->SetAliEnMainPackageDir("/alice/cern.ch/user/..../packages")//
37 // //
38 // ---------------------------------------------------------------------/////////////////////////
39 // Examples of use: //
40 // root [0] TAlienPackage* package = new TAlienPackage("AliRoot","v4-07-Rev-01","Linux-i686"); //
41 // root [1] package->Exec("aliroot -b -q ") //
42 // //
43 // root [0] TAlienPackage* package = new TAlienPackage("ROOT","v5-16-00","Linux-i686"); //
44 // root [1] package->Exec("root -b -q ") //
45 /////////////////////////////////////////////////////////////////////////////////////////////////
46 
47 
48 
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Default constructor of a AliEn package constructing a ROOT:v5-16-00 for Linux-i686.
53 
54 TAlienPackage::TAlienPackage() : fInstallList (0), fPackages (0), fDebugLevel (0)
55 {
56  fName = "ROOT";
57  fVersion = "v5-16-00";
58  fPlatform = "Linux-i686";
59  fAliEnMainPackageDir = "/alice/packages";
60  fInstallationDirectory = "/var/tmp/alien/packages";
61  fPostInstallCommand = "post_install";
62  fEnableCommand = "";
63 
64  if (gDebug > 0)
65  Info ("TAlienPackage",
66  "\tPackage=%s Version=%s Platform=%s Installdir=%s AlienInstalldir=%s PostInstall=%s",
67  fName.Data (), fVersion.Data (), fPlatform.Data (),
68  fInstallationDirectory.Data (), fAliEnMainPackageDir.Data (),
69  fPostInstallCommand.Data ());
70  if (!gGrid)
71  gGrid = TGrid::Connect ("alien://");
72 
73  if (!fInstallList)
74  fInstallList = new TList ();
75  if (!fPackages)
76  fPackages = new TList ();
77 
78  fEnabled = kFALSE;
79  fPackages->SetOwner (kFALSE);
80 }
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 /// Constructor of a AliEn package.
84 
85 TAlienPackage::TAlienPackage(const char *name, const char *version,
86  const char *platform,
87  const char *installationdirectory) :
88  fInstallList (0), fPackages (0), fDebugLevel (0)
89 {
90  fName = name;
91 
92  fVersion = version;
93 
94  fAliEnMainPackageDir = "/alice/packages";
95  fInstallationDirectory = installationdirectory;
96  fPostInstallCommand = "post_install";
97  fEnableCommand = "";
98  fPlatform = platform;
99  fEnabled = kFALSE;
100 
101  if (gDebug > 0)
102  Info ("TAlienPackage",
103  "\tPackage=%s Version=%s Platform=%s Installdir=%s AlienInstalldir=%s PostInstall=%s",
104  name, version, platform, installationdirectory,
106 
107  if (!gGrid)
108  gGrid = TGrid::Connect ("alien://");
109 
110  if (!fInstallList)
111  fInstallList = new TList ();
112 
113  if (!fPackages)
114  fPackages = new TList ();
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Destructor.
120 
121 TAlienPackage::~TAlienPackage()
122 {
123  if (GetDebugLevel () > 2)
124  Info ("~TAlienPackage", "\tDestr: Package=%s Version=%s Platform=%s",
125  fName.Data (), fVersion.Data (), fPlatform.Data ());
127 }
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// Install/enable an AliEn package on the local computer.
131 
133 {
134  fInstallList->Clear ();
135  if (GetDebugLevel () > 1)
136  Info ("Install", "\t\tInstalling Package=%s Version=%s Platform=%s",
137  fName.Data (), fVersion.Data (), fPlatform.Data ());
138 
140  return kFALSE;
141 
142  if (CheckDependencies () == kFALSE)
143  return kFALSE;
144 
145  if (InstallAllPackages () == kFALSE)
146  return kFALSE;
147 
148  gSystem->Exec(Form("mkdir -p %s/%s/%s/%s ; touch %s/%s/%s/%s/.safeguard",
151  fVersion.Data (), fVersion.Data ()));
152 
153  fEnabled = kTRUE;
154  return kTRUE;
155 }
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 /// Return shell command to enable package.
159 
161 {
163  Form ("%s/%s/%s/.alienEnvironment %s/%s/%s ",
166  return fEnableCommand.Data ();
167 }
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 /// Uninstall a package e.g. remove it from the local disk.
171 
173 {
174  gSystem->Exec(Form
175  ("test -e %s/%s/%s/%s/.safeguard && rm -rf %s/%s/%s",
178  fVersion.Data ()));
179  fEnabled = kFALSE;
180  return kTRUE;
181 }
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 /// Check that <str> is listed in GRID directory <dir1>.
185 
186 Bool_t TAlienPackage::IsDirectory (const char *dir1, const char *str)
187 {
188  TGridResult *result = gGrid->Ls (dir1);
189  Int_t i = 0;
190  while (result->GetFileName (i)) {
191  if (TString (result->GetFileName (i)) == str) {
192  return kTRUE;
193  }
194  i++;
195  }
196 
197  return kFALSE;
198 }
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 /// Check the name and version directory of package/version given.
202 
204 {
206 
207  if ((IsDirectory (s.Data (), name.Data ())) == kTRUE) {
208  if (GetDebugLevel () > 1)
209  Info ("CheckDirectories", "\t%s/%s exists.", s.Data (), name.Data ());
210 
211  s += "/" + name;
212  if ((IsDirectory (s, version.Data ())) == kTRUE) {
213  if (GetDebugLevel () > 1)
214  Info ("CheckDirectories", "\t%s/%s exist.", s.Data (), version.Data ());
215 
216  s += "/" + version;
217  if ((IsDirectory (s, GetPlatform ().Data ())) == kTRUE) {
218  if (GetDebugLevel () > 1)
219  Info ("CheckDirectories", "\t%s/%s exist.", s.Data (), GetPlatform ().Data ());
220  return kTRUE;
221  } else {
222  Error ("CheckDirectories", "\t%s/%s does not exist.", s.Data (), GetPlatform ().Data ());
223  }
224  } else {
225  Error ("CheckDirectories", "\t%s/%s does not exist.", s.Data (), version.Data ());
226  }
227  } else {
228  Info ("CheckDirectories", "\t%s/%s exists.", s.Data (), name.Data ());
229  }
230 
231  return kFALSE;
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Reinstalls a package e.g. uninstall + install.
236 
238 {
239  if (UnInstall () == kFALSE)
240  return kFALSE;
241 
242  if (Enable () == kFALSE)
243  return kFALSE;
244  return kTRUE;
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 /// Execute post_install procedure for a package.
249 
251 {
252  TGridResult *result =
253  gGrid->Command (Form
254  ("showTagValue -z %s/%s/%s PackageDef",
255  fAliEnMainPackageDir.Data (), name.Data (), version.Data ()));
256  TString post_install (result->GetKey (0, "post_install"));
257 
258  if (post_install.IsNull () == kTRUE) {
259  if (GetDebugLevel () > 0)
260  Info ("PostInstall",
261  "\tNo post install procedure defined in AliEn.");
262  return kTRUE;
263  }
264 
265  if (GetDebugLevel () > 0)
266  Info ("PostInstall",
267  "\tDownloading PostInstall for Package=%s Version=%s",
268  name.Data (), version.Data ());
269 
270  if (!TFile::Cp(Form("alien://%s", post_install.Data ()),
271  Form("%s/%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
272  version.Data (), fPostInstallCommand.Data ()))) {
273  Error ("PostInstall", "\tCannot download the PostInstall script %s!", post_install.Data ());
274  return kFALSE;
275  }
276 
278  ("%s/%s/%s", fInstallationDirectory.Data (),
279  name.Data (), version.Data ()));
280  gSystem->Exec (Form ("chmod +x %s", fPostInstallCommand.Data ()));
281  gSystem->Exec (Form ("./%s %s/%s/%s", fPostInstallCommand.Data (),
282  fInstallationDirectory.Data (), name.Data (), version.Data ()));
283 
284  if (GetDebugLevel () > 1)
285  Info ("PostInstall",
286  "\tExecuted PostInstall for Package=%s Version=%s ", name.Data (),
287  version.Data ());
288  return kTRUE;
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Execute package command.
293 
294 Bool_t TAlienPackage::Exec (const char *cmdline)
295 {
296  TString fullline = "";
297 
298  if (!fEnabled) {
299  if (!Enable ())
300  return kFALSE;
301  }
302 
303  for (Int_t j = 0; j < fPackages->GetEntries (); j++) {
304  TAlienPackage *package = (TAlienPackage *) fPackages->At (j);
305  fullline += package->GetEnable ();
306  fullline += " ";
307  }
308 
309  fullline += cmdline;
310 
311  Info("Exec", "\t\tExecuting Package=%s Version=%s \"%s\"", fName.Data (),
312  fVersion.Data (), fullline.Data ());
313 
314  gSystem->Exec(fullline.Data());
315  return kTRUE;
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// Check the dependency packages of this package.
320 
322 {
323  TString path (Form("%s/%s/%s", fAliEnMainPackageDir.Data (), fName.Data (),
324  fVersion.Data ()));
325 
326  TGridResult *result =
327  gGrid->Command (Form ("showTagValue -z %s PackageDef", path.Data ()));
328 
329  TString strDep (result->GetKey (0, "dependencies"));
330 
331  if (strDep.IsNull () == kTRUE) {
332  if (GetDebugLevel () > 0)
333  Info ("CheckDepencencies", "\tFound no dependencies ... ");
334  TObjString *strObj =
335  new TObjString (Form ("%s::%s", fName.Data (), fVersion.Data ()));
336  fInstallList->Add (strObj);
337  return kTRUE;
338  }
339 
340  TObjArray *strDeps = strDep.Tokenize (",");
341 
342  if (GetDebugLevel () > 0)
343  Info ("CheckDepencencies", "\tFound %d dependencies ... ",
344  strDeps->GetEntries ());
345 
346  for (Int_t i = 0; i < strDeps->GetEntries (); i++) {
347  TObjString *strObj = (TObjString *) strDeps->At (i);
348  TObjArray *strDepsPackgAndVer = strObj->GetString ().Tokenize ("@");
349  TObjString *strObj2 = (TObjString *) strDepsPackgAndVer->At (1);
350 
351  if (GetDebugLevel () > 2)
352  Info ("CheckDependencies", "\t[%d] Dep. Package=%s", i,
353  strObj2->GetString ().Data ());
354  fInstallList->Add (strObj2);
355  }
356 
357  TObjString *strObj = new TObjString (Form ("%s::%s", fName.Data (), fVersion.Data ()));
358  fInstallList->Add (strObj);
359 
360  for (Int_t j = 0; j < fInstallList->GetEntries (); j++) {
361  strObj = (TObjString *) fInstallList->At(j);
362  TString strObjPackage, strObjVersion;
363  Int_t from = 0;
364  if (strObj->GetString().Tokenize(strObjPackage, from, "::")) {
365  if (!strObj->GetString().Tokenize(strObjVersion, from, "::")) {
366  Warning("CheckDepencencies", "version string not found for j=%d (%s)", j, strObj->GetName());
367  continue;
368  }
369  } else {
370  Warning("CheckDepencencies", "package string not found for j=%d (%s)", j, strObj->GetName());
371  continue;
372  }
373 
374  if (GetDebugLevel () > 2)
375  Info ("CheckDepencencies", "\t[%d] Name=%s Version=%s", j,
376  strObjPackage.Data(), strObjVersion.Data());
377 
378  if (CheckDirectories(strObjPackage, strObjVersion) == kFALSE)
379  return kFALSE;
380  }
381 
382  return kTRUE;
383 }
384 
385 ////////////////////////////////////////////////////////////////////////////////
386 /// Install a single package.
387 
389 {
390  Info ("InstallSinglePackage", "\t%s %s", name.Data (), version.Data ());
391  // install a package without dependencies
392  TString s1 (Form ("%s/%s/%s/%s", fAliEnMainPackageDir.Data (), name.Data (),
393  version.Data (), fPlatform.Data ()));
394  TString s2 (Form ("%s(%s)", name.Data (), version.Data ()));
395  TString s3 (Form ("%s/%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
396  version.Data (), version.Data ()));
397  TString s4 (Form ("%s/%s/%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
398  version.Data (), version.Data (), fPlatform.Data ()));
399  TString s5 (Form ("%s/%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
400  version.Data (), fPlatform.Data ()));
401  TString s6 (Form ("%s/%s", fAliEnMainPackageDir.Data (), name.Data ()));
402  TString s7 (Form ("%s/%s/%s", fInstallationDirectory.Data (), name.Data (),
403  version.Data ()));
404  TString s8 (Form ("%s/%s/%s/%s/.safeguard", fInstallationDirectory.Data (),
405  name.Data (), version.Data (), version.Data ()));
406 
407  if (gSystem->AccessPathName (s8.Data ()) == 0) {
408  if (isDep == kFALSE) {
409  if (GetDebugLevel () > 0) {
410  Warning ("InstallSinglePackage",
411  "\tPackage=%s exists in /%s directory.",
412  s2.Data (), s3.Data ());
413  Warning ("InstallSinglePackage",
414  "\tYou might use function UnInstall() before Enable(), or do ReInstall() !!!!");
415  }
416  return kTRUE;
417  } else {
418  return kTRUE;
419  }
420  }
421 
422  if (GetDebugLevel () > 1)
423  Info ("InstallSinglePackage", "\tCopying from alien://%s to %s ",
424  s1.Data (), s5.Data ());
425 
426  gSystem->Exec (Form ("mkdir -p %s", s3.Data ()));
427 
428  if (gSystem->AccessPathName (s3.Data ())) {
429  Error ("InstallSinglePackage", "\tCouldn't create directory %s !",
430  s3.Data ());
431  return kFALSE;
432  }
433 
434  if (!TFile::Cp (Form ("alien://%s", s1.Data ()), Form ("%s", s5.Data ()))) {
435  Error ("InstallSinglePackage", "\tCouldn't copy alien://%s -> %s",
436  s1.Data (), s5.Data ());
437  return kFALSE;
438  }
439 
440  if (GetDebugLevel () > 2)
441  Info ("InstallSinglePackage", "\tEntering directory %s ", s7.Data ());
442 
443  if (!gSystem->ChangeDirectory (Form ("%s", s7.Data ()))) {
444  Error ("InstallSinglePackage", "\tCannot change into directory %s",
445  s7.Data ());
446  return kFALSE;
447  }
448 
449  if (GetDebugLevel () > 2)
450  Info ("InstallSinglePackage", "\tUnpacking the package %s ...",
451  s2.Data ());
452 
453  gSystem->Exec (Form ("tar -xzf %s", fPlatform.Data ()));
454 
455  if (GetDebugLevel () > 2)
456  Info ("InstallSinglePackage", "\tUnpacking the package %s DONE ...",
457  s2.Data ());
458 
459  gSystem->Exec (Form ("rm -f %s", fPlatform.Data ()));
460 
461  if (GetDebugLevel () > 2)
462  Info ("InstallSinglePackage",
463  "\tCopying PostInstall alien://%s/%s -> %s", s6.Data (),
464  fPostInstallCommand.Data (), s7.Data ());
465 
466  if (!PostInstall (name, version)) {
467  Error ("InstallSinglePackage",
468  "\tPostInstall procedure failed for package %s failed!",
469  s2.Data ());
470  return kFALSE;
471  }
472 
473  return kTRUE;
474 }
475 
476 ////////////////////////////////////////////////////////////////////////////////
477 /// Installs a package and all its direct dependencies.
478 
480 {
481  Bool_t isDep = kFALSE;
482 
483  Info ("InstallAllPackages", "\tPackage=%s Version=%s", fName.Data (),
484  fVersion.Data ());
485 
486  for (Int_t j = 0; j < fPackages->GetEntries (); j++) {
487  TAlienPackage *package = (TAlienPackage *) fPackages->At (j);
488  if (package && (package != this))
489  delete package;
490  }
491 
492  fPackages->Clear ();
493 
494  for (Int_t j = 0; j < fInstallList->GetEntries (); j++) {
495  TObjString *strObj = (TObjString *) fInstallList->At (j);
496 
497  TObjArray *strDepsPackgOrVer = strObj->GetString ().Tokenize ("::");
498  TObjString *strObjPackage = (TObjString *) strDepsPackgOrVer->At (0);
499  TObjString *strObjVersion = (TObjString *) strDepsPackgOrVer->At (1);
500  if (GetDebugLevel () > 1)
501  Info ("InstallAllPackages", "\tPackage=%s Version=%s",
502  strObjPackage->GetString ().Data (),
503  strObjVersion->GetString ().Data ());
504 
505  if (j < (fInstallList->GetEntries () - 1))
506  isDep = kTRUE;
507  else
508  isDep = kFALSE;
509 
510  if (j == (fInstallList->GetEntries () - 1)) {
511  if (InstallSinglePackage(strObjPackage->GetString (), strObjVersion->GetString (), isDep) == kFALSE)
512  return kFALSE;
513  fPackages->Add ((TObject *) this);
514  } else {
515  TAlienPackage *newpackage = new TAlienPackage(strObjPackage->GetName(),
516  strObjVersion->GetName(),
517  fPlatform.Data());
518  if (newpackage) {
519  if (!newpackage->Enable ()) {
520  delete newpackage;
521  return kFALSE;
522  }
523  } else {
524  return kFALSE;
525  }
526 
527  fPackages->Add ((TObject *) newpackage);
528  }
529  }
530 
531  return kTRUE;
532 }
TString fVersion
Definition: TAlienPackage.h:34
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1276
An array of TObjects.
Definition: TObjArray.h:37
virtual const char * GetKey(UInt_t, const char *) const
Definition: TGridResult.h:45
TString fInstallationDirectory
Definition: TAlienPackage.h:36
Collectable string class.
Definition: TObjString.h:28
R__EXTERN TGrid * gGrid
Definition: TGrid.h:129
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TString fPostInstallCommand
Definition: TAlienPackage.h:38
Bool_t Enable()
Install/enable an AliEn package on the local computer.
TString GetAliEnMainPackageDir() const
Definition: TAlienPackage.h:87
virtual Int_t GetEntries() const
Definition: TCollection.h:177
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:860
Basic string class.
Definition: TString.h:125
const char * GetEnable()
Return shell command to enable package.
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TString fAliEnMainPackageDir
Definition: TAlienPackage.h:37
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
Bool_t UnInstall()
Uninstall a package e.g. remove it from the local disk.
Int_t GetDebugLevel()
Definition: TAlienPackage.h:95
virtual Bool_t Cp(const char *dst, Bool_t progressbar=kTRUE, UInt_t buffersize=1000000)
Allows to copy this file to the dst URL.
Definition: TFile.cxx:4848
#define SafeDelete(p)
Definition: RConfig.h:509
static TGrid * Connect(const char *grid, const char *uid=0, const char *pw=0, const char *options=0)
The grid should be of the form: <grid>://<host>[:<port>], e.g.
Definition: TGrid.cxx:50
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
A doubly linked list.
Definition: TList.h:44
Bool_t PostInstall(TString name, TString version)
Execute post_install procedure for a package.
const char * GetName() const
Returns name of object.
Definition: TObjString.h:39
const TString & GetString() const
Definition: TObjString.h:47
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
TString GetPlatform() const
Definition: TAlienPackage.h:79
char * Form(const char *fmt,...)
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:661
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
void Warning(const char *location, const char *msgfmt,...)
Bool_t InstallSinglePackage(TString name, TString version, Bool_t isDep=kFALSE)
Install a single package.
const Bool_t kFALSE
Definition: RtypesCore.h:88
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2251
#define ClassImp(name)
Definition: Rtypes.h:359
Bool_t ReInstall()
Reinstalls a package e.g. uninstall + install.
Bool_t CheckDependencies()
Check the dependency packages of this package.
Bool_t InstallAllPackages()
Installs a package and all its direct dependencies.
static constexpr double s
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
TString fEnableCommand
Definition: TAlienPackage.h:39
Mother of all ROOT objects.
Definition: TObject.h:37
TAlienPackage()
Default constructor of a AliEn package constructing a ROOT:v5-16-00 for Linux-i686.
TList * fInstallList
Definition: TAlienPackage.h:40
TList * fPackages
Definition: TAlienPackage.h:41
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual const char * GetFileName(UInt_t) const
Definition: TGridResult.h:37
TString fPlatform
Definition: TAlienPackage.h:35
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:522
R__EXTERN Int_t gDebug
Definition: Rtypes.h:86
virtual TGridResult * Ls(const char *="", Option_t *="", Bool_t=kFALSE)
Definition: TGrid.h:85
Bool_t CheckDirectories(TString name, TString version)
Check the name and version directory of package/version given.
Bool_t IsDirectory(const char *dir1, const char *str)
Check that <str> is listed in GRID directory <dir1>.
Bool_t Exec(const char *cmdline)
Execute package command.
virtual TGridResult * Command(const char *, Bool_t=kFALSE, UInt_t=2)
Definition: TGrid.h:73
const Bool_t kTRUE
Definition: RtypesCore.h:87
char name[80]
Definition: TGX11.cxx:109
const char * Data() const
Definition: TString.h:345