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