Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TApplication.cxx
Go to the documentation of this file.
1// @(#)root/base:$Id$
2// Author: Fons Rademakers 22/12/95
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TApplication
13\ingroup Base
14
15This class creates the ROOT Application Environment that interfaces
16to the windowing system eventloop and eventhandlers.
17This class must be instantiated exactly once in any given
18application. Normally the specific application class inherits from
19TApplication (see TRint).
20*/
21
22#include "RConfigure.h"
23#include "TApplication.h"
24#include "TException.h"
25#include "TGuiFactory.h"
26#include "TVirtualX.h"
27#include "TROOT.h"
28#include "TSystem.h"
29#include "TString.h"
30#include "TError.h"
31#include "TObjArray.h"
32#include "TObjString.h"
33#include "TTimer.h"
34#include "TInterpreter.h"
35#include "TStyle.h"
36#include "TVirtualPad.h"
37#include "TEnv.h"
38#include "TColor.h"
39#include "TPluginManager.h"
40#include "TClassTable.h"
41#include "TBrowser.h"
42#include "TUrl.h"
43#include "TVirtualMutex.h"
44#include "TClassEdit.h"
45#include "TMethod.h"
46#include "TDataMember.h"
47#include "TApplicationCommandLineOptionsHelp.h"
48#include "TPRegexp.h"
49#include <cstdlib>
50#include <iostream>
51#include <fstream>
52
56TList *TApplication::fgApplications = nullptr; // List of available applications
57
58////////////////////////////////////////////////////////////////////////////////
59
60class TIdleTimer : public TTimer {
61public:
63 Bool_t Notify() override;
64};
65
66////////////////////////////////////////////////////////////////////////////////
67/// Notify handler.
68
75
76
77
79{
80 // Insure that the files, canvases and sockets are closed.
81
82 // If we get here, the tear down has started. We have no way to know what
83 // has or has not yet been done. In particular on Ubuntu, this was called
84 // after the function static in TSystem.cxx has been destructed. So we
85 // set gROOT in its end-of-life mode which prevents executing code, like
86 // autoloading libraries (!) that is pointless ...
87 if (gROOT) {
88 gROOT->SetBit(kInvalidObject);
89 gROOT->EndOfProcessCleanups();
90 }
91}
92
93////////////////////////////////////////////////////////////////////////////////
94/// Default ctor. Can be used by classes deriving from TApplication.
95
97 fArgc(0), fArgv(nullptr), fAppImp(nullptr), fIsRunning(kFALSE), fReturnFromRun(kFALSE),
98 fNoLog(kFALSE), fNoLogo(kFALSE), fQuit(kFALSE),
99 fFiles(nullptr), fIdleTimer(nullptr), fSigHandler(nullptr), fExitOnException(kDontExit),
100 fAppRemote(nullptr)
101{
103}
104
105////////////////////////////////////////////////////////////////////////////////
106/// Create an application environment. The application environment
107/// provides an interface to the graphics system and eventloop
108/// (be it X, Windows, macOS or BeOS). After creating the application
109/// object start the eventloop by calling its Run() method. The command
110/// line options recognized by TApplication are described in the GetOptions()
111/// method. The recognized options are removed from the argument array.
112/// The original list of argument options can be retrieved via the Argc()
113/// and Argv() methods. The "options" and "numOptions" arguments are not used,
114/// except if you want to by-pass the argv processing by GetOptions()
115/// in which case you should specify numOptions<0. All options will
116/// still be available via the Argv() method for later use.
117
119 void * /*options*/, Int_t numOptions) :
120 fArgc(0), fArgv(nullptr), fAppImp(nullptr), fIsRunning(kFALSE), fReturnFromRun(kFALSE),
121 fNoLog(kFALSE), fNoLogo(kFALSE), fQuit(kFALSE),
122 fFiles(nullptr), fIdleTimer(nullptr), fSigHandler(nullptr), fExitOnException(kDontExit),
123 fAppRemote(nullptr)
124{
126
127 // Create the list of applications the first time
128 if (!fgApplications)
129 fgApplications = new TList;
130
131 // Add the new TApplication early, so that the destructor of the
132 // default TApplication (if it is called in the block of code below)
133 // will not destroy the files, socket or TColor that have already been
134 // created.
135 fgApplications->Add(this);
136
138 // allow default TApplication to be replaced by a "real" TApplication
139 delete gApplication;
140 gApplication = nullptr;
141 gROOT->SetBatch(kFALSE);
143 }
144
145 if (gApplication) {
146 Error("TApplication", "only one instance of TApplication allowed");
147 fgApplications->Remove(this);
148 return;
149 }
150
151 if (!gROOT)
152 ::Fatal("TApplication::TApplication", "ROOT system not initialized");
153
154 if (!gSystem)
155 ::Fatal("TApplication::TApplication", "gSystem not initialized");
156
158 if (!hasRegisterAtExit) {
159 // If we are the first TApplication register the atexit)
162 }
163 gROOT->SetName(appClassName);
164
165 // copy command line arguments, can be later accessed via Argc() and Argv()
166 if (argc && *argc > 0) {
167 fArgc = *argc;
168 fArgv = (char **)new char*[fArgc];
169 }
170
171 for (int i = 0; i < fArgc; i++)
172 fArgv[i] = StrDup(argv[i]);
173
174 if (numOptions >= 0)
176
177 if (fArgv)
179
180 // Tell TSystem the TApplication has been created
182
185
186 // Initialize the graphics environment
187 if (gClassTable->GetDict("TPad")) {
189 InitializeGraphics(gROOT->IsWebDisplay());
190 }
191
192 // Save current interpreter context
193 gInterpreter->SaveContext();
194 gInterpreter->SaveGlobalsContext();
195
196 // to allow user to interact with TCanvas's under WIN32
197 gROOT->SetLineHasBeenProcessed();
198
199 //Needs to be done last
200 gApplication = this;
201 gROOT->SetApplication(this);
202
203}
204
205////////////////////////////////////////////////////////////////////////////////
206/// TApplication dtor.
207
209{
210 for (int i = 0; i < fArgc; i++)
211 if (fArgv[i]) delete [] fArgv[i];
212 delete [] fArgv;
213
214 if (fgApplications)
215 fgApplications->Remove(this);
216
217 // Reduce the risk of the files or sockets being closed after the
218 // end of 'main' (or more exactly before the library start being
219 // unloaded).
220 if (fgApplications == nullptr || fgApplications->FirstLink() == nullptr ) {
222 }
223
224 // Now that all the canvases and files have been closed we can
225 // delete the implementation.
227}
228
229////////////////////////////////////////////////////////////////////////////////
230/// Static method. This method should be called from static library
231/// initializers if the library needs the low level graphics system.
232
237
238////////////////////////////////////////////////////////////////////////////////
239/// Initialize the graphics environment.
240/// If @param only_web is specified, only web-related part of graphics is loaded
241
243{
245 return;
246
247 if (!only_web) {
248 // Load the graphics related libraries
250
251 // Try to load TrueType font renderer. Only try to load if not in batch
252 // mode and Root.UseTTFonts is true and Root.TTFontPath exists. Abort silently
253 // if libttf or libGX11TTF are not found in $ROOTSYS/lib or $ROOTSYS/ttf/lib.
254 const char *ttpath = gEnv->GetValue("Root.TTFontPath",
256 char *ttfont = gSystem->Which(ttpath, "arialbd.ttf", kReadPermission);
257 // Check for use of DFSG - fonts
258 if (!ttfont)
259 ttfont = gSystem->Which(ttpath, "FreeSansBold.ttf", kReadPermission);
260
261 #if !defined(R__WIN32)
262 if (!gROOT->IsBatch() && !strcmp(gVirtualX->GetName(), "X11") &&
263 ttfont && gEnv->GetValue("Root.UseTTFonts", 1)) {
264 if (gClassTable->GetDict("TGX11TTF")) {
265 // in principle we should not have linked anything against libGX11TTF
266 // but with ACLiC this can happen, initialize TGX11TTF by hand
267 // (normally this is done by the static library initializer)
268 ProcessLine("TGX11TTF::Activate();");
269 } else {
271 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", "x11ttf")))
272 if (h->LoadPlugin() == -1)
273 Info("InitializeGraphics", "no TTF support");
274 }
275 }
276 #endif
277 delete [] ttfont;
278 }
279
280 if (!only_web || !fAppImp) {
281 // Create WM dependent application environment
282 if (fAppImp)
283 delete fAppImp;
285 if (!fAppImp) {
286 MakeBatch();
288 }
289 }
290
291 // Create the canvas colors early so they are allocated before
292 // any color table expensive bitmaps get allocated in GUI routines (like
293 // creation of XPM bitmaps).
295
296 // Hook for further initializing the WM dependent application environment
297 Init();
298
299 // Set default screen factor (if not disabled in rc file)
300 if (!only_web && gEnv->GetValue("Canvas.UseScreenFactor", 1)) {
301 Int_t x, y;
302 UInt_t w, h;
303 if (gVirtualX) {
304 gVirtualX->GetGeometry(-1, x, y, w, h);
305 if (h > 0)
306 gStyle->SetScreenFactor(0.001 * h);
307 }
308 }
309}
310
311////////////////////////////////////////////////////////////////////////////////
312/// Clear list containing macro files passed as program arguments.
313/// This method is called from TRint::Run() to ensure that the macro
314/// files are only executed the first time Run() is called.
315
317{
318 if (fFiles) {
319 fFiles->Delete();
321 }
322}
323
324////////////////////////////////////////////////////////////////////////////////
325/// Return specified argument.
326
328{
329 if (fArgv) {
330 if (index >= fArgc) {
331 Error("Argv", "index (%d) >= number of arguments (%d)", index, fArgc);
332 return nullptr;
333 }
334 return fArgv[index];
335 }
336 return nullptr;
337}
338
339////////////////////////////////////////////////////////////////////////////////
340/// Get and handle command line options. Arguments handled are removed
341/// from the argument array. See CommandLineOptionsHelp.h for options.
342
344{
345 static char null[1] = { "" };
346
347 fNoLog = kFALSE;
348 fQuit = kFALSE;
349 fFiles = nullptr;
350
351 if (!argc)
352 return;
353
354 int i, j;
355 TString pwd;
356
357 for (i = 1; i < *argc; i++) {
358 if (!strcmp(argv[i], "-?") || !strncmp(argv[i], "-h", 2) ||
359 !strncmp(argv[i], "--help", 6)) {
361 Terminate(0);
362 } else if (!strncmp(argv[i], "--version", 9)) {
363 fprintf(stderr, "ROOT Version: %s\n", gROOT->GetVersion());
364 fprintf(stderr, "Built for %s on %s\n",
366 gROOT->GetGitDate());
367
368 fprintf(stderr, "From %s@%s\n",
369 gROOT->GetGitBranch(),
370 gROOT->GetGitCommit());
371
372 Terminate(0);
373 } else if (!strcmp(argv[i], "-config")) {
374 fprintf(stderr, "ROOT ./configure options:\n%s\n", gROOT->GetConfigOptions());
375 Terminate(0);
376 } else if (!strcmp(argv[i], "-a")) {
377 fprintf(stderr, "ROOT splash screen is not visible with root.exe, use root instead.\n");
378 Terminate(0);
379 } else if (!strcmp(argv[i], "-b")) {
380 MakeBatch();
381 argv[i] = null;
382 } else if (!strcmp(argv[i], "-n")) {
383 fNoLog = kTRUE;
384 argv[i] = null;
385 } else if (!strcmp(argv[i], "-t")) {
387 // EnableImplicitMT() only enables thread safety if IMT was configured;
388 // enable thread safety even with IMT off:
390 argv[i] = null;
391 } else if (!strcmp(argv[i], "-q")) {
392 fQuit = kTRUE;
393 argv[i] = null;
394 } else if (!strcmp(argv[i], "-l")) {
395 // used by front-end program to not display splash screen
396 fNoLogo = kTRUE;
397 argv[i] = null;
398 } else if (!strcmp(argv[i], "-x")) {
400 argv[i] = null;
401 } else if (!strcmp(argv[i], "-splash")) {
402 // used when started by front-end program to signal that
403 // splash screen can be popped down (TRint::PrintLogo())
404 argv[i] = null;
405 } else if (strncmp(argv[i], "--web", 5) == 0) {
406 // the web mode is requested
407 const char *opt = argv[i] + 5;
408 argv[i] = null;
409 gROOT->SetWebDisplay((*opt == '=') ? opt + 1 : "");
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';
479 // ROOT-9959: we do not continue if we could not expand the path
480 continue;
481 }
483 // remove options and anchor to check the path
484 TString sfx = udir.GetFileAndOptions();
485 TString fln = udir.GetFile();
486 sfx.Replace(sfx.Index(fln), fln.Length(), "");
487 TString path = udir.GetFile();
488 if (strcmp(udir.GetProtocol(), "file")) {
489 path = udir.GetUrl();
490 path.Replace(path.Index(sfx), sfx.Length(), "");
491 }
492 // 'path' is the full URL without suffices (options and/or anchor)
493 if (arg) *arg = '(';
494 if (!arg && !gSystem->GetPathInfo(path.Data(), &id, &size, &flags, &modtime)) {
495 if ((flags & 2)) {
496 // if directory set it in fWorkDir
497 if (pwd == "") {
498 pwd = gSystem->WorkingDirectory();
501 argv[i] = null;
502 } else if (!strcmp(gROOT->GetName(), "Rint")) {
503 Warning("GetOptions", "only one directory argument can be specified (%s)", expandedDir.Data());
504 }
505 } else if (size > 0) {
506 // if file add to list of files to be processed
507 if (!fFiles) fFiles = new TObjArray;
508 fFiles->Add(new TObjString(path.Data()));
509 argv[i] = null;
510 } else {
511 Warning("GetOptions", "file %s has size 0, skipping", expandedDir.Data());
512 }
513 } else {
514 if (TString(udir.GetFile()).EndsWith(".root")) {
515 if (!strcmp(udir.GetProtocol(), "file")) {
516 // file ending on .root but does not exist, likely a typo
517 // warn user if plain root...
518 if (!strcmp(gROOT->GetName(), "Rint"))
519 Warning("GetOptions", "file %s not found", expandedDir.Data());
520 } else {
521 // remote file, give it the benefit of the doubt and add it to list of files
522 if (!fFiles) fFiles = new TObjArray;
523 fFiles->Add(new TObjString(argv[i]));
524 argv[i] = null;
525 }
526 } else {
529 char *mac;
530 if (!fFiles) fFiles = new TObjArray;
532 kReadPermission))) {
533 // if file add to list of files to be processed
534 fFiles->Add(new TObjString(argv[i]));
535 argv[i] = null;
536 delete [] mac;
537 } else {
538 // if file add an invalid entry to list of files to be processed
539 fFiles->Add(new TNamed("NOT FOUND!", argv[i]));
540 // only warn if we're plain root,
541 // other progs might have their own params
542 if (!strcmp(gROOT->GetName(), "Rint")) {
543 Error("GetOptions", "macro %s not found", fname.Data());
544 // Return 2 as the Python interpreter does in case the macro
545 // is not found.
546 Terminate(2);
547 }
548 }
549 }
550 }
551 }
552 // ignore unknown options
553 }
554
555 // go back to startup directory
556 if (pwd != "")
558
559 // remove handled arguments from argument array
560 j = 0;
561 for (i = 0; i < *argc; i++) {
562 if (strcmp(argv[i], "")) {
563 argv[j] = argv[i];
564 j++;
565 }
566 }
567
568 *argc = j;
569}
570
571////////////////////////////////////////////////////////////////////////////////
572/// Handle idle timeout. When this timer expires the registered idle command
573/// will be executed by this routine and a signal will be emitted.
574
576{
577 if (!fIdleCommand.IsNull())
579
580 Emit("HandleIdleTimer()");
581}
582
583////////////////////////////////////////////////////////////////////////////////
584/// Handle exceptions (kSigBus, kSigSegmentationViolation,
585/// kSigIllegalInstruction and kSigFloatingException) trapped in TSystem.
586/// Specific TApplication implementations may want something different here.
587
589{
590 if (TROOT::Initialized()) {
591 if (gException) {
592 gInterpreter->RewindDictionary();
593 gInterpreter->ClearFileBusy();
594 }
595 if (fExitOnException == kExit)
596 gSystem->Exit(128 + sig);
597 else if (fExitOnException == kAbort)
598 gSystem->Abort();
599 else
600 Throw(sig);
601 }
602 gSystem->Exit(128 + sig);
603}
604
605////////////////////////////////////////////////////////////////////////////////
606/// Set the exit on exception option. Setting this option determines what
607/// happens in HandleException() in case an exception (kSigBus,
608/// kSigSegmentationViolation, kSigIllegalInstruction or kSigFloatingException)
609/// is trapped. Choices are: kDontExit (default), kExit or kAbort.
610/// Returns the previous value.
611
618
619/////////////////////////////////////////////////////////////////////////////////
620/// The function generates and executes a command that loads the Doxygen URL in
621/// a browser. It works for Mac, Windows and Linux. In the case of Linux, the
622/// function also checks if the DISPLAY is set. If it isn't, a warning message
623/// and the URL will be displayed on the terminal.
624///
625/// \param[in] url web page to be displayed in a browser
626
628{
629 // We check what operating system the user has.
630#ifdef R__MACOSX
631 // Command for opening a browser on Mac.
632 TString cMac("open ");
633 // We generate the full command and execute it.
634 cMac.Append(url);
635 gSystem->Exec(cMac);
636#elif defined(R__WIN32)
637 // Command for opening a browser on Windows.
638 TString cWindows("start \"\" ");
639 cWindows.Append(url);
641#else
642 // Command for opening a browser in Linux.
643 TString cLinux("xdg-open ");
644 // For Linux we check if the DISPLAY is set.
645 if (gSystem->Getenv("DISPLAY")) {
646 // If the DISPLAY is set it will open the browser.
647 cLinux.Append(url);
649 } else {
650 // Else the user will have a warning and the URL in the terminal.
651 Warning("OpenInBrowser", "The $DISPLAY is not set! Please open (e.g. Ctrl-click) %s\n", url.Data());
652 return;
653 }
654#endif
655 Info("OpenInBrowser", "A new tab should have opened in your browser.");
656}
657
658namespace {
660////////////////////////////////////////////////////////////////////////////////
661/// The function generates a URL address for class or namespace (scopeName).
662/// This is the URL to the online reference guide, generated by Doxygen.
663/// With the enumeration "EUrl" we pick which case we need - the one for
664/// class (kURLforClass) or the one for namespace (kURLforNameSpace).
665///
666/// \param[in] scopeName the name of the class or the namespace
667/// \param[in] scopeType the enumerator for class or namespace
668
670{
671 // We start the URL with a static part, the same for all scopes and members.
672 TString url = "https://root.cern/doc/";
673 // Then we check the ROOT version used.
674 TPRegexp re4(R"(.*/(v\d)-(\d\d)-00-patches)");
675 const char *branchName = gROOT->GetGitBranch();
676 TObjArray *objarr = re4.MatchS(branchName);
678 // We extract the correct version name for the URL.
679 if (objarr && objarr->GetEntries() == 3) {
680 // We have a valid version of ROOT and we will extract the correct name for the URL.
681 version = ((TObjString *)objarr->At(1))->GetString() + ((TObjString *)objarr->At(2))->GetString();
682 } else {
683 // If it's not a supported version, we will go to "master" branch.
684 version = "master";
685 }
686 delete objarr;
687 url.Append(version);
688 url.Append("/");
689 // We will replace all "::" with "_1_1" and all "_" with "__" in the
690 // classes definitions, due to Doxygen syntax requirements.
691 scopeName.ReplaceAll("_", "__");
692 scopeName.ReplaceAll("::", "_1_1");
693 // We build the URL for the correct scope type and name.
694 if (scopeType == kURLforClass) {
695 url.Append("class");
696 } else if (scopeType == kURLforStruct) {
697 url.Append("struct");
698 } else {
699 url.Append("namespace");
700 }
701 url.Append(scopeName);
702 url.Append(".html");
703 return url;
704}
705} // namespace
706
707namespace {
708////////////////////////////////////////////////////////////////////////////////
709/// The function returns a TString with the arguments of a method from the
710/// scope (scopeName), but modified with respect to Doxygen syntax - spacing
711/// around special symbols and adding the missing scopes ("std::").
712/// "FormatMethodArgsForDoxygen" works for functions defined inside namespaces
713/// as well. We avoid looking up twice for the TFunction by passing "func".
714///
715/// \param[in] scopeName the name of the class/namespace/struct
716/// \param[in] func pointer to the method
717
719{
720 // With "GetSignature" we get the arguments of the method and put them in a TString.
722 // "methodArguments" is modified with respect of Doxygen requirements.
723 methodArguments.ReplaceAll(" = ", "=");
724 methodArguments.ReplaceAll("* ", " *");
725 methodArguments.ReplaceAll("*=", " *=");
726 methodArguments.ReplaceAll("*)", " *)");
727 methodArguments.ReplaceAll("*,", " *,");
728 methodArguments.ReplaceAll("*& ", " *&");
729 methodArguments.ReplaceAll("& ", " &");
730 // TODO: prepend "std::" to all stdlib classes!
731 methodArguments.ReplaceAll("ostream", "std::ostream");
732 methodArguments.ReplaceAll("istream", "std::istream");
733 methodArguments.ReplaceAll("map", "std::map");
734 methodArguments.ReplaceAll("vector", "std::vector");
735 // We need to replace the "currentClass::foo" with "foo" in the arguments.
736 // TODO: protect the global functions.
737 TString scopeNameRE("\\b");
738 scopeNameRE.Append(scopeName);
739 scopeNameRE.Append("::\\b");
741 argFix.Substitute(methodArguments, "");
742 return methodArguments;
743}
744} // namespace
745
746namespace {
747////////////////////////////////////////////////////////////////////////////////
748/// The function returns a TString with the text as an encoded url so that it
749/// can be passed to the function OpenInBrowser
750///
751/// \param[in] text the input text
752/// \return the text appropriately escaped
753
755{
756 text.ReplaceAll("\n","%0A");
757 text.ReplaceAll("#","%23");
758 text.ReplaceAll(";","%3B");
759 text.ReplaceAll("\"","%22");
760 text.ReplaceAll("`","%60");
761 text.ReplaceAll("+","%2B");
762 text.ReplaceAll("/","%2F");
763 return text;
764}
765} // namespace
766
767namespace {
768////////////////////////////////////////////////////////////////////////////////
769/// The function checks if a member function of a scope is defined as inline.
770/// If so, it also checks if it is virtual. Then the return type of "func" is
771/// modified for the need of Doxygen and with respect to the function
772/// definition. We pass pointer to the method (func) to not re-do the
773/// TFunction lookup.
774///
775/// \param[in] scopeName the name of the class/namespace/struct
776/// \param[in] func pointer to the method
777
779{
780 // We put the return type of "func" in a TString "returnType".
782 // If the return type is a type nested in the current class, it will appear scoped (Class::Enumeration).
783 // Below we make sure to remove the current class, because the syntax of Doxygen requires it.
784 TString scopeNameRE("\\b");
785 scopeNameRE.Append(scopeName);
786 scopeNameRE.Append("::\\b");
788 returnFix.Substitute(returnType, "");
789 // We check is if the method is defined as inline.
790 if (func->ExtraProperty() & kIsInlined) {
791 // We check if the function is defined as virtual.
792 if (func->Property() & kIsVirtual) {
793 // If the function is virtual, we append "virtual" before the return type.
794 returnType.Prepend("virtual ");
795 }
796 returnType.ReplaceAll(" *", "*");
797 } else {
798 // If the function is not inline we only change the spacing in "returnType"
799 returnType.ReplaceAll("*", " *");
800 }
801 // In any case (with no respect to virtual/inline check) we need to change
802 // the return type as following.
803 // TODO: prepend "std::" to all stdlib classes!
804 returnType.ReplaceAll("istream", "std::istream");
805 returnType.ReplaceAll("ostream", "std::ostream");
806 returnType.ReplaceAll("map", "std::map");
807 returnType.ReplaceAll("vector", "std::vector");
808 returnType.ReplaceAll("&", " &");
809 return returnType;
810}
811} // namespace
812
813namespace {
814////////////////////////////////////////////////////////////////////////////////
815/// The function generates a URL for "dataMemberName" defined in "scopeName".
816/// It returns a TString with the URL used in the online reference guide,
817/// generated with Doxygen. For data members the URL consist of 2 parts -
818/// URL for "scopeName" and a part for "dataMemberName".
819/// For enumerator, the URL could be separated into 3 parts - URL for
820/// "scopeName", part for the enumeration and a part for the enumerator.
821///
822/// \param[in] scopeName the name of the class/namespace/struct
823/// \param[in] dataMemberName the name of the data member/enumerator
824/// \param[in] dataMember pointer to the data member/enumerator
825/// \param[in] scopeType enumerator to the scope type
826
827static TString
829{
830 // We first check if the data member is not enumerator.
831 if (!dataMember->IsEnum()) {
832 // If we work with data members, we have to append a hashed with MD5 text, consisting of:
833 // "Type ClassName::DataMemberNameDataMemberName(arguments)".
834 // We first get the type of the data member.
835 TString md5DataMember(dataMember->GetFullTypeName());
836 md5DataMember.Append(" ");
837 // We append the scopeName and "::".
838 md5DataMember.Append(scopeName);
839 md5DataMember.Append("::");
840 // We append the dataMemberName twice.
843 // We call UrlGenerator for the scopeName.
845 // Then we append "#a" and the hashed text.
846 urlForDataMember.Append("#a");
847 urlForDataMember.Append(md5DataMember.MD5());
848 return urlForDataMember;
849 }
850 // If the data member is enumerator, then we first have to check if the enumeration is anonymous.
851 // Doxygen requires different syntax for anonymous enumeration ("scopeName::@1@1").
852 // We create a TString with the name of the scope and the enumeration from which the enumerator is.
853 TString scopeEnumeration = dataMember->GetTrueTypeName();
855 if (scopeEnumeration.Contains("(unnamed)")) {
856 // FIXME: need to investigate the numbering scheme.
857 md5EnumClass.Append(scopeName);
858 md5EnumClass.Append("::@1@1");
859 } else {
860 // If the enumeration is not anonymous we put "scopeName::Enumeration" in a TString,
861 // which will be hashed with MD5 later.
863 // We extract the part after "::" (this is the enumerator name).
865 // The syntax is "Class::EnumeratorEnumerator
867 }
868 // The next part of the URL is hashed "@ scopeName::EnumeratorEnumerator".
870 md5Enumerator.Append(scopeName);
871 md5Enumerator.Append("::");
874 // We make the URL for the "scopeName".
876 // Then we have to append the hashed text for the enumerator.
877 url.Append("#a");
878 url.Append(md5EnumClass.MD5());
879 // We append "a" and then the next hashed text.
880 url.Append("a");
881 url.Append(md5Enumerator.MD5());
882 return url;
883}
884} // namespace
885
886namespace {
887////////////////////////////////////////////////////////////////////////////////
888/// The function generates URL for enumeration. The hashed text consist of:
889/// "Class::EnumerationEnumeration".
890///
891/// \param[in] scopeName the name of the class/namespace/struct
892/// \param[in] enumeration the name of the enumeration
893/// \param[in] scopeType enumerator for class/namespace/struct
894
896{
897 // The URL consists of URL for the "scopeName", "#a" and hashed as MD5 text.
898 // The text is "Class::EnumerationEnumeration.
900 md5Enumeration.Append("::");
903 // We make the URL for the scope "scopeName".
905 // Then we have to append "#a" and the hashed text.
906 url.Append("#a");
907 url.Append(md5Enumeration.MD5());
908 return url;
909}
910} // namespace
911
912namespace {
913enum EMethodKind { kURLforMethod, kURLforStructor };
914////////////////////////////////////////////////////////////////////////////////
915/// The function generates URL for any member function (including Constructor/
916/// Destructor) of "scopeName". Doxygen first generates the URL for the scope.
917/// We do that with the help of "UrlGenerator". Then we append "#a" and a
918/// hashed with MD5 text. It consists of:
919/// "ReturnType ScopeName::MethodNameMethodName(Method arguments)".
920/// For constructor/destructor of a class, the return type is not appended.
921///
922/// \param[in] scopeName the name of the class/namespace/struct
923/// \param[in] methodName the name of the method from the scope
924/// \param[in] func pointer to the method
925/// \param[in] methodType enumerator for method or constructor
926/// \param[in] scopeType enumerator for class/namespace/struct
927
928static TString GetUrlForMethod(const TString &scopeName, const TString &methodName, TFunction *func,
929 EMethodKind methodType, EUrl scopeType)
930{
932 if (methodType == kURLforMethod) {
933 // In the case of method, we append the return type too.
934 // "FormatReturnTypeForDoxygen" modifies the return type with respect to Doxygen's requirement.
937 // We need to append "constexpr" if we work with constexpr functions in namespaces.
938 if (func->Property() & kIsConstexpr) {
939 md5Text.Prepend("constexpr ");
940 }
941 }
942 md5Text.Append(" ");
943 }
944 // We append ScopeName::MethodNameMethodName.
945 md5Text.Append(scopeName);
946 md5Text.Append("::");
947 md5Text.Append(methodName);
948 md5Text.Append(methodName);
949 // We use "FormatMethodArgsForDoxygen" to modify the arguments of Method with respect of Doxygen.
951 // We generate the URL for the class/namespace/struct.
953 url.Append("#a");
954 // We append the hashed text.
955 url.Append(md5Text.MD5());
956 return url;
957}
958} // namespace
959
960////////////////////////////////////////////////////////////////////////////////
961/// It gets the ROOT installation setup as TString
962///
963/// \return a string with several lines
964///
966{
967 std::vector<TString> lines;
968 lines.emplace_back("```");
969 lines.emplace_back(TString::Format("ROOT v%s",
970 gROOT->GetVersion()));
971 lines.emplace_back(TString::Format("Built for %s on %s", gSystem->GetBuildArch(), gROOT->GetGitDate()));
972 if (!strcmp(gROOT->GetGitBranch(), gROOT->GetGitCommit())) {
973 static const char *months[] = {"January","February","March","April","May",
974 "June","July","August","September","October",
975 "November","December"};
976 Int_t idatqq = gROOT->GetVersionDate();
977 Int_t iday = idatqq%100;
978 Int_t imonth = (idatqq/100)%100;
979 Int_t iyear = (idatqq/10000);
980
981 lines.emplace_back(TString::Format("From tag %s, %d %s %4d",
982 gROOT->GetGitBranch(),
983 iday,months[imonth-1],iyear));
984 } else {
985 // If branch and commit are identical - e.g. "v5-34-18" - then we have
986 // a release build. Else specify the git hash this build was made from.
987 lines.emplace_back(TString::Format("From %s@%s",
988 gROOT->GetGitBranch(),
989 gROOT->GetGitCommit()));
990 }
991 lines.emplace_back(TString::Format("With %s",
993 lines.emplace_back("Binary directory: "+ gROOT->GetBinDir());
994 lines.emplace_back("```");
995 TString setup = "";
996 for (auto& line : lines) {
997 setup.Append(line);
998 setup.Append('\n');
999 }
1000 setup.Chop(); // trim final `\n`
1001 return setup;
1002}
1003
1004////////////////////////////////////////////////////////////////////////////////
1005/// It opens a Forum topic in a web browser with prefilled ROOT version
1006///
1007/// \param[in] type the issue type (only bug supported right now)
1008
1010{
1011 // https://meta.discourse.org/t/how-to-create-a-post-clicking-a-link/96197
1012
1013 if (type == "bug") {
1014 //OpenInBrowser("\"https://root-forum.cern.ch/new-topic?title=topic%20title&body=topic%20body&category=category/subcategory&tags=email,planned\"");
1016R"(___
1017_Please read [tips for efficient and successful posting](https://root-forum.cern.ch/t/tips-for-efficient-and-successful-posting/28292) and [posting code](https://root-forum.cern.ch/t/posting-code-read-this-first/28293)_
1018
1019### Describe the bug
1020<!--
1021A clear and concise description of what the wrong behavior is.
1022-->
1023### Expected behavior
1024<!--
1025A clear and concise description of what you expected to happen.
1026-->
1027
1028### To Reproduce
1029<!--
1030Steps to reproduce the behavior:
10311. Your code that triggers the issue: at least a part; ideally something we can run ourselves.
10322. Don't forget to attach the required input files!
10333. How to run your code and / or build it, e.g. `root myMacro.C`, ...
1034-->
1035
1036### Setup
1037)"+GetSetup()+
1038R"(
1039<!--
1040Please specify also how you obtained ROOT, such as `dnf install` / binary download / you built it yourself.
1041-->
1042
1043### Additional context
1044<!--
1045Add any other context about the problem here.
1046-->)";
1048
1049 OpenInBrowser("\"https://root-forum.cern.ch/new-topic?category=ROOT&tags=bug&body="+report_template+"&\"");
1050 } else {
1051 Warning("OpenForumTopic", "cannot find \"%s\" as type for a Forum topic\n"
1052 "Available types are 'bug'.", type.Data());
1053 }
1054}
1055
1056////////////////////////////////////////////////////////////////////////////////
1057/// It opens a GitHub issue in a web browser with prefilled ROOT version
1058///
1059/// \param[in] type the issue type (bug, feature or improvement)
1060
1062{
1063 // https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue#creating-an-issue-from-a-url-query
1064
1065 if (type == "bug") {
1067 "\"https://github.com/root-project/root/issues/new?labels=bug&template=bug_report.yml&root-version=" +
1068 FormatHttpUrl(GetSetup()) + "\"");
1069 } else if (type == "improvement") {
1070 OpenInBrowser("\"https://github.com/root-project/root/issues/"
1071 "new?labels=improvement&template=improvement_report.yml&root-version=" +
1072 FormatHttpUrl(GetSetup()) + "\"");
1073 } else if (type == "feature") {
1075 "\"https://github.com/root-project/root/issues/new?labels=new+feature&template=feature_request.yml\"");
1076 } else {
1077 Warning("OpenGitHubIssue",
1078 "Cannot find GitHub issue type \"%s\".\n"
1079 "Available types are 'bug', 'feature' and 'improvement'.",
1080 type.Data());
1081 }
1082}
1083
1084////////////////////////////////////////////////////////////////////////////////
1085/// It opens the online reference guide, generated with Doxygen, for the
1086/// chosen scope (class/namespace/struct) or member (method/function/
1087/// data member/enumeration/enumerator. If the user types incorrect value,
1088/// it will return an error or warning.
1089///
1090/// \param[in] strippedClass the scope or scope::member
1091
1093{
1094 // We check if the user is searching for a scope and if the scope exists.
1096 // We check what scope he is searching for (class/namespace/struct).
1097 // Enumerators will switch between the possible cases.
1098 EUrl scopeType;
1099 if (clas->Property() & kIsNamespace) {
1101 } else if (clas->Property() & kIsStruct) {
1103 } else {
1105 }
1106 // If the user search directly for a scope we open the URL for him with OpenInBrowser.
1108 return;
1109 }
1110 // Else we subtract the name of the method and remove it from the command.
1112 // Error out if "strippedClass" is un-scoped (and it's not a class, see `TClass::GetClass(strippedClass)` above).
1113 // TODO: Global functions.
1114 if (strippedClass == memberName) {
1115 Error("OpenReferenceGuideFor", "Unknown entity \"%s\" - global variables / functions not supported yet!",
1116 strippedClass.Data());
1117 return;
1118 }
1119 // Else we remove the member name to be left with the scope.
1120 TString scopeName = strippedClass(0, strippedClass.Length() - memberName.Length() - 2);
1121 // We check if the scope exists in ROOT.
1123 if (!cl) {
1124 // That's a member of something ROOT doesn't know.
1125 Warning("OpenReferenceGuideFor", "\"%s\" does not exist in ROOT!", scopeName.Data());
1126 return;
1127 }
1128 // We have enumerators for the three available cases - class, namespace and struct.
1129 EUrl scopeType;
1130 if (cl->Property() & kIsNamespace) {
1132 } else if (cl->Property() & kIsStruct) {
1134 } else {
1136 }
1137 // If the user wants to search for a method, we take its name (memberName) and
1138 // modify it - we delete everything starting at the first "(" so the user won't have to
1139 // do it by hand when they use Tab.
1140 int bracket = memberName.First("(");
1141 if (bracket > 0) {
1142 memberName.Remove(bracket);
1143 }
1144 // We check if "memberName" is a member function of "cl" or any of its base classes.
1145 if (TFunction *func = cl->GetMethodAllAny(memberName)) {
1146 // If so we find the name of the class that it belongs to.
1147 TString baseClName = ((TMethod *)func)->GetClass()->GetName();
1148 // We define an enumerator to distinguish between structor and method.
1149 EMethodKind methodType;
1150 // We check if "memberName" is a constructor.
1151 if (baseClName == memberName) {
1153 // We check if "memberName" is a destructor.
1154 } else if (memberName[0] == '~') {
1156 // We check if "memberName" is a method.
1157 } else {
1159 }
1160 // We call "GetUrlForMethod" for the correct class and scope.
1162 return;
1164 // We check if "memberName" is an enumeration.
1165 if (cl->GetListOfEnums()->FindObject(memberName)) {
1166 // If so with OpenInBrowser we open the URL generated with GetUrlForEnumeration
1167 // with respect to the "scopeType".
1169 return;
1170 }
1171
1172 // We check if "memberName" is enumerator defined in one the base classes of "scopeName".
1174 // We find the actual scope (might be in a base) and open the URL in a browser.
1175 TString baseClName = ((TMethod *)enumerator->GetClass())->GetName();
1177 return;
1178 }
1179
1180 // Warning message will appear if the user types the function name incorrectly
1181 // or the function is not a member function of "cl" or any of its base classes.
1182 Warning("OpenReferenceGuideFor", "cannot find \"%s\" as member of %s or its base classes! Check %s\n", memberName.Data(),
1183 scopeName.Data(), UrlGenerator(scopeName, scopeType).Data());
1185
1186////////////////////////////////////////////////////////////////////////////////
1187/// The function (".forum <type>") submits a new post on the ROOT forum
1188/// via web browser.
1189/// \note You can use "bug" as <type>.
1190/// \param[in] line command from the command line
1191
1192void TApplication::Forum(const char *line)
1193{
1194 // We first check if the user chose a correct syntax.
1196 if (!strippedCommand.BeginsWith(".forum ")) {
1197 Error("Forum", "Unknown command! Use 'bug' after '.forum '");
1198 return;
1199 }
1200 // We remove the command ".forum" from the TString.
1201 strippedCommand.Remove(0, 7);
1202 // We strip the command line after removing ".help" or ".?".
1204
1207
1208////////////////////////////////////////////////////////////////////////////////
1209/// The function (".gh <type>") submits a new issue on GitHub via web browser.
1210/// \note You can use "bug", "feature" or "improvement" as <type>.
1211/// \param[in] line command from the command line
1212
1213void TApplication::GitHub(const char *line)
1214{
1215 // We first check if the user chose a correct syntax.
1217 if (!strippedCommand.BeginsWith(".gh ")) {
1218 Error("GitHub", "Unknown command! Use 'bug', 'feature' or 'improvement' after '.gh '");
1219 return;
1220 }
1221 // We remove the command ".gh" from the TString.
1222 strippedCommand.Remove(0, 4);
1223 // We strip the command line after removing ".help" or ".?".
1225
1227}
1228
1229////////////////////////////////////////////////////////////////////////////////
1230/// The function lists useful commands (".help") or opens the online reference
1231/// guide, generated with Doxygen (".help scope" or ".help scope::member").
1232/// \note You can use ".?" as the short version of ".help"
1233/// \param[in] line command from the command line
1234
1235void TApplication::Help(const char *line)
1236{
1237 // We first check if the user wants to print the help on the interpreter.
1239 // If the user chooses ".help" or ".?".
1240 if ((strippedCommand == ".help") || (strippedCommand == ".?")) {
1241 gInterpreter->ProcessLine(line);
1242 Printf("\n ROOT special commands.");
1243 Printf(" ==============================================================================");
1244 Printf(" .L <filename>[flags]: load the given file with optional flags like\n"
1245 " + to compile or ++ to force recompile.\n"
1246 " Type .? TSystem::CompileMacro for a list of all flags.\n"
1247 " <filename> can also be a shared library; skip flags.");
1248 Printf(" .(x|X) <filename>[flags](args) :\n"
1249 " same as .L <filename>[flags] and runs then a function\n"
1250 " with signature: ret_type filename(args).");
1251 Printf(" .credits : show credits");
1252 Printf(" .demo : launch GUI demo");
1253 Printf(" .forum bug : ask for help with a bug or crash at the ROOT forum.");
1254 Printf(" .gh [bug|feature|improvement]\n"
1255 " : submit a bug report, feature or improvement suggestion");
1256 Printf(" .help Class::Member : open reference guide for that class member (or .?).\n"
1257 " Specifying '::Member' is optional.");
1258 Printf(" .help edit : show line editing shortcuts (or .?)");
1259 Printf(" .license : show license");
1260 Printf(" .libraries : show loaded libraries");
1261 Printf(" .ls : list contents of current TDirectory");
1262 Printf(" .pwd : show current TDirectory, pad and style");
1263 Printf(" .quit (or .exit) : quit ROOT (long form of .q)");
1264 Printf(" .R [user@]host[:dir] [-l user] [-d dbg] [script] :\n"
1265 " launch process in a remote host");
1266 Printf(" .qqq : quit ROOT - mandatory");
1267 Printf(" .qqqqq : exit process immediately");
1268 Printf(" .qqqqqqq : abort process");
1269 Printf(" .which [file] : show path of macro file");
1270 Printf(" .![OS_command] : execute OS-specific shell command");
1271 Printf(" .!root -? : print ROOT usage (CLI options)");
1272 return;
1273 } else {
1274 // If the user wants to use the extended ".help scopeName" command to access
1275 // the online reference guide, we first check if the command starts correctly.
1276 if ((!strippedCommand.BeginsWith(".help ")) && (!strippedCommand.BeginsWith(".? "))) {
1277 Error("Help", "Unknown command!");
1278 return;
1279 }
1280 // We remove the command ".help" or ".?" from the TString.
1281 if (strippedCommand.BeginsWith(".? ")) {
1282 strippedCommand.Remove(0, 3);
1283 } else {
1284 strippedCommand.Remove(0, 5);
1285 }
1286 // We strip the command line after removing ".help" or ".?".
1288
1289 if (strippedCommand == "edit") {
1290 Printf("\n ROOT terminal keyboard shortcuts (GNU-readline style).");
1291 #ifdef R__MACOSX
1292 #define FOOTNOTE " *"
1293 Printf("* Some of these commands might be intercepted by macOS predefined system shortcuts.");
1294 // https://apple.stackexchange.com/questions/18043/how-can-i-make-ctrlright-left-arrow-stop-changing-desktops-in-lion
1295 #else
1296 #define FOOTNOTE ""
1297 #endif
1298 Printf(" ==============================================================================");
1299 Printf(" Arrow_Left : move cursor left [Ctrl+B]");
1300 Printf(" Arrow_Right : move cursor right [Ctrl+F] [Ctrl+G]");
1301 #ifdef R__MACOSX
1302 Printf(" Fn+Arrow_Left : move cursor to beginning of line [Ctrl+A]");
1303 #else
1304 Printf(" Home : move cursor to beginning of line [Ctrl+A]");
1305 #endif
1306 #ifdef R__MACOSX
1307 Printf(" Fn+Arrow_Right : move cursor to end of line [Ctrl+E]");
1308 #else
1309 Printf(" End : move cursor to end of line [Ctrl+E]");
1310 #endif
1311 Printf(" Ctrl+Arrow_Left : jump to previous word [Esc,B] [Alt,B]" FOOTNOTE);
1312 Printf(" Ctrl+Arrow_Right : jump to next word [Esc,F] [Alt,F]" FOOTNOTE);
1313
1314 Printf(" Backspace : delete previous character [Ctrl+H]");
1315 Printf(" Del : delete next character [Ctrl+D]");
1316 Printf(" Esc,Backspace : delete previous word [Ctrl+W] [Esc,Ctrl+H] [Alt+Backspace] [Esc,Del] [Esc,Ctrl+Del]" FOOTNOTE);// Del is 0x7F on macOS
1317 Printf(" Ctrl+Del : delete next word [Esc,D] [Alt,D]" FOOTNOTE);
1318 Printf(" Ctrl+U : cut all characters between cursor and start of line");
1319 Printf(" Ctrl+K : cut all characters between cursor and end of line");
1320
1321 Printf(" Ctrl+T : transpose characters");
1322 Printf(" Esc,C : character to upper and jump to next word");
1323 Printf(" Esc,L : word to lower case and jump to its end");
1324 Printf(" Esc,U : word to upper case and jump to its end");
1325 Printf(" Ctrl+Shift+C : copy clipboard content");
1326 Printf(" Ctrl+Shift+V : paste clipboard content [Ctrl+Y] [Alt+Y]");
1327 #ifdef R__MACOSX
1328 Printf(" Fn+Enter : toggle overwrite mode");
1329 #else
1330 Printf(" Ins : toggle overwrite mode");
1331 #endif
1333 Printf(" Ctrl+_ : undo last keypress action");
1334 Printf(" Tab : autocomplete command or print suggestions [Ctrl+I] [Esc,Tab]");
1335 Printf(" Enter : execute command [Ctrl+J] [Ctrl+M]");
1336 Printf(" Ctrl+L : clear prompt screen");
1337 Printf(" Ctrl+D : quit ROOT (if empty line)");
1338 Printf(" Ctrl+C : send kSigInt interrupt signal");
1339 Printf(" Ctrl+Z : send kSigStop pause job signal");
1340 Printf(" Ctrl+\\ : send kSigQuit quit job signal");
1341
1342 Printf(" Arrow_Down : navigate downwards in command history [Ctrl+N]");
1343 Printf(" Arrow_Up : navigate upwards in command history [Ctrl+P]");
1344 Printf(" Ctrl+R ; Ctrl+S : search command in your history by typing a string.\n"
1345 " Use Backspace if you mistyped (but not arrows).\n"
1346 " Press Ctrl+R (Ctrl+S) repeateadly to navigate matches in reverse (forward) order");
1347 Printf(" Arrow_Right : after Ctrl+R (Ctrl+S), select current match of the history search\n"
1348 " [Ctrl+O] [Enter] [Ctrl+J] [Ctrl+M] [Arrow_Left] [Esc,Esc].\n"
1349 " Use Ctrl+F or Ctrl+G to cancel search and revert original line");
1350
1351 return;
1352 }
1353 // We call the function what handles the extended ".help scopeName" command.
1355 }
1356}
1357
1358/// Load shared libs necessary for graphics. These libraries are only
1359/// loaded when gROOT->IsBatch() is kFALSE.
1360
1362{
1363 if (gROOT->IsBatch())
1364 return;
1365
1366 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualPad"))
1367 if (h->LoadPlugin() == -1)
1368 return;
1369
1370 TString name;
1371 TString title1 = "ROOT interface to ";
1372 TString nativex, title;
1373
1374#ifdef R__WIN32
1375 nativex = "win32gdk";
1376 name = "Win32gdk";
1377 title = title1 + "Win32gdk";
1378#elif defined(R__HAS_COCOA)
1379 nativex = "quartz";
1380 name = "quartz";
1381 title = title1 + "Quartz";
1382#else
1383 nativex = "x11";
1384 name = "X11";
1385 title = title1 + "X11";
1386#endif
1387
1388 TString guiBackend = gEnv->GetValue("Gui.Backend", "native");
1389 guiBackend.ToLower();
1390 if (guiBackend == "native") {
1392 } else {
1393 name = guiBackend;
1395 }
1396
1397 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualX", guiBackend)) {
1398 if (h->LoadPlugin() == -1) {
1399 gROOT->SetBatch(kTRUE);
1400 return;
1401 }
1402 gVirtualX = (TVirtualX *) h->ExecPlugin(2, name.Data(), title.Data());
1404 }
1405
1406 TString guiFactory = gEnv->GetValue("Gui.Factory", "native");
1407 guiFactory.ToLower();
1408 if (guiFactory == "native")
1409 guiFactory = "root";
1410
1411 if (auto h = gROOT->GetPluginManager()->FindHandler("TGuiFactory", guiFactory)) {
1412 if (h->LoadPlugin() == -1) {
1413 gROOT->SetBatch(kTRUE);
1414 return;
1415 }
1416 gGuiFactory = (TGuiFactory *) h->ExecPlugin(0);
1417 }
1419
1420////////////////////////////////////////////////////////////////////////////////
1421/// Switch to batch mode.
1422
1424{
1425 gROOT->SetBatch();
1428#ifndef R__WIN32
1429 if (gVirtualX != gGXBatch) delete gVirtualX;
1430#endif
1432}
1433
1434////////////////////////////////////////////////////////////////////////////////
1435/// Parse the content of a line starting with ".R" (already stripped-off)
1436/// The format is
1437/// ~~~ {.cpp}
1438/// [user@]host[:dir] [-l user] [-d dbg] [script]
1439/// ~~~
1440/// The variable 'dir' is the remote directory to be used as working dir.
1441/// The username can be specified in two ways, "-l" having the priority
1442/// (as in ssh).
1443/// A 'dbg' value > 0 gives increasing verbosity.
1444/// The last argument 'script' allows to specify an alternative script to
1445/// be executed remotely to startup the session.
1446
1448 TString &hostdir, TString &user,
1450{
1451 if (!ln || strlen(ln) <= 0)
1452 return 0;
1453
1454 Int_t rc = 0;
1459
1460 TString line(ln);
1461 TString tkn;
1462 Int_t from = 0;
1463 while (line.Tokenize(tkn, from, " ")) {
1464 if (tkn == "-l") {
1465 // Next is a user name
1466 isUser = kTRUE;
1467 } else if (tkn == "-d") {
1468 isDbg = kTRUE;
1469 } else if (tkn == "-close") {
1470 rc = 1;
1471 } else if (tkn.BeginsWith("-")) {
1472 ::Warning("TApplication::ParseRemoteLine","unknown option: %s", tkn.Data());
1473 } else {
1474 if (isUser) {
1475 user = tkn;
1476 isUser = kFALSE;
1477 } else if (isDbg) {
1478 dbg = tkn.Atoi();
1479 isDbg = kFALSE;
1480 } else if (isHostDir) {
1481 hostdir = tkn;
1482 hostdir.ReplaceAll(":","/");
1483 isHostDir = kFALSE;
1485 } else if (isScript) {
1486 // Add everything left
1487 script = tkn;
1488 script.Insert(0, "\"");
1489 script += "\"";
1490 // isScript = kFALSE; // [clang-tidy] never read
1491 break;
1492 }
1493 }
1494 }
1495
1496 // Done
1497 return rc;
1498}
1499
1500////////////////////////////////////////////////////////////////////////////////
1501/// Process the content of a line starting with ".R" (already stripped-off)
1502/// The format is
1503/// ~~~ {.cpp}
1504/// [user@]host[:dir] [-l user] [-d dbg] [script] | [host] -close
1505/// ~~~
1506/// The variable 'dir' is the remote directory to be used as working dir.
1507/// The username can be specified in two ways, "-l" having the priority
1508/// (as in ssh).
1509/// A 'dbg' value > 0 gives increasing verbosity.
1510/// The last argument 'script' allows to specify an alternative script to
1511/// be executed remotely to startup the session.
1512
1514{
1515 if (!line) return 0;
1516
1517 if (!strncmp(line, "-?", 2) || !strncmp(line, "-h", 2) ||
1518 !strncmp(line, "--help", 6)) {
1519 Info("ProcessRemote", "remote session help:");
1520 Printf(".R [user@]host[:dir] [-l user] [-d dbg] [[<]script] | [host] -close");
1521 Printf("Create a ROOT session on the specified remote host.");
1522 Printf("The variable \"dir\" is the remote directory to be used as working dir.");
1523 Printf("The username can be specified in two ways, \"-l\" having the priority");
1524 Printf("(as in ssh). A \"dbg\" value > 0 gives increasing verbosity.");
1525 Printf("The last argument \"script\" allows to specify an alternative script to");
1526 Printf("be executed remotely to startup the session, \"roots\" being");
1527 Printf("the default. If the script is preceded by a \"<\" the script will be");
1528 Printf("sourced, after which \"roots\" is executed. The sourced script can be ");
1529 Printf("used to change the PATH and other variables, allowing an alternative");
1530 Printf("\"roots\" script to be found.");
1531 Printf("To close down a session do \".R host -close\".");
1532 Printf("To switch between sessions do \".R host\", to switch to the local");
1533 Printf("session do \".R\".");
1534 Printf("To list all open sessions do \"gApplication->GetApplications()->Print()\".");
1535 return 0;
1536 }
1537
1538 TString hostdir, user, script;
1539 Int_t dbg = 0;
1541 if (hostdir.Length() <= 0) {
1542 // Close the remote application if required
1543 if (rc == 1) {
1545 delete fAppRemote;
1546 }
1547 // Return to local run
1548 fAppRemote = nullptr;
1549 // Done
1550 return 1;
1551 } else if (rc == 1) {
1552 // close an existing remote application
1553 TApplication *ap = TApplication::Open(hostdir, 0, nullptr);
1554 if (ap) {
1556 delete ap;
1557 }
1558 }
1559 // Attach or start a remote application
1560 if (user.Length() > 0)
1561 hostdir.Insert(0, TString::Format("%s@", user.Data()));
1562 const char *sc = (script.Length() > 0) ? script.Data() : nullptr;
1564 if (ap) {
1565 fAppRemote = ap;
1566 }
1567
1568 // Done
1569 return 1;
1570}
1571
1572namespace {
1573 static int PrintFile(const char* filename) {
1577 Error("ProcessLine()", "Cannot find file %s", filename);
1578 return 1;
1579 }
1580 std::ifstream instr(sFileName);
1582 content.ReadFile(instr);
1583 Printf("%s", content.Data());
1584 return 0;
1585 }
1586 } // namespace
1587
1588////////////////////////////////////////////////////////////////////////////////
1589/// Process a single command line, either a C++ statement or an interpreter
1590/// command starting with a ".".
1591/// Return the return value of the command cast to a long.
1592
1594{
1595 if (!line || !*line) return 0;
1596
1597 // If we are asked to go remote do it
1598 if (!strncmp(line, ".R", 2)) {
1599 Int_t n = 2;
1600 while (*(line+n) == ' ')
1601 n++;
1602 return ProcessRemote(line+n, err);
1603 }
1604
1605 // Redirect, if requested
1608 return fAppRemote->ProcessLine(line, err);
1609 }
1610
1611 if (!strncasecmp(line, ".qqqqqqq", 7)) {
1612 gSystem->Abort();
1613 } else if (!strncasecmp(line, ".qqqqq", 5)) {
1614 Info("ProcessLine", "Bye... (try '.qqqqqqq' if still running)");
1615 gSystem->Exit(1);
1616 } else if (!strncasecmp(line, ".exit", 4) || !strncasecmp(line, ".quit", 2)) {
1617 Terminate(0);
1618 return 0;
1619 }
1620
1621 if (!strncmp(line, ".gh", 3)) {
1622 GitHub(line);
1623 return 1;
1624 }
1625
1626 if (!strncmp(line, ".forum", 6)) {
1627 Forum(line);
1628 return 1;
1629 }
1630
1631 if (!strncmp(line, ".?", 2) || !strncmp(line, ".help", 5)) {
1632 Help(line);
1633 return 1;
1634 }
1635
1636 if (!strncmp(line, ".demo", 5)) {
1637 if (gROOT->IsBatch()) {
1638 Error("ProcessLine", "Cannot show demos in batch mode!");
1639 return 1;
1640 }
1641 ProcessLine(".x " + TROOT::GetTutorialDir() + "/demos.C");
1642 return 0;
1643 }
1644
1645 if (!strncmp(line, ".license", 8)) {
1646 return PrintFile(TROOT::GetDocDir() + "/LICENSE");
1647 }
1648
1649 if (!strncmp(line, ".credits", 8)) {
1650 TString credits = TROOT::GetDocDir() + "/CREDITS";
1652 credits = TROOT::GetDocDir() + "/README/CREDITS";
1653 return PrintFile(credits);
1654 }
1655
1656 if (!strncmp(line, ".pwd", 4)) {
1657 if (gDirectory)
1658 Printf("Current directory: %s", gDirectory->GetPath());
1659 if (gPad)
1660 Printf("Current pad: %s", gPad->GetName());
1661 if (gStyle)
1662 Printf("Current style: %s", gStyle->GetName());
1663 return 1;
1664 }
1665
1666 if (!strncmp(line, ".ls", 3)) {
1667 const char *opt = nullptr;
1668 if (line[3]) opt = &line[3];
1669 if (gDirectory) gDirectory->ls(opt);
1670 return 1;
1671 }
1672
1673 if (!strncmp(line, ".which", 6)) {
1674 char *fn = Strip(line+7);
1675 char *s = strtok(fn, "+("); // this method does not need to be reentrant
1677 if (!mac)
1678 Printf("No macro %s in path %s", s, TROOT::GetMacroPath());
1679 else
1680 Printf("%s", mac);
1681 delete [] fn;
1682 delete [] mac;
1683 return mac ? 1 : 0;
1684 }
1685
1686 if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2)) {
1687 TString aclicMode, arguments, io;
1688 TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
1689
1691 if (arguments.Length())
1692 Warning("ProcessLine", "argument(s) \"%s\" ignored with .%c", arguments.Data(), line[1]);
1693 Longptr_t retval = 0;
1694 if (!mac) {
1695 Error("ProcessLine", "macro %s not found in path %s", fname.Data(), TROOT::GetMacroPath());
1696 } else {
1697 TString cmd(line + 1);
1698 Ssiz_t posSpace = cmd.Index(' ');
1699 if (posSpace == kNPOS)
1700 cmd.Remove(1);
1701 else
1702 cmd.Remove(posSpace);
1703 auto tempbuf = TString::Format(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(), io.Data());
1704 delete[] mac;
1705 if (sync)
1706 retval = gInterpreter->ProcessLineSynch(tempbuf.Data(), (TInterpreter::EErrorCode *)err);
1707 else
1708 retval = gInterpreter->ProcessLine(tempbuf.Data(), (TInterpreter::EErrorCode *)err);
1709 }
1710
1711 InitializeGraphics(gROOT->IsWebDisplay());
1712
1713 return retval;
1714 }
1715
1716 if (!strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
1717 return ProcessFile(line+3, err, line[2] == 'k');
1718 }
1720 if (!strcmp(line, ".reset")) {
1721 // Do nothing, .reset disabled in Cling because too many side effects
1722 Printf("*** .reset not allowed, please use gROOT->Reset() ***");
1723 return 0;
1724
1725#if 0
1726 // delete the ROOT dictionary since CINT will destroy all objects
1727 // referenced by the dictionary classes (TClass et. al.)
1728 gROOT->GetListOfClasses()->Delete();
1729 // fall through
1730#endif
1731 }
1732
1733 if (!strcmp(line, ".libraries")) {
1734 // List the loaded libraries
1736 return 0;
1737 }
1738
1739 if (sync)
1740 return gInterpreter->ProcessLineSynch(line, (TInterpreter::EErrorCode*)err);
1741 else
1742 return gInterpreter->ProcessLine(line, (TInterpreter::EErrorCode*)err);
1743}
1744
1745////////////////////////////////////////////////////////////////////////////////
1746/// Process a file containing a C++ macro.
1747
1748Longptr_t TApplication::ProcessFile(const char *file, Int_t *error, Bool_t keep)
1749{
1750 return ExecuteFile(file, error, keep);
1751}
1752
1753////////////////////////////////////////////////////////////////////////////////
1754/// Execute a file containing a C++ macro (static method). Can be used
1755/// while TApplication is not yet created.
1756
1757Longptr_t TApplication::ExecuteFile(const char *file, Int_t *error, Bool_t keep)
1758{
1759 static const Int_t kBufSize = 1024;
1760
1761 if (!file || !*file) return 0;
1762
1764 TString arguments;
1765 TString io;
1766 TString fname = gSystem->SplitAclicMode(file, aclicMode, arguments, io);
1767
1769 if (!exnam) {
1770 ::Error("TApplication::ExecuteFile", "macro %s not found in path %s", fname.Data(),
1772 delete [] exnam;
1773 if (error)
1775 return 0;
1776 }
1777
1778 ::std::ifstream macro(exnam, std::ios::in);
1779 if (!macro.good()) {
1780 ::Error("TApplication::ExecuteFile", "%s no such file", exnam);
1781 if (error)
1783 delete [] exnam;
1784 return 0;
1785 }
1786
1787 char currentline[kBufSize];
1788 char dummyline[kBufSize];
1789 int tempfile = 0;
1790 int comment = 0;
1791 int ifndefc = 0;
1792 int ifdef = 0;
1793 char *s = nullptr;
1794 Bool_t execute = kFALSE;
1795 Longptr_t retval = 0;
1796
1797 while (1) {
1798 bool res = (bool)macro.getline(currentline, kBufSize);
1799 if (macro.eof()) break;
1800 if (!res) {
1801 // Probably only read kBufSize, let's ignore the remainder of
1802 // the line.
1803 macro.clear();
1804 while (!macro.getline(dummyline, kBufSize) && !macro.eof()) {
1805 macro.clear();
1806 }
1807 }
1808 s = currentline;
1809 while (s && (*s == ' ' || *s == '\t')) s++; // strip-off leading blanks
1810
1811 // very simple minded pre-processor parsing, only works in case macro file
1812 // starts with "#ifndef __CINT__". In that case everything till next
1813 // "#else" or "#endif" will be skipped.
1814 if (*s == '#') {
1815 char *cs = Compress(currentline);
1816 if (strstr(cs, "#ifndef__CINT__") ||
1817 strstr(cs, "#if!defined(__CINT__)"))
1818 ifndefc = 1;
1819 else if (ifndefc && (strstr(cs, "#ifdef") || strstr(cs, "#ifndef") ||
1820 strstr(cs, "#ifdefined") || strstr(cs, "#if!defined")))
1821 ifdef++;
1822 else if (ifndefc && strstr(cs, "#endif")) {
1823 if (ifdef)
1824 ifdef--;
1825 else
1826 ifndefc = 0;
1827 } else if (ifndefc && !ifdef && strstr(cs, "#else"))
1828 ifndefc = 0;
1829 delete [] cs;
1830 }
1831 if (!*s || *s == '#' || ifndefc || !strncmp(s, "//", 2)) continue;
1832
1833 if (!comment && (!strncmp(s, ".X", 2) || !strncmp(s, ".x", 2))) {
1834 retval = ExecuteFile(s+3);
1835 execute = kTRUE;
1836 continue;
1837 }
1838
1839 if (!strncmp(s, "/*", 2)) comment = 1;
1840 if (comment) {
1841 // handle slightly more complex cases like: /* */ /*
1842again:
1843 s = strstr(s, "*/");
1844 if (s) {
1845 comment = 0;
1846 s += 2;
1847
1848 while (s && (*s == ' ' || *s == '\t')) s++; // strip-off leading blanks
1849 if (!*s) continue;
1850 if (!strncmp(s, "//", 2)) continue;
1851 if (!strncmp(s, "/*", 2)) {
1852 comment = 1;
1853 goto again;
1854 }
1855 }
1856 }
1857 if (!comment && *s == '{') tempfile = 1;
1858 if (!comment) break;
1860 macro.close();
1861
1862 if (!execute) {
1864 if (!tempfile) {
1865 // We have a script that does NOT contain an unnamed macro,
1866 // so we can call the script compiler on it.
1867 exname += aclicMode;
1868 }
1869 exname += arguments;
1870 exname += io;
1871
1874 tempbuf.Form(".x %s", exname.Data());
1875 } else {
1876 tempbuf.Form(".X%s %s", keep ? "k" : " ", exname.Data());
1877 }
1878 retval = gInterpreter->ProcessLineSynch(tempbuf,(TInterpreter::EErrorCode*)error);
1879 }
1880
1881 delete [] exnam;
1882 return retval;
1883}
1885////////////////////////////////////////////////////////////////////////////////
1886/// Main application eventloop. Calls system dependent eventloop via gSystem.
1887
1889{
1891
1892 fIsRunning = kTRUE;
1893
1894 gSystem->Run();
1896}
1897
1898////////////////////////////////////////////////////////////////////////////////
1899/// Set the command to be executed after the system has been idle for
1900/// idleTimeInSec seconds. Normally called via TROOT::Idle(...).
1901
1903{
1908}
1909
1910////////////////////////////////////////////////////////////////////////////////
1911/// Remove idle timer. Normally called via TROOT::Idle(0).
1912
1914{
1915 if (fIdleTimer) {
1916 // timers are removed from the gSystem timer list by their dtor
1918 }
1919}
1920
1921////////////////////////////////////////////////////////////////////////////////
1922/// Called when system starts idleing.
1923
1925{
1927 fIdleTimer->Reset();
1929 }
1930}
1931
1932////////////////////////////////////////////////////////////////////////////////
1933/// Called when system stops idleing.
1934
1936{
1937 if (fIdleTimer)
1939}
1941////////////////////////////////////////////////////////////////////////////////
1942/// What to do when tab is pressed. Re-implemented by TRint.
1943/// See TTabCom::Hook() for meaning of return values.
1944
1945Int_t TApplication::TabCompletionHook(char* /*buf*/, int* /*pLoc*/, std::ostream& /*out*/)
1946{
1947 return -1;
1949
1950
1951////////////////////////////////////////////////////////////////////////////////
1952/// Terminate the application by call TSystem::Exit() unless application has
1953/// been told to return from Run(), by a call to SetReturnFromRun().
1954
1955void TApplication::Terminate(Int_t status)
1957 Emit("Terminate(Int_t)", status);
1958
1959 if (fReturnFromRun)
1960 gSystem->ExitLoop();
1961 else {
1962 gSystem->Exit(status);
1963 }
1964}
1965
1966////////////////////////////////////////////////////////////////////////////////
1967/// Emit signal when a line has been processed.
1968
1969void TApplication::LineProcessed(const char *line)
1970{
1971 Emit("LineProcessed(const char*)", line);
1972}
1973
1974////////////////////////////////////////////////////////////////////////////////
1975/// Emit signal when console keyboard key was pressed.
1976
1978{
1979 Emit("KeyPressed(Int_t)", key);
1980}
1981
1982////////////////////////////////////////////////////////////////////////////////
1983/// Emit signal when return key was pressed.
1984
1986{
1987 Emit("ReturnPressed(char*)", text);
1988}
1989
1990////////////////////////////////////////////////////////////////////////////////
1991/// Set console echo mode:
1992///
1993/// - mode = kTRUE - echo input symbols
1994/// - mode = kFALSE - noecho input symbols
1995
1997{
1999
2000////////////////////////////////////////////////////////////////////////////////
2001/// Static function used to create a default application environment.
2002
2004{
2006 // gApplication is set at the end of 'new TApplication.
2007 if (!gApplication) {
2008 char *a = StrDup("RootApp");
2009 char *b = StrDup("-b");
2010 char *argv[2];
2011 Int_t argc = 2;
2012 argv[0] = a;
2013 argv[1] = b;
2014 new TApplication("RootApp", &argc, argv, nullptr, 0);
2015 if (gDebug > 0)
2016 Printf("<TApplication::CreateApplication>: "
2017 "created default TApplication");
2018 delete [] a; delete [] b;
2020 }
2021}
2022
2023////////////////////////////////////////////////////////////////////////////////
2024/// Static function used to attach to an existing remote application
2025/// or to start one.
2026
2028 Int_t debug, const char *script)
2029{
2030 TApplication *ap = nullptr;
2031 TUrl nu(url);
2032 Int_t nnew = 0;
2033
2034 // Look among the existing ones
2035 if (fgApplications) {
2037 while ((ap = (TApplication *) nxa())) {
2038 TString apn(ap->ApplicationName());
2039 if (apn == url) {
2040 // Found matching application
2041 return ap;
2042 } else {
2043 // Check if same machine and user
2044 TUrl au(apn);
2045 if (strlen(au.GetUser()) > 0 && strlen(nu.GetUser()) > 0 &&
2046 !strcmp(au.GetUser(), nu.GetUser())) {
2047 if (!strncmp(au.GetHost(), nu.GetHost(), strlen(nu.GetHost())))
2048 // New session on a known machine
2049 nnew++;
2050 }
2051 }
2052 }
2053 } else {
2054 ::Error("TApplication::Open", "list of applications undefined - protocol error");
2055 return ap;
2056 }
2057
2058 // If new session on a known machine pass the number as option
2059 if (nnew > 0) {
2060 nnew++;
2061 nu.SetOptions(TString::Format("%d", nnew).Data());
2062 }
2063
2064 // Instantiate the TApplication object to be run
2065 TPluginHandler *h = nullptr;
2066 if ((h = gROOT->GetPluginManager()->FindHandler("TApplication","remote"))) {
2067 if (h->LoadPlugin() == 0) {
2068 ap = (TApplication *) h->ExecPlugin(3, nu.GetUrl(), debug, script);
2069 } else {
2070 ::Error("TApplication::Open", "failed to load plugin for TApplicationRemote");
2071 }
2072 } else {
2073 ::Error("TApplication::Open", "failed to find plugin for TApplicationRemote");
2074 }
2075
2076 // Add to the list
2077 if (ap && !(ap->TestBit(kInvalidObject))) {
2078 fgApplications->Add(ap);
2079 gROOT->GetListOfBrowsables()->Add(ap, ap->ApplicationName());
2080 TIter next(gROOT->GetListOfBrowsers());
2081 TBrowser *b;
2082 while ((b = (TBrowser*) next()))
2083 b->Add(ap, ap->ApplicationName());
2084 gROOT->RefreshBrowsers();
2085 } else {
2087 ::Error("TApplication::Open",
2088 "TApplicationRemote for %s could not be instantiated", url);
2089 }
2090
2091 // Done
2092 return ap;
2093}
2094
2095////////////////////////////////////////////////////////////////////////////////
2096/// Static function used to close a remote application
2097
2099{
2100 if (app) {
2101 app->Terminate(0);
2103 gROOT->GetListOfBrowsables()->RecursiveRemove(app);
2104 TIter next(gROOT->GetListOfBrowsers());
2105 TBrowser *b;
2106 while ((b = (TBrowser*) next()))
2108 gROOT->RefreshBrowsers();
2109 }
2110}
2111
2112////////////////////////////////////////////////////////////////////////////////
2113/// Show available sessions
2114
2115void TApplication::ls(Option_t *opt) const
2116{
2117 if (fgApplications) {
2119 TApplication *a = nullptr;
2120 while ((a = (TApplication *) nxa())) {
2121 a->Print(opt);
2122 }
2123 } else {
2124 Print(opt);
2125 }
2126}
2127
2128////////////////////////////////////////////////////////////////////////////////
2129/// Static method returning the list of available applications
2130
2132{
2133 return fgApplications;
2134}
#define SafeDelete(p)
Definition RConfig.hxx:533
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:89
int Ssiz_t
String size (currently int)
Definition RtypesCore.h:81
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
static void CallEndOfProcessCleanups()
#define FOOTNOTE
TApplication * gApplication
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
@ kIsInlined
@ kIsConstexpr
Definition TDictionary.h:93
@ kIsStruct
Definition TDictionary.h:66
@ kIsVirtual
Definition TDictionary.h:72
@ kIsNamespace
Definition TDictionary.h:95
#define gDirectory
Definition TDirectory.h:385
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:208
R__EXTERN ExceptionContext_t * gException
Definition TException.h:69
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.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
R__EXTERN TGuiFactory * gBatchGuiFactory
Definition TGuiFactory.h:67
R__EXTERN TGuiFactory * gGuiFactory
Definition TGuiFactory.h:66
R__EXTERN TVirtualMutex * gInterpreterMutex
#define gInterpreter
@ kInvalidObject
Definition TObject.h:377
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:627
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:411
char * Compress(const char *str)
Remove all blanks from the string str.
Definition TString.cxx:2578
char * Strip(const char *str, char c=' ')
Strip leading and trailing c (blanks by default) from a string.
Definition TString.cxx:2527
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2509
char * StrDup(const char *str)
Duplicate the string str.
Definition TString.cxx:2563
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
@ kReadPermission
Definition TSystem.h:55
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
#define R__LOCKGUARD(mutex)
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
R__EXTERN TVirtualX * gGXBatch
Definition TVirtualX.h:339
This class creates the ROOT Application Environment that interfaces to the windowing system eventloop...
EExitOnException ExitOnException(EExitOnException opt=kExit)
Set the exit on exception option.
virtual void KeyPressed(Int_t key)
Emit signal when console keyboard key was pressed.
virtual Longptr_t ProcessLine(const char *line, Bool_t sync=kFALSE, Int_t *error=nullptr)
Process a single command line, either a C++ statement or an interpreter command starting with a "....
static TList * fgApplications
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
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
void InitializeGraphics(Bool_t only_web=kFALSE)
Initialize the graphics environment.
virtual void Open()
virtual void LoadGraphicsLibs()
Load shared libs necessary for graphics.
virtual void StopIdleing()
Called when system stops idleing.
virtual void StartIdleing()
Called when system starts idleing.
virtual void Run(Bool_t retrn=kFALSE)
Main application eventloop. Calls system dependent eventloop via gSystem.
virtual ~TApplication()
TApplication dtor.
void OpenReferenceGuideFor(const TString &strippedClass)
It opens the online reference guide, generated with Doxygen, for the chosen scope (class/namespace/st...
virtual void HandleException(Int_t sig)
Handle exceptions (kSigBus, kSigSegmentationViolation, kSigIllegalInstruction and kSigFloatingExcepti...
virtual void MakeBatch()
Switch to batch mode.
void OpenGitHubIssue(const TString &type)
It opens a GitHub issue in a web browser with prefilled ROOT version.
Bool_t fReturnFromRun
virtual void Init()
TString fIdleCommand
char ** Argv() const
static Bool_t fgGraphNeeded
virtual void Terminate(Int_t status=0)
Terminate the application by call TSystem::Exit() unless application has been told to return from Run...
void OpenInBrowser(const TString &url)
The function generates and executes a command that loads the Doxygen URL in a browser.
virtual void Forum(const char *line)
The function (".forum <type>") submits a new post on the ROOT forum via web browser.
void SetReturnFromRun(Bool_t ret)
virtual Int_t TabCompletionHook(char *buf, int *pLoc, std::ostream &out)
What to do when tab is pressed.
EExitOnException fExitOnException
TObjArray * fFiles
const char * GetIdleCommand() const
TApplication()
Default ctor. Can be used by classes deriving from TApplication.
virtual Longptr_t ProcessFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Process a file containing a C++ macro.
void OpenForumTopic(const TString &type)
It opens a Forum topic in a web browser with prefilled ROOT version.
TString fWorkDir
virtual void ReturnPressed(char *text)
Emit signal when return key was pressed.
static Bool_t fgGraphInit
virtual void RemoveIdleTimer()
Remove idle timer. Normally called via TROOT::Idle(0).
virtual void SetIdleTimer(UInt_t idleTimeInSec, const char *command)
Set the command to be executed after the system has been idle for idleTimeInSec seconds.
virtual void GitHub(const char *line)
The function (".gh <type>") submits a new issue on GitHub via web browser.
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.
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
void ls(Option_t *option="") const override
Show available sessions.
TString GetSetup()
It gets the ROOT installation setup as TString.
virtual void HandleIdleTimer()
Handle idle timeout.
virtual Longptr_t ProcessRemote(const char *line, Int_t *error=nullptr)
Process the content of a line starting with ".R" (already stripped-off) The format is.
TApplication * fAppRemote
char ** fArgv
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
void RecursiveRemove(TObject *obj) override
Recursively remove obj from browser.
Definition TBrowser.cxx:427
void Add(TObject *obj, const char *name=nullptr, Int_t check=-1)
Add object with name to browser.
Definition TBrowser.cxx:302
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:84
TList * GetListOfAllPublicDataMembers(Bool_t load=kTRUE)
Returns a list of all public data members of this class and its base classes.
Definition TClass.cxx:3889
TList * GetListOfEnums(Bool_t load=kTRUE)
Return a list containing the TEnums of a class.
Definition TClass.cxx:3713
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6128
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
Definition TClass.cxx:4411
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:2973
static void InitializeColors()
Initialize colors used by the TCanvas based graphics (via TColor objects).
Definition TColor.cxx:1172
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:490
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
const char * GetSignature()
Return signature of function.
Long_t ExtraProperty() const
Get property description word. For meaning of bits see EProperty.
const char * GetReturnTypeName() const
Get full type description of function return type, e,g.: "class TDirectory*".
This ABC is a factory for GUI components.
Definition TGuiFactory.h:42
virtual TApplicationImp * CreateApplicationImp(const char *classname, int *argc, char **argv)
Create a batch version of TApplicationImp.
TIdleTimer(Long_t ms)
Bool_t Notify() override
Notify handler.
void ls(Option_t *option="") const override
List this line with its attributes.
Definition TLine.cxx:409
A doubly linked list.
Definition TList.h:38
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:575
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
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
An array of TObjects.
Definition TObjArray.h:31
void Delete(Option_t *option="") override
Remove all objects from the array AND delete all heap based objects.
void Add(TObject *obj) override
Definition TObjArray.h:68
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:457
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1099
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:655
void ResetBit(UInt_t f)
Definition TObject.h:201
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:78
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1045
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:2764
static void ShutDown()
Shut down ROOT.
Definition TROOT.cxx:3191
static const TString & GetTTFFontDir()
Get the fonts directory in the installation. Static utility function.
Definition TROOT.cxx:3244
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition TROOT.cxx:2913
static const TString & GetTutorialDir()
Get the tutorials directory in the installation. Static utility function.
Definition TROOT.cxx:3170
static const TString & GetDocDir()
Get the documentation directory in the installation. Static utility function.
Definition TROOT.cxx:3133
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2250
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition TString.cxx:1170
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:702
const char * Data() const
Definition TString.h:384
TString & Chop()
Definition TString.h:699
@ kBoth
Definition TString.h:284
Bool_t IsNull() const
Definition TString.h:422
TString & Append(const char *cs)
Definition TString.h:580
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:640
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:659
void SetScreenFactor(Float_t factor=1)
Definition TStyle.h:321
virtual void NotifyApplicationCreated()
Hook to tell TSystem that the TApplication object has been created.
Definition TSystem.cxx:309
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1285
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1676
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4282
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition TSystem.cxx:651
virtual void ListLibraries(const char *regexp="")
List the loaded shared libraries.
Definition TSystem.cxx:2096
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:1409
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:1307
virtual void Run()
System event loop.
Definition TSystem.cxx:341
virtual void ExitLoop()
Exit from event loop.
Definition TSystem.cxx:390
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition TSystem.cxx:872
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition TSystem.cxx:469
virtual const char * GetBuildCompilerVersionStr() const
Return the build compiler version identifier string.
Definition TSystem.cxx:3923
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition TSystem.cxx:725
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:881
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1559
virtual void SetProgname(const char *name)
Set the application name (from command line, argv[0]) and copy it in gProgName.
Definition TSystem.cxx:224
virtual const char * GetBuildArch() const
Return the build architecture.
Definition TSystem.cxx:3899
virtual void Abort(int code=0)
Abort the application.
Definition TSystem.cxx:734
virtual TTimer * RemoveTimer(TTimer *t)
Remove timer from list of system timers.
Definition TSystem.cxx:479
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
void Reset()
Reset the timer.
Definition TTimer.cxx:162
This class represents a WWW compatible URL.
Definition TUrl.h:33
Semi-Abstract base class defining a generic interface to the underlying, low level,...
Definition TVirtualX.h:46
TLine * line
static constexpr const char kCommandLineOptionsHelp[]
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
void EnableImplicitMT(UInt_t numthreads=0)
Enable ROOT's implicit multi-threading for all objects and methods that provide an internal paralleli...
Definition TROOT.cxx:544
void EnableThreadSafety()
Enable support for multi-threading within the ROOT code in particular, enables the global mutex to ma...
Definition TROOT.cxx:506
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.