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