Logo ROOT   master
Reference Guide
TApplication.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Fons Rademakers 22/12/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, 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 /** \class TApplication
13 \ingroup Base
14 
15 This class creates the ROOT Application Environment that interfaces
16 to the windowing system eventloop and eventhandlers.
17 This class must be instantiated exactly once in any given
18 application. Normally the specific application class inherits from
19 TApplication (see TRint).
20 */
21 
22 #include "RConfigure.h"
23 #include "Riostream.h"
24 #include "TApplication.h"
25 #include "TException.h"
26 #include "TGuiFactory.h"
27 #include "TVirtualX.h"
28 #include "TROOT.h"
29 #include "TSystem.h"
30 #include "TString.h"
31 #include "TError.h"
32 #include "TObjArray.h"
33 #include "TObjString.h"
34 #include "TTimer.h"
35 #include "TInterpreter.h"
36 #include "TStyle.h"
37 #include "TVirtualPad.h"
38 #include "TEnv.h"
39 #include "TColor.h"
40 #include "TPluginManager.h"
41 #include "TClassTable.h"
42 #include "TBrowser.h"
43 #include "TUrl.h"
44 #include "TVirtualMutex.h"
45 #include "TClassEdit.h"
46 #include "TMethod.h"
47 #include "TDataMember.h"
48 #include "TApplicationCommandLineOptionsHelp.h"
49 #include "TPRegexp.h"
50 #include <stdlib.h>
51 
55 TList *TApplication::fgApplications = 0; // List of available applications
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 
59 class TIdleTimer : public TTimer {
60 public:
61  TIdleTimer(Long_t ms) : TTimer(ms, kTRUE) { }
62  Bool_t Notify();
63 };
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 /// Notify handler.
67 
68 Bool_t TIdleTimer::Notify()
69 {
71  Reset();
72  return kFALSE;
73 }
74 
75 
77 
79 {
80  // Insure that the files, canvases and sockets are closed.
81 
82  // If we get here, the tear down has started. We have no way to know what
83  // has or has not yet been done. In particular on Ubuntu, this was called
84  // after the function static in TSystem.cxx has been destructed. So we
85  // set gROOT in its end-of-life mode which prevents executing code, like
86  // autoloading libraries (!) that is pointless ...
87  if (gROOT) {
88  gROOT->SetBit(kInvalidObject);
89  gROOT->EndOfProcessCleanups();
90  }
91 }
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 /// Default ctor. Can be used by classes deriving from TApplication.
95 
97  fArgc(0), fArgv(0), fAppImp(0), fIsRunning(kFALSE), fReturnFromRun(kFALSE),
98  fNoLog(kFALSE), fNoLogo(kFALSE), fQuit(kFALSE), fUseMemstat(kFALSE),
99  fFiles(0), fIdleTimer(0), fSigHandler(0), fExitOnException(kDontExit),
100  fAppRemote(0)
101 {
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Create an application environment. The application environment
107 /// provides an interface to the graphics system and eventloop
108 /// (be it X, Windows, MacOS or BeOS). After creating the application
109 /// object start the eventloop by calling its Run() method. The command
110 /// line options recognized by TApplication are described in the GetOptions()
111 /// method. The recognized options are removed from the argument array.
112 /// The original list of argument options can be retrieved via the Argc()
113 /// and Argv() methods. The appClassName "proofserv" is reserved for the
114 /// PROOF system. The "options" and "numOptions" arguments are not used,
115 /// except if you want to by-pass the argv processing by GetOptions()
116 /// in which case you should specify numOptions<0. All options will
117 /// still be available via the Argv() method for later use.
118 
119 TApplication::TApplication(const char *appClassName, Int_t *argc, char **argv,
120  void * /*options*/, Int_t numOptions) :
121  fArgc(0), fArgv(0), fAppImp(0), fIsRunning(kFALSE), fReturnFromRun(kFALSE),
122  fNoLog(kFALSE), fNoLogo(kFALSE), fQuit(kFALSE), fUseMemstat(kFALSE),
123  fFiles(0), fIdleTimer(0), fSigHandler(0), fExitOnException(kDontExit),
124  fAppRemote(0)
125 {
127 
128  // Create the list of applications the first time
129  if (!fgApplications)
130  fgApplications = new TList;
131 
132  // Add the new TApplication early, so that the destructor of the
133  // default TApplication (if it is called in the block of code below)
134  // will not destroy the files, socket or TColor that have already been
135  // created.
136  fgApplications->Add(this);
137 
139  // allow default TApplication to be replaced by a "real" TApplication
140  delete gApplication;
141  gApplication = 0;
142  gROOT->SetBatch(kFALSE);
144  }
145 
146  if (gApplication) {
147  Error("TApplication", "only one instance of TApplication allowed");
148  fgApplications->Remove(this);
149  return;
150  }
151 
152  if (!gROOT)
153  ::Fatal("TApplication::TApplication", "ROOT system not initialized");
154 
155  if (!gSystem)
156  ::Fatal("TApplication::TApplication", "gSystem not initialized");
157 
158  static Bool_t hasRegisterAtExit(kFALSE);
159  if (!hasRegisterAtExit) {
160  // If we are the first TApplication register the atexit)
161  atexit(CallEndOfProcessCleanups);
162  hasRegisterAtExit = kTRUE;
163  }
164  gROOT->SetName(appClassName);
165 
166  // copy command line arguments, can be later accessed via Argc() and Argv()
167  if (argc && *argc > 0) {
168  fArgc = *argc;
169  fArgv = (char **)new char*[fArgc];
170  }
171 
172  for (int i = 0; i < fArgc; i++)
173  fArgv[i] = StrDup(argv[i]);
174 
175  if (numOptions >= 0)
176  GetOptions(argc, argv);
177 
178  if (fArgv)
180 
181  // Tell TSystem the TApplication has been created
183 
184  fAppImp = gGuiFactory->CreateApplicationImp(appClassName, argc, argv);
186 
187  // Initialize the graphics environment
188  if (gClassTable->GetDict("TPad")) {
191  }
192 
193  // Save current interpreter context
194  gInterpreter->SaveContext();
195  gInterpreter->SaveGlobalsContext();
196 
197  // to allow user to interact with TCanvas's under WIN32
198  gROOT->SetLineHasBeenProcessed();
199 
200  // activate TMemStat
201  if (fUseMemstat || gEnv->GetValue("Root.TMemStat", 0)) {
202  fUseMemstat = kTRUE;
203  Int_t buffersize = gEnv->GetValue("Root.TMemStat.buffersize", 100000);
204  Int_t maxcalls = gEnv->GetValue("Root.TMemStat.maxcalls", 5000000);
205  const char *ssystem = gEnv->GetValue("Root.TMemStat.system","gnubuiltin");
206  if (maxcalls > 0) {
207  gROOT->ProcessLine(Form("new TMemStat(\"%s\",%d,%d);",ssystem,buffersize,maxcalls));
208  }
209  }
210 
211  //Needs to be done last
212  gApplication = this;
213  gROOT->SetApplication(this);
214 
215 }
216 
217 ////////////////////////////////////////////////////////////////////////////////
218 /// TApplication dtor.
219 
221 {
222  for (int i = 0; i < fArgc; i++)
223  if (fArgv[i]) delete [] fArgv[i];
224  delete [] fArgv;
225 
226  if (fgApplications)
227  fgApplications->Remove(this);
228 
229  //close TMemStat
230  if (fUseMemstat) {
231  ProcessLine("TMemStat::Close()");
233  }
234 
235  // Reduce the risk of the files or sockets being closed after the
236  // end of 'main' (or more exactly before the library start being
237  // unloaded).
238  if (fgApplications == 0 || fgApplications->FirstLink() == 0 ) {
239  TROOT::ShutDown();
240  }
241 
242  // Now that all the canvases and files have been closed we can
243  // delete the implementation.
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 /// Static method. This method should be called from static library
249 /// initializers if the library needs the low level graphics system.
250 
252 {
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Initialize the graphics environment.
258 
260 {
261  if (fgGraphInit || !fgGraphNeeded) return;
262 
263  // Load the graphics related libraries
265 
266  // Try to load TrueType font renderer. Only try to load if not in batch
267  // mode and Root.UseTTFonts is true and Root.TTFontPath exists. Abort silently
268  // if libttf or libGX11TTF are not found in $ROOTSYS/lib or $ROOTSYS/ttf/lib.
269  const char *ttpath = gEnv->GetValue("Root.TTFontPath",
271  char *ttfont = gSystem->Which(ttpath, "arialbd.ttf", kReadPermission);
272  // Check for use of DFSG - fonts
273  if (!ttfont)
274  ttfont = gSystem->Which(ttpath, "FreeSansBold.ttf", kReadPermission);
275 
276 #if !defined(R__WIN32)
277  if (!gROOT->IsBatch() && !strcmp(gVirtualX->GetName(), "X11") &&
278  ttfont && gEnv->GetValue("Root.UseTTFonts", 1)) {
279  if (gClassTable->GetDict("TGX11TTF")) {
280  // in principle we should not have linked anything against libGX11TTF
281  // but with ACLiC this can happen, initialize TGX11TTF by hand
282  // (normally this is done by the static library initializer)
283  ProcessLine("TGX11TTF::Activate();");
284  } else {
285  TPluginHandler *h;
286  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", "x11ttf")))
287  if (h->LoadPlugin() == -1)
288  Info("InitializeGraphics", "no TTF support");
289  }
290  }
291 #endif
292  delete [] ttfont;
293 
294  // Create WM dependent application environment
295  if (fAppImp)
296  delete fAppImp;
298  if (!fAppImp) {
299  MakeBatch();
301  }
302 
303  // Create the canvas colors early so they are allocated before
304  // any color table expensive bitmaps get allocated in GUI routines (like
305  // creation of XPM bitmaps).
307 
308  // Hook for further initializing the WM dependent application environment
309  Init();
310 
311  // Set default screen factor (if not disabled in rc file)
312  if (gEnv->GetValue("Canvas.UseScreenFactor", 1)) {
313  Int_t x, y;
314  UInt_t w, h;
315  if (gVirtualX) {
316  gVirtualX->GetGeometry(-1, x, y, w, h);
317  if (h > 0 && h < 1000) gStyle->SetScreenFactor(0.0011*h);
318  }
319  }
320 }
321 
322 ////////////////////////////////////////////////////////////////////////////////
323 /// Clear list containing macro files passed as program arguments.
324 /// This method is called from TRint::Run() to ensure that the macro
325 /// files are only executed the first time Run() is called.
326 
328 {
329  if (fFiles) {
330  fFiles->Delete();
332  }
333 }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 /// Return specified argument.
337 
338 char *TApplication::Argv(Int_t index) const
339 {
340  if (fArgv) {
341  if (index >= fArgc) {
342  Error("Argv", "index (%d) >= number of arguments (%d)", index, fArgc);
343  return 0;
344  }
345  return fArgv[index];
346  }
347  return 0;
348 }
349 
350 ////////////////////////////////////////////////////////////////////////////////
351 /// Get and handle command line options. Arguments handled are removed
352 /// from the argument array. See CommandLineOptionsHelp.h for options.
353 
354 void TApplication::GetOptions(Int_t *argc, char **argv)
355 {
356  static char null[1] = { "" };
357 
358  fNoLog = kFALSE;
359  fQuit = kFALSE;
360  fFiles = 0;
361 
362  if (!argc)
363  return;
364 
365  int i, j;
366  TString pwd;
367 
368  for (i = 1; i < *argc; i++) {
369  if (!strcmp(argv[i], "-?") || !strncmp(argv[i], "-h", 2) ||
370  !strncmp(argv[i], "--help", 6)) {
371  fprintf(stderr, kCommandLineOptionsHelp);
372  Terminate(0);
373  } else if (!strncmp(argv[i], "--version", 9)) {
374  fprintf(stderr, "ROOT Version: %s\n", gROOT->GetVersion());
375  fprintf(stderr, "Built for %s on %s\n",
377  gROOT->GetGitDate());
378 
379  fprintf(stderr, "From %s@%s\n",
380  gROOT->GetGitBranch(),
381  gROOT->GetGitCommit());
382 
383  Terminate(0);
384  } else if (!strcmp(argv[i], "-config")) {
385  fprintf(stderr, "ROOT ./configure options:\n%s\n", gROOT->GetConfigOptions());
386  Terminate(0);
387  } else if (!strcmp(argv[i], "-memstat")) {
388  fUseMemstat = kTRUE;
389  argv[i] = null;
390  } else if (!strcmp(argv[i], "-b")) {
391  MakeBatch();
392  argv[i] = null;
393  } else if (!strcmp(argv[i], "-n")) {
394  fNoLog = kTRUE;
395  argv[i] = null;
396  } else if (!strcmp(argv[i], "-t")) {
398  // EnableImplicitMT() only enables thread safety if IMT was configured;
399  // enable thread safety even with IMT off:
401  argv[i] = null;
402  } else if (!strcmp(argv[i], "-q")) {
403  fQuit = kTRUE;
404  argv[i] = null;
405  } else if (!strcmp(argv[i], "-l")) {
406  // used by front-end program to not display splash screen
407  fNoLogo = kTRUE;
408  argv[i] = null;
409  } else if (!strcmp(argv[i], "-x")) {
411  argv[i] = null;
412  } else if (!strcmp(argv[i], "-splash")) {
413  // used when started by front-end program to signal that
414  // splash screen can be popped down (TRint::PrintLogo())
415  argv[i] = null;
416  } else if (strncmp(argv[i], "--web", 5) == 0) {
417  // the web mode is requested
418  const char *opt = argv[i] + 5;
419  argv[i] = null;
420  TString argw;
421  if (gROOT->IsBatch()) argw = "batch";
422  if (*opt == '=') argw.Append(opt+1);
423  if (gSystem->Load("libROOTWebDisplay") >= 0) {
424  gROOT->SetWebDisplay(argw.Data());
425  gEnv->SetValue("Gui.Factory", "web");
426  } else {
427  Error("GetOptions", "--web option not supported, ROOT should be built with at least c++14 enabled");
428  }
429  } else if (!strcmp(argv[i], "-e")) {
430  argv[i] = null;
431  ++i;
432 
433  if ( i < *argc ) {
434  if (!fFiles) fFiles = new TObjArray;
435  TObjString *expr = new TObjString(argv[i]);
436  expr->SetBit(kExpression);
437  fFiles->Add(expr);
438  argv[i] = null;
439  } else {
440  Warning("GetOptions", "-e must be followed by an expression.");
441  }
442  } else if (!strcmp(argv[i], "--")) {
443  TObjString* macro = nullptr;
444  bool warnShown = false;
445 
446  if (fFiles) {
447  for (auto f: *fFiles) {
448  TObjString* file = dynamic_cast<TObjString*>(f);
449  if (!file) {
450  if (!dynamic_cast<TNamed*>(f)) {
451  Error("GetOptions()", "Inconsistent file entry (not a TObjString)!");
452  f->Dump();
453  } // else we did not find the file.
454  continue;
455  }
456 
457  if (file->TestBit(kExpression))
458  continue;
459  if (file->String().EndsWith(".root"))
460  continue;
461  if (file->String().Contains('('))
462  continue;
463 
464  if (macro && !warnShown && (warnShown = true))
465  Warning("GetOptions", "-- is used with several macros. "
466  "The arguments will be passed to the last one.");
467 
468  macro = file;
469  }
470  }
471 
472  if (macro) {
473  argv[i] = null;
474  ++i;
475  TString& str = macro->String();
476 
477  str += '(';
478  for (; i < *argc; i++) {
479  str += argv[i];
480  str += ',';
481  argv[i] = null;
482  }
483  str.EndsWith(",") ? str[str.Length() - 1] = ')' : str += ')';
484  } else {
485  Warning("GetOptions", "no macro to pass arguments to was provided. "
486  "Everything after the -- will be ignored.");
487  for (; i < *argc; i++)
488  argv[i] = null;
489  }
490  } else if (argv[i][0] != '-' && argv[i][0] != '+') {
491  Long64_t size;
492  Long_t id, flags, modtime;
493  char *arg = strchr(argv[i], '(');
494  if (arg) *arg = '\0';
495  char *dir = gSystem->ExpandPathName(argv[i]);
496  // ROOT-9959: we do not continue if we could not expand the path
497  if (!dir) continue;
498  TUrl udir(dir, kTRUE);
499  // remove options and anchor to check the path
500  TString sfx = udir.GetFileAndOptions();
501  TString fln = udir.GetFile();
502  sfx.Replace(sfx.Index(fln), fln.Length(), "");
503  TString path = udir.GetFile();
504  if (strcmp(udir.GetProtocol(), "file")) {
505  path = udir.GetUrl();
506  path.Replace(path.Index(sfx), sfx.Length(), "");
507  }
508  // 'path' is the full URL without suffices (options and/or anchor)
509  if (arg) *arg = '(';
510  if (!arg && !gSystem->GetPathInfo(path.Data(), &id, &size, &flags, &modtime)) {
511  if ((flags & 2)) {
512  // if directory set it in fWorkDir
513  if (pwd == "") {
514  pwd = gSystem->WorkingDirectory();
515  fWorkDir = dir;
516  gSystem->ChangeDirectory(dir);
517  argv[i] = null;
518  } else if (!strcmp(gROOT->GetName(), "Rint")) {
519  Warning("GetOptions", "only one directory argument can be specified (%s)", dir);
520  }
521  } else if (size > 0) {
522  // if file add to list of files to be processed
523  if (!fFiles) fFiles = new TObjArray;
524  fFiles->Add(new TObjString(path.Data()));
525  argv[i] = null;
526  } else {
527  Warning("GetOptions", "file %s has size 0, skipping", dir);
528  }
529  } else {
530  if (TString(udir.GetFile()).EndsWith(".root")) {
531  if (!strcmp(udir.GetProtocol(), "file")) {
532  // file ending on .root but does not exist, likely a typo
533  // warn user if plain root...
534  if (!strcmp(gROOT->GetName(), "Rint"))
535  Warning("GetOptions", "file %s not found", dir);
536  } else {
537  // remote file, give it the benefit of the doubt and add it to list of files
538  if (!fFiles) fFiles = new TObjArray;
539  fFiles->Add(new TObjString(argv[i]));
540  argv[i] = null;
541  }
542  } else {
543  TString mode,fargs,io;
544  TString fname = gSystem->SplitAclicMode(dir,mode,fargs,io);
545  char *mac;
546  if (!fFiles) fFiles = new TObjArray;
547  if ((mac = gSystem->Which(TROOT::GetMacroPath(), fname,
548  kReadPermission))) {
549  // if file add to list of files to be processed
550  fFiles->Add(new TObjString(argv[i]));
551  argv[i] = null;
552  delete [] mac;
553  } else {
554  // if file add an invalid entry to list of files to be processed
555  fFiles->Add(new TNamed("NOT FOUND!", argv[i]));
556  // only warn if we're plain root,
557  // other progs might have their own params
558  if (!strcmp(gROOT->GetName(), "Rint"))
559  Warning("GetOptions", "macro %s not found", fname.Data());
560  }
561  }
562  }
563  delete [] dir;
564  }
565  // ignore unknown options
566  }
567 
568  // go back to startup directory
569  if (pwd != "")
570  gSystem->ChangeDirectory(pwd);
571 
572  // remove handled arguments from argument array
573  j = 0;
574  for (i = 0; i < *argc; i++) {
575  if (strcmp(argv[i], "")) {
576  argv[j] = argv[i];
577  j++;
578  }
579  }
580 
581  *argc = j;
582 }
583 
584 ////////////////////////////////////////////////////////////////////////////////
585 /// Handle idle timeout. When this timer expires the registered idle command
586 /// will be executed by this routine and a signal will be emitted.
587 
589 {
590  if (!fIdleCommand.IsNull())
592 
593  Emit("HandleIdleTimer()");
594 }
595 
596 ////////////////////////////////////////////////////////////////////////////////
597 /// Handle exceptions (kSigBus, kSigSegmentationViolation,
598 /// kSigIllegalInstruction and kSigFloatingException) trapped in TSystem.
599 /// Specific TApplication implementations may want something different here.
600 
602 {
603  if (TROOT::Initialized()) {
604  if (gException) {
605  gInterpreter->RewindDictionary();
606  gInterpreter->ClearFileBusy();
607  }
608  if (fExitOnException == kExit)
609  gSystem->Exit(128 + sig);
610  else if (fExitOnException == kAbort)
611  gSystem->Abort();
612  else
613  Throw(sig);
614  }
615  gSystem->Exit(128 + sig);
616 }
617 
618 ////////////////////////////////////////////////////////////////////////////////
619 /// Set the exit on exception option. Setting this option determines what
620 /// happens in HandleException() in case an exception (kSigBus,
621 /// kSigSegmentationViolation, kSigIllegalInstruction or kSigFloatingException)
622 /// is trapped. Choices are: kDontExit (default), kExit or kAbort.
623 /// Returns the previous value.
624 
626 {
628  fExitOnException = opt;
629  return old;
630 }
631 
632 /////////////////////////////////////////////////////////////////////////////////
633 /// The function generates and executes a command that loads the Doxygen URL in
634 /// a browser. It works for Mac, Windows and Linux. In the case of Linux, the
635 /// function also checks if the DISPLAY is set. If it isn't, a warning message
636 /// and the URL will be displayed on the terminal.
637 ///
638 /// \param[in] url web page to be displayed in a browser
639 
641 {
642  // We check what operating system the user has.
643 #ifdef R__MACOSX
644  // Command for opening a browser on Mac.
645  TString cMac("open ");
646  // We generate the full command and execute it.
647  cMac.Append(url);
648  gSystem->Exec(cMac);
649 #elif defined(R__WIN32)
650  // Command for opening a browser on Windows.
651  TString cWindows("start ");
652  cWindows.Append(url);
653  gSystem->Exec(cWindows);
654 #else
655  // Command for opening a browser in Linux.
656  TString cLinux("xdg-open ");
657  // For Linux we check if the DISPLAY is set.
658  if (gSystem->Getenv("DISPLAY")) {
659  // If the DISPLAY is set it will open the browser.
660  cLinux.Append(url);
661  gSystem->Exec(cLinux);
662  } else {
663  // Else the user will have a warning and the URL in the terminal.
664  Warning("OpenInBrowser", "The $DISPLAY is not set! Please open (e.g. Ctrl-click) %s\n", url.Data());
665  }
666 #endif
667 }
668 
669 namespace {
670 enum EUrl { kURLforClass, kURLforNameSpace, kURLforStruct };
671 ////////////////////////////////////////////////////////////////////////////////
672 /// The function generates a URL address for class or namespace (scopeName).
673 /// This is the URL to the online reference guide, generated by Doxygen.
674 /// With the enumeration "EUrl" we pick which case we need - the one for
675 /// class (kURLforClass) or the one for namespace (kURLforNameSpace).
676 ///
677 /// \param[in] scopeName the name of the class or the namespace
678 /// \param[in] scopeType the enumerator for class or namespace
679 
680 static TString UrlGenerator(TString scopeName, EUrl scopeType)
681 {
682  // We start the URL with a static part, the same for all scopes and members.
683  TString url = "https://root.cern/doc/";
684  // Then we check the ROOT version used.
685  TPRegexp re4(R"(.*/v(\d)-(\d\d)-00-patches)");
686  const char *branchName = gROOT->GetGitBranch();
687  TObjArray *objarr = re4.MatchS(branchName);
688  TString version;
689  // We extract the correct version name for the URL.
690  if (objarr && objarr->GetEntries() == 3) {
691  // We have a valid version of ROOT and we will extract the correct name for the URL.
692  version = ((TObjString *)objarr->At(1))->GetString() + ((TObjString *)objarr->At(2))->GetString();
693  } else {
694  // If it's not a supported version, we will go to "master" branch.
695  version = "master";
696  }
697  delete objarr;
698  url.Append(version);
699  url.Append("/");
700  // We will replace all "::" with "_1_1" and all "_" with "__" in the
701  // classes definitions, due to Doxygen syntax requirements.
702  scopeName.ReplaceAll("_", "__");
703  scopeName.ReplaceAll("::", "_1_1");
704  // We build the URL for the correct scope type and name.
705  if (scopeType == kURLforClass) {
706  url.Append("class");
707  } else if (scopeType == kURLforStruct) {
708  url.Append("struct");
709  } else {
710  url.Append("namespace");
711  }
712  url.Append(scopeName);
713  url.Append(".html");
714  return url;
715 }
716 } // namespace
717 
718 namespace {
719 ////////////////////////////////////////////////////////////////////////////////
720 /// The function returns a TString with the arguments of a method from the
721 /// scope (scopeName), but modified with respect to Doxygen syntax - spacing
722 /// around special symbols and adding the missing scopes ("std::").
723 /// "FormatMethodArgsForDoxygen" works for functions defined inside namespaces
724 /// as well. We avoid looking up twice for the TFunction by passing "func".
725 ///
726 /// \param[in] scopeName the name of the class/namespace/struct
727 /// \param[in] func pointer to the method
728 
729 static TString FormatMethodArgsForDoxygen(const TString &scopeName, TFunction *func)
730 {
731  // With "GetSignature" we get the arguments of the method and put them in a TString.
732  TString methodArguments = func->GetSignature();
733  // "methodArguments" is modified with respect of Doxygen requirements.
734  methodArguments.ReplaceAll(" = ", "=");
735  methodArguments.ReplaceAll("* ", " *");
736  methodArguments.ReplaceAll("*=", " *=");
737  methodArguments.ReplaceAll("*)", " *)");
738  methodArguments.ReplaceAll("*,", " *,");
739  methodArguments.ReplaceAll("*& ", " *&");
740  methodArguments.ReplaceAll("& ", " &");
741  // TODO: prepend "std::" to all stdlib classes!
742  methodArguments.ReplaceAll("ostream", "std::ostream");
743  methodArguments.ReplaceAll("istream", "std::istream");
744  methodArguments.ReplaceAll("map", "std::map");
745  methodArguments.ReplaceAll("vector", "std::vector");
746  // We need to replace the "currentClass::foo" with "foo" in the arguments.
747  // TODO: protect the global functions.
748  TString scopeNameRE("\\b");
749  scopeNameRE.Append(scopeName);
750  scopeNameRE.Append("::\\b");
751  TPRegexp argFix(scopeNameRE);
752  argFix.Substitute(methodArguments, "");
753  return methodArguments;
754 }
755 } // namespace
756 
757 namespace {
758 ////////////////////////////////////////////////////////////////////////////////
759 /// The function checks if a member function of a scope is defined as inline.
760 /// If so, it also checks if it is virtual. Then the return type of "func" is
761 /// modified for the need of Doxygen and with respect to the function
762 /// definition. We pass pointer to the method (func) to not re-do the
763 /// TFunction lookup.
764 ///
765 /// \param[in] scopeName the name of the class/namespace/struct
766 /// \param[in] func pointer to the method
767 
768 static TString FormatReturnTypeForDoxygen(const TString &scopeName, TFunction *func)
769 {
770  // We put the return type of "func" in a TString "returnType".
771  TString returnType = func->GetReturnTypeName();
772  // If the return type is a type nested in the current class, it will appear scoped (Class::Enumeration).
773  // Below we make sure to remove the current class, because the syntax of Doxygen requires it.
774  TString scopeNameRE("\\b");
775  scopeNameRE.Append(scopeName);
776  scopeNameRE.Append("::\\b");
777  TPRegexp returnFix(scopeNameRE);
778  returnFix.Substitute(returnType, "");
779  // We check is if the method is defined as inline.
780  if (func->ExtraProperty() & kIsInlined) {
781  // We check if the function is defined as virtual.
782  if (func->Property() & kIsVirtual) {
783  // If the function is virtual, we append "virtual" before the return type.
784  returnType.Prepend("virtual ");
785  }
786  returnType.ReplaceAll(" *", "*");
787  } else {
788  // If the function is not inline we only change the spacing in "returnType"
789  returnType.ReplaceAll("*", " *");
790  }
791  // In any case (with no respect to virtual/inline check) we need to change
792  // the return type as following.
793  // TODO: prepend "std::" to all stdlib classes!
794  returnType.ReplaceAll("istream", "std::istream");
795  returnType.ReplaceAll("ostream", "std::ostream");
796  returnType.ReplaceAll("map", "std::map");
797  returnType.ReplaceAll("vector", "std::vector");
798  returnType.ReplaceAll("&", " &");
799  return returnType;
800 }
801 } // namespace
802 
803 namespace {
804 ////////////////////////////////////////////////////////////////////////////////
805 /// The function generates a URL for "dataMemberName" defined in "scopeName".
806 /// It returns a TString with the URL used in the online reference guide,
807 /// generated with Doxygen. For data members the URL consist of 2 parts -
808 /// URL for "scopeName" and a part for "dataMemberName".
809 /// For enumerator, the URL could be separated into 3 parts - URL for
810 /// "scopeName", part for the enumeration and a part for the enumerator.
811 ///
812 /// \param[in] scopeName the name of the class/namespace/struct
813 /// \param[in] dataMemberName the name of the data member/enumerator
814 /// \param[in] dataMember pointer to the data member/enumerator
815 /// \param[in] scopeType enumerator to the scope type
816 
817 static TString
818 GetUrlForDataMember(const TString &scopeName, const TString &dataMemberName, TDataMember *dataMember, EUrl scopeType)
819 {
820  // We first check if the data member is not enumerator.
821  if (!dataMember->IsEnum()) {
822  // If we work with data members, we have to append a hashed with MD5 text, consisting of:
823  // "Type ClassName::DataMemberNameDataMemberName(arguments)".
824  // We first get the type of the data member.
825  TString md5DataMember(dataMember->GetFullTypeName());
826  md5DataMember.Append(" ");
827  // We append the scopeName and "::".
828  md5DataMember.Append(scopeName);
829  md5DataMember.Append("::");
830  // We append the dataMemberName twice.
831  md5DataMember.Append(dataMemberName);
832  md5DataMember.Append(dataMemberName);
833  // We call UrlGenerator for the scopeName.
834  TString urlForDataMember = UrlGenerator(scopeName, scopeType);
835  // Then we append "#a" and the hashed text.
836  urlForDataMember.Append("#a");
837  urlForDataMember.Append(md5DataMember.MD5());
838  return urlForDataMember;
839  }
840  // If the data member is enumerator, then we first have to check if the enumeration is anonymous.
841  // Doxygen requires different syntax for anonymous enumeration ("scopeName::@1@1").
842  // We create a TString with the name of the scope and the enumeration from which the enumerator is.
843  TString scopeEnumeration = dataMember->GetTrueTypeName();
844  TString md5EnumClass;
845  if (scopeEnumeration.Contains("(anonymous)")) {
846  // FIXME: need to investigate the numbering scheme.
847  md5EnumClass.Append(scopeName);
848  md5EnumClass.Append("::@1@1");
849  } else {
850  // If the enumeration is not anonymous we put "scopeName::Enumeration" in a TString,
851  // which will be hashed with MD5 later.
852  md5EnumClass.Append(scopeEnumeration);
853  // We extract the part after "::" (this is the enumerator name).
854  TString enumOnlyName = TClassEdit::GetUnqualifiedName(scopeEnumeration);
855  // The syntax is "Class::EnumeratorEnumerator
856  md5EnumClass.Append(enumOnlyName);
857  }
858  // The next part of the URL is hashed "@ scopeName::EnumeratorEnumerator".
859  TString md5Enumerator("@ ");
860  md5Enumerator.Append(scopeName);
861  md5Enumerator.Append("::");
862  md5Enumerator.Append(dataMemberName);
863  md5Enumerator.Append(dataMemberName);
864  // We make the URL for the "scopeName".
865  TString url = UrlGenerator(scopeName, scopeType);
866  // Then we have to append the hashed text for the enumerator.
867  url.Append("#a");
868  url.Append(md5EnumClass.MD5());
869  // We append "a" and then the next hashed text.
870  url.Append("a");
871  url.Append(md5Enumerator.MD5());
872  return url;
873 }
874 } // namespace
875 
876 namespace {
877 ////////////////////////////////////////////////////////////////////////////////
878 /// The function generates URL for enumeration. The hashed text consist of:
879 /// "Class::EnumerationEnumeration".
880 ///
881 /// \param[in] scopeName the name of the class/namespace/struct
882 /// \param[in] enumeration the name of the enumeration
883 /// \param[in] scopeType enumerator for class/namespace/struct
884 
885 static TString GetUrlForEnumeration(TString scopeName, const TString &enumeration, EUrl scopeType)
886 {
887  // The URL consists of URL for the "scopeName", "#a" and hashed as MD5 text.
888  // The text is "Class::EnumerationEnumeration.
889  TString md5Enumeration(scopeName);
890  md5Enumeration.Append("::");
891  md5Enumeration.Append(enumeration);
892  md5Enumeration.Append(enumeration);
893  // We make the URL for the scope "scopeName".
894  TString url(UrlGenerator(scopeName, scopeType));
895  // Then we have to append "#a" and the hashed text.
896  url.Append("#a");
897  url.Append(md5Enumeration.MD5());
898  return url;
899 }
900 } // namespace
901 
902 namespace {
903 enum EMethodKind { kURLforMethod, kURLforStructor };
904 ////////////////////////////////////////////////////////////////////////////////
905 /// The function generates URL for any member function (including Constructor/
906 /// Destructor) of "scopeName". Doxygen first generates the URL for the scope.
907 /// We do that with the help of "UrlGenerator". Then we append "#a" and a
908 /// hashed with MD5 text. It consists of:
909 /// "ReturnType ScopeName::MethodNameMethodName(Method arguments)".
910 /// For constructor/destructor of a class, the return type is not appended.
911 ///
912 /// \param[in] scopeName the name of the class/namespace/struct
913 /// \param[in] methodName the name of the method from the scope
914 /// \param[in] func pointer to the method
915 /// \param[in] methodType enumerator for method or constructor
916 /// \param[in] scopeType enumerator for class/namespace/struct
917 
918 static TString GetUrlForMethod(const TString &scopeName, const TString &methodName, TFunction *func,
919  EMethodKind methodType, EUrl scopeType)
920 {
921  TString md5Text;
922  if (methodType == kURLforMethod) {
923  // In the case of method, we append the return type too.
924  // "FormatReturnTypeForDoxygen" modifies the return type with respect to Doxygen's requirement.
925  md5Text.Append((FormatReturnTypeForDoxygen(scopeName, func)));
926  if (scopeType == kURLforNameSpace) {
927  // We need to append "constexpr" if we work with constexpr functions in namespaces.
928  if (func->Property() & kIsConstexpr) {
929  md5Text.Prepend("constexpr ");
930  }
931  }
932  md5Text.Append(" ");
933  }
934  // We append ScopeName::MethodNameMethodName.
935  md5Text.Append(scopeName);
936  md5Text.Append("::");
937  md5Text.Append(methodName);
938  md5Text.Append(methodName);
939  // We use "FormatMethodArgsForDoxygen" to modify the arguments of Method with respect of Doxygen.
940  md5Text.Append(FormatMethodArgsForDoxygen(scopeName, func));
941  // We generate the URL for the class/namespace/struct.
942  TString url = UrlGenerator(scopeName, scopeType);
943  url.Append("#a");
944  // We append the hashed text.
945  url.Append(md5Text.MD5());
946  return url;
947 }
948 } // namespace
949 
950 
951 ////////////////////////////////////////////////////////////////////////////////
952 /// It opens the online reference guide, generated with Doxygen, for the
953 /// chosen scope (class/namespace/struct) or member (method/function/
954 /// data member/enumeration/enumerator. If the user types incorrect value,
955 /// it will return an error or warning.
956 ///
957 /// \param[in] strippedClass the scope or scope::member
958 
960 {
961  // We check if the user is searching for a scope and if the scope exists.
962  if (TClass *clas = TClass::GetClass(strippedClass)) {
963  // We check what scope he is searching for (class/namespace/struct).
964  // Enumerators will switch between the possible cases.
965  EUrl scopeType;
966  if (clas->Property() & kIsNamespace) {
967  scopeType = kURLforNameSpace;
968  } else if (clas->Property() & kIsStruct) {
969  scopeType = kURLforStruct;
970  } else {
971  scopeType = kURLforClass;
972  }
973  // If the user search directly for a scope we open the URL for him with OpenInBrowser.
974  OpenInBrowser(UrlGenerator(strippedClass, scopeType));
975  return;
976  }
977  // Else we subtract the name of the method and remove it from the command.
978  TString memberName = TClassEdit::GetUnqualifiedName(strippedClass);
979  // Error out if "strippedClass" is un-scoped (and it's not a class, see `TClass::GetClass(strippedClass)` above).
980  // TODO: Global functions.
981  if (strippedClass == memberName) {
982  Error("OpenReferenceGuideFor", "Unknown entity \"%s\" - global variables / functions not supported yet!",
983  strippedClass.Data());
984  return;
985  }
986  // Else we remove the member name to be left with the scope.
987  TString scopeName = strippedClass(0, strippedClass.Length() - memberName.Length() - 2);
988  // We check if the scope exists in ROOT.
989  TClass *cl = TClass::GetClass(scopeName);
990  if (!cl) {
991  // That's a member of something ROOT doesn't know.
992  Warning("OpenReferenceGuideFor", "\"%s\" does not exist in ROOT!", scopeName.Data());
993  return;
994  }
995  // We have enumerators for the three available cases - class, namespace and struct.
996  EUrl scopeType;
997  if (cl->Property() & kIsNamespace) {
998  scopeType = kURLforNameSpace;
999  } else if (cl->Property() & kIsStruct) {
1000  scopeType = kURLforStruct;
1001  } else {
1002  scopeType = kURLforClass;
1003  }
1004  // If the user wants to search for a method, we take its name (memberName) and
1005  // modify it - we delete everything starting at the first "(" so the user won't have to
1006  // do it by hand when they use Tab.
1007  int bracket = memberName.First("(");
1008  if (bracket > 0) {
1009  memberName.Remove(bracket);
1010  }
1011  // We check if "memberName" is a member function of "cl" or any of its base classes.
1012  if (TFunction *func = cl->GetMethodAllAny(memberName)) {
1013  // If so we find the name of the class that it belongs to.
1014  TString baseClName = ((TMethod *)func)->GetClass()->GetName();
1015  // We define an enumerator to distinguish between structor and method.
1016  EMethodKind methodType;
1017  // We check if "memberName" is a constructor.
1018  if (baseClName == memberName) {
1019  methodType = kURLforStructor;
1020  // We check if "memberName" is a destructor.
1021  } else if (memberName[0] == '~') {
1022  methodType = kURLforStructor;
1023  // We check if "memberName" is a method.
1024  } else {
1025  methodType = kURLforMethod;
1026  }
1027  // We call "GetUrlForMethod" for the correct class and scope.
1028  OpenInBrowser(GetUrlForMethod(baseClName, memberName, func, methodType, scopeType));
1029  return;
1030  }
1031  // We check if "memberName" is an enumeration.
1032  if (cl->GetListOfEnums()->FindObject(memberName)) {
1033  // If so with OpenInBrowser we open the URL generated with GetUrlForEnumeration
1034  // with respect to the "scopeType".
1035  OpenInBrowser(GetUrlForEnumeration(scopeName, memberName, scopeType));
1036  return;
1037  }
1038 
1039  // We check if "memberName" is enumerator defined in one the base classes of "scopeName".
1040  if (auto enumerator = (TDataMember *)cl->GetListOfAllPublicDataMembers()->FindObject(memberName)) {
1041  // We find the actual scope (might be in a base) and open the URL in a browser.
1042  TString baseClName = ((TMethod *)enumerator->GetClass())->GetName();
1043  OpenInBrowser(GetUrlForDataMember(baseClName, memberName, enumerator, scopeType));
1044  return;
1045  }
1046 
1047  // Warning message will appear if the user types the function name incorrectly
1048  // or the function is not a member function of "cl" or any of its base classes.
1049  Warning("Help", "cannot find \"%s\" as member of %s or its base classes! Check %s\n", memberName.Data(),
1050  scopeName.Data(), UrlGenerator(scopeName, scopeType).Data());
1051 }
1052 
1053 ////////////////////////////////////////////////////////////////////////////////
1054 /// The function lists useful commands (".help") or opens the online reference
1055 /// guide, generated with Doxygen (".help scope" or ".help scope::member").
1056 ///
1057 /// \param[in] line command from the command line
1058 
1059 void TApplication::Help(const char *line)
1060 {
1061  // We first check if the user wants to print the help on the interpreter.
1062  TString strippedCommand = TString(line).Strip(TString::kBoth);
1063  // If the user chooses ".help" or ".?".
1064  if ((strippedCommand == ".help") || (strippedCommand == ".?")) {
1065  gInterpreter->ProcessLine(line);
1066  Printf("\nROOT special commands.");
1067  Printf("==========================================================================");
1068  Printf(" .pwd : show current directory, pad and style");
1069  Printf(" .ls : list contents of current directory");
1070  Printf(" .which [file] : shows path of macro file");
1071  Printf(" .help Class : opens the reference guide for that class");
1072  Printf(" .help Class::Member : opens the reference guide for function/member");
1073  return;
1074  } else {
1075  // If the user wants to use the extended ".help scopeName" command to access
1076  // the online reference guide, we first check if the command starts correctly.
1077  if ((!strippedCommand.BeginsWith(".help ")) && (!strippedCommand.BeginsWith(".? "))) {
1078  Error("Help", "Unknown command!");
1079  return;
1080  }
1081  // We remove the command ".help" or ".?" from the TString.
1082  if (strippedCommand.BeginsWith(".? ")) {
1083  strippedCommand.Remove(0, 3);
1084  } else {
1085  strippedCommand.Remove(0, 5);
1086  }
1087  // We strip the command line after removing ".help" or ".?".
1088  strippedCommand = strippedCommand.Strip(TString::kBoth);
1089  // We call the function what handles the extended ".help scopeName" command.
1090  OpenReferenceGuideFor(strippedCommand);
1091  }
1092 }
1093 
1094 /// Load shared libs necessary for graphics. These libraries are only
1095 /// loaded when gROOT->IsBatch() is kFALSE.
1096 
1098 {
1099  if (gROOT->IsBatch()) return;
1100 
1101  TPluginHandler *h;
1102  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPad")))
1103  if (h->LoadPlugin() == -1)
1104  return;
1105 
1106  TString name;
1107  TString title1 = "ROOT interface to ";
1108  TString nativex, title;
1109  TString nativeg = "root";
1110 
1111 #ifdef R__WIN32
1112  nativex = "win32gdk";
1113  name = "Win32gdk";
1114  title = title1 + "Win32gdk";
1115 #elif defined(R__HAS_COCOA)
1116  nativex = "quartz";
1117  name = "quartz";
1118  title = title1 + "Quartz";
1119 #else
1120  nativex = "x11";
1121  name = "X11";
1122  title = title1 + "X11";
1123 #endif
1124 
1125  TString guiBackend(gEnv->GetValue("Gui.Backend", "native"));
1126  guiBackend.ToLower();
1127  if (guiBackend == "native") {
1128  guiBackend = nativex;
1129  } else {
1130  name = guiBackend;
1131  title = title1 + guiBackend;
1132  }
1133  TString guiFactory(gEnv->GetValue("Gui.Factory", "native"));
1134  guiFactory.ToLower();
1135  if (guiFactory == "native")
1136  guiFactory = nativeg;
1137 
1138  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", guiBackend))) {
1139  if (h->LoadPlugin() == -1) {
1140  gROOT->SetBatch(kTRUE);
1141  return;
1142  }
1143  gVirtualX = (TVirtualX *) h->ExecPlugin(2, name.Data(), title.Data());
1144  fgGraphInit = kTRUE;
1145  }
1146  if ((h = gROOT->GetPluginManager()->FindHandler("TGuiFactory", guiFactory))) {
1147  if (h->LoadPlugin() == -1) {
1148  gROOT->SetBatch(kTRUE);
1149  return;
1150  }
1151  gGuiFactory = (TGuiFactory *) h->ExecPlugin(0);
1152  }
1153 }
1154 
1155 ////////////////////////////////////////////////////////////////////////////////
1156 /// Switch to batch mode.
1157 
1159 {
1160  gROOT->SetBatch();
1161  if (gGuiFactory != gBatchGuiFactory) delete gGuiFactory;
1163 #ifndef R__WIN32
1164  if (gVirtualX != gGXBatch) delete gVirtualX;
1165 #endif
1166  gVirtualX = gGXBatch;
1167 }
1168 
1169 ////////////////////////////////////////////////////////////////////////////////
1170 /// Parse the content of a line starting with ".R" (already stripped-off)
1171 /// The format is
1172 /// ~~~ {.cpp}
1173 /// [user@]host[:dir] [-l user] [-d dbg] [script]
1174 /// ~~~
1175 /// The variable 'dir' is the remote directory to be used as working dir.
1176 /// The username can be specified in two ways, "-l" having the priority
1177 /// (as in ssh).
1178 /// A 'dbg' value > 0 gives increasing verbosity.
1179 /// The last argument 'script' allows to specify an alternative script to
1180 /// be executed remotely to startup the session.
1181 
1183  TString &hostdir, TString &user,
1184  Int_t &dbg, TString &script)
1185 {
1186  if (!ln || strlen(ln) <= 0)
1187  return 0;
1188 
1189  Int_t rc = 0;
1190  Bool_t isHostDir = kTRUE;
1191  Bool_t isScript = kFALSE;
1192  Bool_t isUser = kFALSE;
1193  Bool_t isDbg = kFALSE;
1194 
1195  TString line(ln);
1196  TString tkn;
1197  Int_t from = 0;
1198  while (line.Tokenize(tkn, from, " ")) {
1199  if (tkn == "-l") {
1200  // Next is a user name
1201  isUser = kTRUE;
1202  } else if (tkn == "-d") {
1203  isDbg = kTRUE;
1204  } else if (tkn == "-close") {
1205  rc = 1;
1206  } else if (tkn.BeginsWith("-")) {
1207  ::Warning("TApplication::ParseRemoteLine","unknown option: %s", tkn.Data());
1208  } else {
1209  if (isUser) {
1210  user = tkn;
1211  isUser = kFALSE;
1212  } else if (isDbg) {
1213  dbg = tkn.Atoi();
1214  isDbg = kFALSE;
1215  } else if (isHostDir) {
1216  hostdir = tkn;
1217  hostdir.ReplaceAll(":","/");
1218  isHostDir = kFALSE;
1219  isScript = kTRUE;
1220  } else if (isScript) {
1221  // Add everything left
1222  script = tkn;
1223  script.Insert(0, "\"");
1224  script += "\"";
1225  isScript = kFALSE;
1226  break;
1227  }
1228  }
1229  }
1230 
1231  // Done
1232  return rc;
1233 }
1234 
1235 ////////////////////////////////////////////////////////////////////////////////
1236 /// Process the content of a line starting with ".R" (already stripped-off)
1237 /// The format is
1238 /// ~~~ {.cpp}
1239 /// [user@]host[:dir] [-l user] [-d dbg] [script] | [host] -close
1240 /// ~~~
1241 /// The variable 'dir' is the remote directory to be used as working dir.
1242 /// The username can be specified in two ways, "-l" having the priority
1243 /// (as in ssh).
1244 /// A 'dbg' value > 0 gives increasing verbosity.
1245 /// The last argument 'script' allows to specify an alternative script to
1246 /// be executed remotely to startup the session.
1247 
1249 {
1250  if (!line) return 0;
1251 
1252  if (!strncmp(line, "-?", 2) || !strncmp(line, "-h", 2) ||
1253  !strncmp(line, "--help", 6)) {
1254  Info("ProcessRemote", "remote session help:");
1255  Printf(".R [user@]host[:dir] [-l user] [-d dbg] [[<]script] | [host] -close");
1256  Printf("Create a ROOT session on the specified remote host.");
1257  Printf("The variable \"dir\" is the remote directory to be used as working dir.");
1258  Printf("The username can be specified in two ways, \"-l\" having the priority");
1259  Printf("(as in ssh). A \"dbg\" value > 0 gives increasing verbosity.");
1260  Printf("The last argument \"script\" allows to specify an alternative script to");
1261  Printf("be executed remotely to startup the session, \"roots\" being");
1262  Printf("the default. If the script is preceded by a \"<\" the script will be");
1263  Printf("sourced, after which \"roots\" is executed. The sourced script can be ");
1264  Printf("used to change the PATH and other variables, allowing an alternative");
1265  Printf("\"roots\" script to be found.");
1266  Printf("To close down a session do \".R host -close\".");
1267  Printf("To switch between sessions do \".R host\", to switch to the local");
1268  Printf("session do \".R\".");
1269  Printf("To list all open sessions do \"gApplication->GetApplications()->Print()\".");
1270  return 0;
1271  }
1272 
1273  TString hostdir, user, script;
1274  Int_t dbg = 0;
1275  Int_t rc = ParseRemoteLine(line, hostdir, user, dbg, script);
1276  if (hostdir.Length() <= 0) {
1277  // Close the remote application if required
1278  if (rc == 1) {
1280  delete fAppRemote;
1281  }
1282  // Return to local run
1283  fAppRemote = 0;
1284  // Done
1285  return 1;
1286  } else if (rc == 1) {
1287  // close an existing remote application
1288  TApplication *ap = TApplication::Open(hostdir, 0, 0);
1289  if (ap) {
1290  TApplication::Close(ap);
1291  delete ap;
1292  }
1293  }
1294  // Attach or start a remote application
1295  if (user.Length() > 0)
1296  hostdir.Insert(0,Form("%s@", user.Data()));
1297  const char *sc = (script.Length() > 0) ? script.Data() : 0;
1298  TApplication *ap = TApplication::Open(hostdir, dbg, sc);
1299  if (ap) {
1300  fAppRemote = ap;
1301  }
1302 
1303  // Done
1304  return 1;
1305 }
1306 
1307 namespace {
1308  static int PrintFile(const char* filename) {
1309  TString sFileName(filename);
1310  gSystem->ExpandPathName(sFileName);
1311  if (gSystem->AccessPathName(sFileName)) {
1312  Error("ProcessLine()", "Cannot find file %s", filename);
1313  return 1;
1314  }
1315  std::ifstream instr(sFileName);
1316  TString content;
1317  content.ReadFile(instr);
1318  Printf("%s", content.Data());
1319  return 0;
1320  }
1321  } // namespace
1322 
1323 ////////////////////////////////////////////////////////////////////////////////
1324 /// Process a single command line, either a C++ statement or an interpreter
1325 /// command starting with a ".".
1326 /// Return the return value of the command cast to a long.
1327 
1328 Long_t TApplication::ProcessLine(const char *line, Bool_t sync, Int_t *err)
1329 {
1330  if (!line || !*line) return 0;
1331 
1332  // If we are asked to go remote do it
1333  if (!strncmp(line, ".R", 2)) {
1334  Int_t n = 2;
1335  while (*(line+n) == ' ')
1336  n++;
1337  return ProcessRemote(line+n, err);
1338  }
1339 
1340  // Redirect, if requested
1343  return fAppRemote->ProcessLine(line, err);
1344  }
1345 
1346  if (!strncasecmp(line, ".qqqqqqq", 7)) {
1347  gSystem->Abort();
1348  } else if (!strncasecmp(line, ".qqqqq", 5)) {
1349  Info("ProcessLine", "Bye... (try '.qqqqqqq' if still running)");
1350  gSystem->Exit(1);
1351  } else if (!strncasecmp(line, ".exit", 4) || !strncasecmp(line, ".quit", 2)) {
1352  Terminate(0);
1353  return 0;
1354  }
1355 
1356  if (!strncmp(line, ".?", 2) || !strncmp(line, ".help", 5)) {
1357  Help(line);
1358  return 1;
1359  }
1360 
1361  if (!strncmp(line, ".demo", 5)) {
1362  if (gROOT->IsBatch()) {
1363  Error("ProcessLine", "Cannot show demos in batch mode!");
1364  return 1;
1365  }
1366  ProcessLine(".x " + TROOT::GetTutorialDir() + "/demos.C");
1367  return 0;
1368  }
1369 
1370  if (!strncmp(line, ".license", 8)) {
1371  return PrintFile(TROOT::GetDocDir() + "/LICENSE");
1372  }
1373 
1374  if (!strncmp(line, ".credits", 8)) {
1375  TString credits = TROOT::GetDocDir() + "/CREDITS";
1376  if (gSystem->AccessPathName(credits, kReadPermission))
1377  credits = TROOT::GetDocDir() + "/README/CREDITS";
1378  return PrintFile(credits);
1379  }
1380 
1381  if (!strncmp(line, ".pwd", 4)) {
1382  if (gDirectory)
1383  Printf("Current directory: %s", gDirectory->GetPath());
1384  if (gPad)
1385  Printf("Current pad: %s", gPad->GetName());
1386  if (gStyle)
1387  Printf("Current style: %s", gStyle->GetName());
1388  return 1;
1389  }
1390 
1391  if (!strncmp(line, ".ls", 3)) {
1392  const char *opt = 0;
1393  if (line[3]) opt = &line[3];
1394  if (gDirectory) gDirectory->ls(opt);
1395  return 1;
1396  }
1397 
1398  if (!strncmp(line, ".which", 6)) {
1399  char *fn = Strip(line+7);
1400  char *s = strtok(fn, "+("); // this method does not need to be reentrant
1402  if (!mac)
1403  Printf("No macro %s in path %s", s, TROOT::GetMacroPath());
1404  else
1405  Printf("%s", mac);
1406  delete [] fn;
1407  delete [] mac;
1408  return mac ? 1 : 0;
1409  }
1410 
1411  if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2)) {
1412  TString aclicMode;
1413  TString arguments;
1414  TString io;
1415  TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
1416 
1417  char *mac = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
1418  if (arguments.Length()) {
1419  Warning("ProcessLine", "argument(s) \"%s\" ignored with .%c", arguments.Data(),
1420  line[1]);
1421  }
1422  Long_t retval = 0;
1423  if (!mac)
1424  Error("ProcessLine", "macro %s not found in path %s", fname.Data(),
1426  else {
1427  TString cmd(line+1);
1428  Ssiz_t posSpace = cmd.Index(' ');
1429  if (posSpace == -1) cmd.Remove(1);
1430  else cmd.Remove(posSpace);
1431  TString tempbuf;
1432  if (sync) {
1433  tempbuf.Form(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(),io.Data());
1434  retval = gInterpreter->ProcessLineSynch(tempbuf,
1435  (TInterpreter::EErrorCode*)err);
1436  } else {
1437  tempbuf.Form(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(),io.Data());
1438  retval = gInterpreter->ProcessLine(tempbuf,
1439  (TInterpreter::EErrorCode*)err);
1440  }
1441  }
1442 
1443  delete [] mac;
1444 
1446 
1447  return retval;
1448  }
1449 
1450  if (!strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
1451  return ProcessFile(line+3, err, line[2] == 'k');
1452  }
1453 
1454  if (!strcmp(line, ".reset")) {
1455  // Do nothing, .reset disabled in CINT because too many side effects
1456  Printf("*** .reset not allowed, please use gROOT->Reset() ***");
1457  return 0;
1458 
1459 #if 0
1460  // delete the ROOT dictionary since CINT will destroy all objects
1461  // referenced by the dictionary classes (TClass et. al.)
1462  gROOT->GetListOfClasses()->Delete();
1463  // fall through
1464 #endif
1465  }
1466 
1467  if (sync)
1468  return gInterpreter->ProcessLineSynch(line, (TInterpreter::EErrorCode*)err);
1469  else
1470  return gInterpreter->ProcessLine(line, (TInterpreter::EErrorCode*)err);
1471 }
1472 
1473 ////////////////////////////////////////////////////////////////////////////////
1474 /// Process a file containing a C++ macro.
1475 
1476 Long_t TApplication::ProcessFile(const char *file, Int_t *error, Bool_t keep)
1477 {
1478  return ExecuteFile(file, error, keep);
1479 }
1480 
1481 ////////////////////////////////////////////////////////////////////////////////
1482 /// Execute a file containing a C++ macro (static method). Can be used
1483 /// while TApplication is not yet created.
1484 
1485 Long_t TApplication::ExecuteFile(const char *file, Int_t *error, Bool_t keep)
1486 {
1487  static const Int_t kBufSize = 1024;
1488 
1489  if (!file || !*file) return 0;
1490 
1491  TString aclicMode;
1492  TString arguments;
1493  TString io;
1494  TString fname = gSystem->SplitAclicMode(file, aclicMode, arguments, io);
1495 
1496  char *exnam = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
1497  if (!exnam) {
1498  ::Error("TApplication::ExecuteFile", "macro %s not found in path %s", fname.Data(),
1500  delete [] exnam;
1501  if (error)
1503  return 0;
1504  }
1505 
1506  ::std::ifstream macro(exnam, std::ios::in);
1507  if (!macro.good()) {
1508  ::Error("TApplication::ExecuteFile", "%s no such file", exnam);
1509  if (error)
1511  delete [] exnam;
1512  return 0;
1513  }
1514 
1515  char currentline[kBufSize];
1516  char dummyline[kBufSize];
1517  int tempfile = 0;
1518  int comment = 0;
1519  int ifndefc = 0;
1520  int ifdef = 0;
1521  char *s = 0;
1522  Bool_t execute = kFALSE;
1523  Long_t retval = 0;
1524 
1525  while (1) {
1526  bool res = (bool)macro.getline(currentline, kBufSize);
1527  if (macro.eof()) break;
1528  if (!res) {
1529  // Probably only read kBufSize, let's ignore the remainder of
1530  // the line.
1531  macro.clear();
1532  while (!macro.getline(dummyline, kBufSize) && !macro.eof()) {
1533  macro.clear();
1534  }
1535  }
1536  s = currentline;
1537  while (s && (*s == ' ' || *s == '\t')) s++; // strip-off leading blanks
1538 
1539  // very simple minded pre-processor parsing, only works in case macro file
1540  // starts with "#ifndef __CINT__". In that case everything till next
1541  // "#else" or "#endif" will be skipped.
1542  if (*s == '#') {
1543  char *cs = Compress(currentline);
1544  if (strstr(cs, "#ifndef__CINT__") ||
1545  strstr(cs, "#if!defined(__CINT__)"))
1546  ifndefc = 1;
1547  else if (ifndefc && (strstr(cs, "#ifdef") || strstr(cs, "#ifndef") ||
1548  strstr(cs, "#ifdefined") || strstr(cs, "#if!defined")))
1549  ifdef++;
1550  else if (ifndefc && strstr(cs, "#endif")) {
1551  if (ifdef)
1552  ifdef--;
1553  else
1554  ifndefc = 0;
1555  } else if (ifndefc && !ifdef && strstr(cs, "#else"))
1556  ifndefc = 0;
1557  delete [] cs;
1558  }
1559  if (!*s || *s == '#' || ifndefc || !strncmp(s, "//", 2)) continue;
1560 
1561  if (!comment && (!strncmp(s, ".X", 2) || !strncmp(s, ".x", 2))) {
1562  retval = ExecuteFile(s+3);
1563  execute = kTRUE;
1564  continue;
1565  }
1566 
1567  if (!strncmp(s, "/*", 2)) comment = 1;
1568  if (comment) {
1569  // handle slightly more complex cases like: /* */ /*
1570 again:
1571  s = strstr(s, "*/");
1572  if (s) {
1573  comment = 0;
1574  s += 2;
1575 
1576  while (s && (*s == ' ' || *s == '\t')) s++; // strip-off leading blanks
1577  if (!*s) continue;
1578  if (!strncmp(s, "//", 2)) continue;
1579  if (!strncmp(s, "/*", 2)) {
1580  comment = 1;
1581  goto again;
1582  }
1583  }
1584  }
1585  if (!comment && *s == '{') tempfile = 1;
1586  if (!comment) break;
1587  }
1588  macro.close();
1589 
1590  if (!execute) {
1591  TString exname = exnam;
1592  if (!tempfile) {
1593  // We have a script that does NOT contain an unnamed macro,
1594  // so we can call the script compiler on it.
1595  exname += aclicMode;
1596  }
1597  exname += arguments;
1598  exname += io;
1599 
1600  TString tempbuf;
1601  if (tempfile) {
1602  tempbuf.Form(".x %s", exname.Data());
1603  } else {
1604  tempbuf.Form(".X%s %s", keep ? "k" : " ", exname.Data());
1605  }
1606  retval = gInterpreter->ProcessLineSynch(tempbuf,(TInterpreter::EErrorCode*)error);
1607  }
1608 
1609  delete [] exnam;
1610  return retval;
1611 }
1612 
1613 ////////////////////////////////////////////////////////////////////////////////
1614 /// Main application eventloop. Calls system dependent eventloop via gSystem.
1615 
1616 void TApplication::Run(Bool_t retrn)
1617 {
1618  SetReturnFromRun(retrn);
1619 
1620  fIsRunning = kTRUE;
1621 
1622  gSystem->Run();
1623  fIsRunning = kFALSE;
1624 }
1625 
1626 ////////////////////////////////////////////////////////////////////////////////
1627 /// Set the command to be executed after the system has been idle for
1628 /// idleTimeInSec seconds. Normally called via TROOT::Idle(...).
1629 
1630 void TApplication::SetIdleTimer(UInt_t idleTimeInSec, const char *command)
1631 {
1632  if (fIdleTimer) RemoveIdleTimer();
1633  fIdleCommand = command;
1634  fIdleTimer = new TIdleTimer(idleTimeInSec*1000);
1636 }
1637 
1638 ////////////////////////////////////////////////////////////////////////////////
1639 /// Remove idle timer. Normally called via TROOT::Idle(0).
1640 
1642 {
1643  if (fIdleTimer) {
1644  // timers are removed from the gSystem timer list by their dtor
1646  }
1647 }
1648 
1649 ////////////////////////////////////////////////////////////////////////////////
1650 /// Called when system starts idleing.
1651 
1653 {
1654  if (fIdleTimer) {
1655  fIdleTimer->Reset();
1657  }
1658 }
1659 
1660 ////////////////////////////////////////////////////////////////////////////////
1661 /// Called when system stops idleing.
1662 
1664 {
1665  if (fIdleTimer)
1667 }
1668 
1669 ////////////////////////////////////////////////////////////////////////////////
1670 /// What to do when tab is pressed. Re-implemented by TRint.
1671 /// See TTabCom::Hook() for meaning of return values.
1672 
1673 Int_t TApplication::TabCompletionHook(char* /*buf*/, int* /*pLoc*/, std::ostream& /*out*/)
1674 {
1675  return -1;
1676 }
1677 
1678 
1679 ////////////////////////////////////////////////////////////////////////////////
1680 /// Terminate the application by call TSystem::Exit() unless application has
1681 /// been told to return from Run(), by a call to SetReturnFromRun().
1682 
1683 void TApplication::Terminate(Int_t status)
1684 {
1685  Emit("Terminate(Int_t)", status);
1686 
1687  if (fReturnFromRun)
1688  gSystem->ExitLoop();
1689  else {
1690  //close TMemStat
1691  if (fUseMemstat) {
1692  ProcessLine("TMemStat::Close()");
1693  fUseMemstat = kFALSE;
1694  }
1695 
1696  gSystem->Exit(status);
1697  }
1698 }
1699 
1700 ////////////////////////////////////////////////////////////////////////////////
1701 /// Emit signal when a line has been processed.
1702 
1703 void TApplication::LineProcessed(const char *line)
1704 {
1705  Emit("LineProcessed(const char*)", line);
1706 }
1707 
1708 ////////////////////////////////////////////////////////////////////////////////
1709 /// Emit signal when console keyboard key was pressed.
1710 
1712 {
1713  Emit("KeyPressed(Int_t)", key);
1714 }
1715 
1716 ////////////////////////////////////////////////////////////////////////////////
1717 /// Emit signal when return key was pressed.
1718 
1719 void TApplication::ReturnPressed(char *text )
1720 {
1721  Emit("ReturnPressed(char*)", text);
1722 }
1723 
1724 ////////////////////////////////////////////////////////////////////////////////
1725 /// Set console echo mode:
1726 ///
1727 /// - mode = kTRUE - echo input symbols
1728 /// - mode = kFALSE - noecho input symbols
1729 
1731 {
1732 }
1733 
1734 ////////////////////////////////////////////////////////////////////////////////
1735 /// Static function used to create a default application environment.
1736 
1738 {
1740  // gApplication is set at the end of 'new TApplication.
1741  if (!gApplication) {
1742  char *a = StrDup("RootApp");
1743  char *b = StrDup("-b");
1744  char *argv[2];
1745  Int_t argc = 2;
1746  argv[0] = a;
1747  argv[1] = b;
1748  new TApplication("RootApp", &argc, argv, 0, 0);
1749  if (gDebug > 0)
1750  Printf("<TApplication::CreateApplication>: "
1751  "created default TApplication");
1752  delete [] a; delete [] b;
1754  }
1755 }
1756 
1757 ////////////////////////////////////////////////////////////////////////////////
1758 /// Static function used to attach to an existing remote application
1759 /// or to start one.
1760 
1761 TApplication *TApplication::Open(const char *url,
1762  Int_t debug, const char *script)
1763 {
1764  TApplication *ap = 0;
1765  TUrl nu(url);
1766  Int_t nnew = 0;
1767 
1768  // Look among the existing ones
1769  if (fgApplications) {
1770  TIter nxa(fgApplications);
1771  while ((ap = (TApplication *) nxa())) {
1772  TString apn(ap->ApplicationName());
1773  if (apn == url) {
1774  // Found matching application
1775  return ap;
1776  } else {
1777  // Check if same machine and user
1778  TUrl au(apn);
1779  if (strlen(au.GetUser()) > 0 && strlen(nu.GetUser()) > 0 &&
1780  !strcmp(au.GetUser(), nu.GetUser())) {
1781  if (!strncmp(au.GetHost(), nu.GetHost(), strlen(nu.GetHost())))
1782  // New session on a known machine
1783  nnew++;
1784  }
1785  }
1786  }
1787  } else {
1788  ::Error("TApplication::Open", "list of applications undefined - protocol error");
1789  return ap;
1790  }
1791 
1792  // If new session on a known machine pass the number as option
1793  if (nnew > 0) {
1794  nnew++;
1795  nu.SetOptions(Form("%d", nnew));
1796  }
1797 
1798  // Instantiate the TApplication object to be run
1799  TPluginHandler *h = 0;
1800  if ((h = gROOT->GetPluginManager()->FindHandler("TApplication","remote"))) {
1801  if (h->LoadPlugin() == 0) {
1802  ap = (TApplication *) h->ExecPlugin(3, nu.GetUrl(), debug, script);
1803  } else {
1804  ::Error("TApplication::Open", "failed to load plugin for TApplicationRemote");
1805  }
1806  } else {
1807  ::Error("TApplication::Open", "failed to find plugin for TApplicationRemote");
1808  }
1809 
1810  // Add to the list
1811  if (ap && !(ap->TestBit(kInvalidObject))) {
1812  fgApplications->Add(ap);
1813  gROOT->GetListOfBrowsables()->Add(ap, ap->ApplicationName());
1814  TIter next(gROOT->GetListOfBrowsers());
1815  TBrowser *b;
1816  while ((b = (TBrowser*) next()))
1817  b->Add(ap, ap->ApplicationName());
1818  gROOT->RefreshBrowsers();
1819  } else {
1820  SafeDelete(ap);
1821  ::Error("TApplication::Open",
1822  "TApplicationRemote for %s could not be instantiated", url);
1823  }
1824 
1825  // Done
1826  return ap;
1827 }
1828 
1829 ////////////////////////////////////////////////////////////////////////////////
1830 /// Static function used to close a remote application
1831 
1833 {
1834  if (app) {
1835  app->Terminate(0);
1836  fgApplications->Remove(app);
1837  gROOT->GetListOfBrowsables()->RecursiveRemove(app);
1838  TIter next(gROOT->GetListOfBrowsers());
1839  TBrowser *b;
1840  while ((b = (TBrowser*) next()))
1841  b->RecursiveRemove(app);
1842  gROOT->RefreshBrowsers();
1843  }
1844 }
1845 
1846 ////////////////////////////////////////////////////////////////////////////////
1847 /// Show available sessions
1848 
1849 void TApplication::ls(Option_t *opt) const
1850 {
1851  if (fgApplications) {
1852  TIter nxa(fgApplications);
1853  TApplication *a = 0;
1854  while ((a = (TApplication *) nxa())) {
1855  a->Print(opt);
1856  }
1857  } else {
1858  Print(opt);
1859  }
1860 }
1861 
1862 ////////////////////////////////////////////////////////////////////////////////
1863 /// Static method returning the list of available applications
1864 
1866 {
1867  return fgApplications;
1868 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
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:1291
virtual void LoadGraphicsLibs()
Load shared libs necessary for graphics.
static const TString & GetTTFFontDir()
Get the fonts directory in the installation. Static utility function.
Definition: TROOT.cxx:3073
std::istream & ReadFile(std::istream &str)
Replace string with the contents of strm, stopping at an EOF.
Definition: Stringio.cxx:28
R__EXTERN TGuiFactory * gBatchGuiFactory
Definition: TGuiFactory.h:67
Semi-Abstract base class defining a generic interface to the underlying, low level, native graphics backend (X11, Win32, MacOS, OpenGL...).
Definition: TVirtualX.h:46
An array of TObjects.
Definition: TObjArray.h:37
virtual void KeyPressed(Int_t key)
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:862
long long Long64_t
Definition: RtypesCore.h:71
static const TString & GetTutorialDir()
Get the tutorials directory in the installation. Static utility function.
Definition: TROOT.cxx:2999
Bool_t fReturnFromRun
Definition: TApplication.h:62
static Bool_t fgGraphInit
Definition: TApplication.h:75
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:867
char * Compress(const char *str)
Remove all blanks from the string str.
Definition: TString.cxx:2504
void Reset()
Reset the timer.
Definition: TTimer.cxx:157
virtual void ls(Option_t *option="") const
The ls function lists the contents of a class on stdout.
EUrl
virtual void NotifyApplicationCreated()
Hook to tell TSystem that the TApplication object has been created.
Definition: TSystem.cxx:309
const char * GetFullTypeName() const
Get full type description of data member, e,g.: "class TDirectory*".
TLine * line
R__EXTERN void Throw(int code)
If an exception context has been set (using the TRY and RETRY macros) jump back to where it was set...
Definition: TException.cxx:27
Collectable string class.
Definition: TObjString.h:28
virtual void StartIdleing()
R__EXTERN TClassTable * gClassTable
Definition: TClassTable.h:94
const char * GetReturnTypeName() const
Get full type description of function return type, e,g.: "class TDirectory*".
Definition: TFunction.cxx:140
const char Option_t
Definition: RtypesCore.h:64
static const std::string comment("comment")
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form: ~~~ {.cpp} [path/]macro.C[+|++[k|f|g|O|c|s|d|v|-]][(args)]...
Definition: TSystem.cxx:4254
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:356
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:41
This class represents a WWW compatible URL.
Definition: TUrl.h:35
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
Bool_t IsEnum() const
Return true if data member is an enum.
R__EXTERN TStyle * gStyle
Definition: TStyle.h:410
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1393
const char * GetProtocol() const
Definition: TUrl.h:66
virtual void RemoveIdleTimer()
virtual void MakeBatch()
Switch to batch mode.
TString fIdleCommand
Definition: TApplication.h:69
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:858
const char * GetFileAndOptions() const
Return the file and its options (the string specified behind the ?).
Definition: TUrl.cxx:501
#define gROOT
Definition: TROOT.h:404
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1849
Basic string class.
Definition: TString.h:131
static void Close(TApplication *app)
#define f(i)
Definition: RSha256.hxx:104
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
int Int_t
Definition: RtypesCore.h:43
bool Bool_t
Definition: RtypesCore.h:61
virtual TTimer * RemoveTimer(TTimer *t)
Remove timer from list of system timers.
Definition: TSystem.cxx:479
static Bool_t fgGraphNeeded
Definition: TApplication.h:74
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:59
EExitOnException fExitOnException
Definition: TApplication.h:72
#define gInterpreter
Definition: TInterpreter.h:556
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1541
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:550
TString & Prepend(const char *cs)
Definition: TString.h:656
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
virtual Long_t ProcessRemote(const char *line, Int_t *error=0)
Process the content of a line starting with ".R" (already stripped-off) The format is [user@]host[:di...
Bool_t fNoLogo
Definition: TApplication.h:64
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:644
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:387
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:677
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2690
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:736
const char * GetFile() const
Definition: TUrl.h:71
null_t< F > null()
void OpenInBrowser(const TString &url)
The function generates and executes a command that loads the Doxygen URL in a browser.
TString fWorkDir
Definition: TApplication.h:68
Double_t x[n]
Definition: legend1.C:17
virtual TApplicationImp * CreateApplicationImp(const char *classname, int *argc, char **argv)
Create a batch version of TApplicationImp.
Definition: TGuiFactory.cxx:48
virtual Long_t ProcessLine(const char *line, Bool_t sync=kFALSE, Int_t *error=0)
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2793
static Int_t ParseRemoteLine(const char *ln, TString &hostdir, TString &user, Int_t &dbg, TString &script)
Parse the content of a line starting with ".R" (already stripped-off) The format is [user@]host[:dir]...
virtual Int_t TabCompletionHook(char *buf, int *pLoc, std::ostream &out)
virtual ~TApplication()
TApplication dtor.
virtual void SetEchoMode(Bool_t mode)
virtual void Init()
Definition: TApplication.h:113
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1658
static const TString & GetDocDir()
Get the documentation directory in the installation. Static utility function.
Definition: TROOT.cxx:2962
static void CreateApplication()
TString & Append(const char *cs)
Definition: TString.h:559
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
static TList * GetApplications()
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Definition: TFunction.cxx:183
virtual void ExitLoop()
Exit from event loop.
Definition: TSystem.cxx:390
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:499
static constexpr double s
XFontStruct * id
Definition: TGX11.cxx:108
static void CallEndOfProcessCleanups()
virtual void Run(Bool_t retrn=kFALSE)
R__EXTERN TGuiFactory * gGuiFactory
Definition: TGuiFactory.h:66
R__EXTERN Int_t gDebug
Definition: RtypesCore.h:117
void Error(const char *location, const char *msgfmt,...)
virtual void GetOptions(Int_t *argc, char **argv)
Get and handle command line options.
void EnableImplicitMT(UInt_t numthreads=0)
Enable ROOT&#39;s implicit multi-threading for all objects and methods that provide an internal paralleli...
Definition: TROOT.cxx:524
virtual Bool_t Notify()
Notify when timer times out.
Definition: TTimer.cxx:143
A doubly linked list.
Definition: TList.h:44
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
virtual void Open()
Definition: TApplication.h:128
R__EXTERN TVirtualX * gGXBatch
Definition: TVirtualX.h:341
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3885
Bool_t fIsRunning
Window system specific application implementation.
Definition: TApplication.h:61
TObjArray * fFiles
Definition: TApplication.h:67
void ClearInputFiles()
Clear list containing macro files passed as program arguments.
virtual const char * ApplicationName() const
Definition: TApplication.h:124
static void NeedGraphicsLibs()
Static method.
R__EXTERN TSystem * gSystem
Definition: TSystem.h:556
if object ctor succeeded but object should not be used
Definition: TObject.h:68
auto * a
Definition: textangle.C:12
static Long_t ExecuteFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
virtual void ReturnPressed(char *text)
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:821
void SetScreenFactor(Float_t factor=1)
Definition: TStyle.h:301
static constexpr double ms
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
unsigned int UInt_t
Definition: RtypesCore.h:44
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:888
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:405
TString MD5() const
Return the MD5 digest for this string, in a string representation.
Definition: TString.cxx:901
Bool_t fUseMemstat
Definition: TApplication.h:66
TApplicationImp * fAppImp
Definition: TApplication.h:60
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1106
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:51
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:651
char * Strip(const char *str, char c=' ')
Strip leading and trailing c (blanks by default) from a string.
Definition: TString.cxx:2454
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:722
TApplication * fAppRemote
Definition: TApplication.h:81
TString & String()
Definition: TObjString.h:48
#define gVirtualX
Definition: TVirtualX.h:338
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual void Run()
System event loop.
Definition: TSystem.cxx:341
#define h(i)
Definition: RSha256.hxx:106
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2490
virtual void Help(const char *line)
The function lists useful commands (".help") or opens the online reference guide, generated with Doxy...
const Bool_t kFALSE
Definition: RtypesCore.h:90
const char * GetTrueTypeName() const
Get full type description of data member, e,g.: "class TDirectory*".
void InitializeGraphics()
Initialize the graphics environment.
#define SafeDelete(p)
Definition: RConfig.hxx:543
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
long Long_t
Definition: RtypesCore.h:52
virtual void SetIdleTimer(UInt_t idleTimeInSec, const char *command)
int Ssiz_t
Definition: RtypesCore.h:65
R__EXTERN ExceptionContext_t * gException
Definition: TException.h:74
Bool_t fNoLog
Definition: TApplication.h:63
void OpenReferenceGuideFor(const TString &strippedClass)
It opens the online reference guide, generated with Doxygen, for the chosen scope (class/namespace/st...
#define ClassImp(name)
Definition: Rtypes.h:361
void EnableThreadSafety()
Enables the global mutex to make ROOT thread safe/aware.
Definition: TROOT.cxx:493
void Printf(const char *fmt,...)
TText * text
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
const char * GetIdleCommand() const
Definition: TApplication.h:119
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
TTimer(const TTimer &)
Double_t y[n]
Definition: legend1.C:17
char ** Argv() const
Definition: TApplication.h:137
virtual void SetProgname(const char *name)
Set the application name (from command line, argv[0]) and copy it in gProgName.
Definition: TSystem.cxx:220
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
#define R__LOCKGUARD(mutex)
virtual Long_t ProcessFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2923
TTimer * fIdleTimer
Definition: TApplication.h:70
virtual void Terminate(Int_t status=0)
bool EndsWith(const std::string &theString, const std::string &theSubstring)
char ** fArgv
Definition: TApplication.h:59
Bool_t IsNull() const
Definition: TString.h:402
Long_t ExtraProperty() const
Get property description word. For meaning of bits see EProperty.
Definition: TFunction.cxx:191
EMethodKind
EExitOnException ExitOnException(EExitOnException opt=kExit)
Set the exit on exception option.
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:28
This ABC is a factory for GUI components.
Definition: TGuiFactory.h:42
virtual void HandleIdleTimer()
Handle idle timeout.
virtual void HandleException(Int_t sig)
Handle exceptions (kSigBus, kSigSegmentationViolation, kSigIllegalInstruction and kSigFloatingExcepti...
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in &#39;original&#39;.
Definition: TClassEdit.cxx:894
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition: TSystem.cxx:469
Definition: file.py:1
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition: TSystem.cxx:714
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
TApplication * gApplication
#define gPad
Definition: TVirtualPad.h:287
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:523
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1921
static void ShutDown()
Shut down ROOT.
Definition: TROOT.cxx:3020
void Add(TObject *obj)
Definition: TObjArray.h:74
#define gDirectory
Definition: TDirectory.h:236
static void InitializeColors()
Initialize colors used by the TCanvas based graphics (via TColor objects).
Definition: TColor.cxx:1083
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition: TQObject.h:164
void ResetBit(UInt_t f)
Definition: TObject.h:171
This class creates the ROOT Application Environment that interfaces to the windowing system eventloop...
Definition: TApplication.h:39
Bool_t fQuit
Definition: TApplication.h:65
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1269
static TList * fgApplications
Definition: TApplication.h:83
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:916
void SetReturnFromRun(Bool_t ret)
Definition: TApplication.h:150
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
const Bool_t kTRUE
Definition: RtypesCore.h:89
const Int_t n
Definition: legend1.C:16
char name[80]
Definition: TGX11.cxx:109
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:874
const char * GetSignature()
Return signature of function.
Definition: TFunction.cxx:115
virtual void LineProcessed(const char *line)
const char * Data() const
Definition: TString.h:364
TApplication()
Default ctor. Can be used by classes deriving from TApplication.
virtual void StopIdleing()