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