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
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 "options" and "numOptions" arguments are not used,
115/// except if you want to by-pass the argv processing by GetOptions()
116/// in which case you should specify numOptions<0. All options will
117/// still be available via the Argv() method for later use.
118
120 void * /*options*/, Int_t numOptions) :
121 fArgc(0), fArgv(nullptr), fAppImp(nullptr), fIsRunning(kFALSE), fReturnFromRun(kFALSE),
122 fNoLog(kFALSE), fNoLogo(kFALSE), fQuit(kFALSE),
123 fFiles(nullptr), fIdleTimer(nullptr), fSigHandler(nullptr), fExitOnException(kDontExit),
124 fAppRemote(nullptr)
125{
127
128 // Create the list of applications the first time
129 if (!fgApplications)
130 fgApplications = new TList;
131
132 // Add the new TApplication early, so that the destructor of the
133 // default TApplication (if it is called in the block of code below)
134 // will not destroy the files, socket or TColor that have already been
135 // created.
136 fgApplications->Add(this);
137
139 // allow default TApplication to be replaced by a "real" TApplication
140 delete gApplication;
141 gApplication = nullptr;
142 gROOT->SetBatch(kFALSE);
144 }
145
146 if (gApplication) {
147 Error("TApplication", "only one instance of TApplication allowed");
148 fgApplications->Remove(this);
149 return;
150 }
151
152 if (!gROOT)
153 ::Fatal("TApplication::TApplication", "ROOT system not initialized");
154
155 if (!gSystem)
156 ::Fatal("TApplication::TApplication", "gSystem not initialized");
157
159 if (!hasRegisterAtExit) {
160 // If we are the first TApplication register the atexit)
163 }
164 gROOT->SetName(appClassName);
165
166 // copy command line arguments, can be later accessed via Argc() and Argv()
167 if (argc && *argc > 0) {
168 fArgc = *argc;
169 fArgv = (char **)new char*[fArgc];
170 }
171
172 for (int i = 0; i < fArgc; i++)
173 fArgv[i] = StrDup(argv[i]);
174
175 if (numOptions >= 0)
177
178 if (fArgv)
180
181 // Tell TSystem the TApplication has been created
183
186
187 // Initialize the graphics environment
188 if (gClassTable->GetDict("TPad")) {
190 InitializeGraphics(gROOT->IsWebDisplay());
191 }
192
193 // Save current interpreter context
194 gInterpreter->SaveContext();
195 gInterpreter->SaveGlobalsContext();
196
197 // to allow user to interact with TCanvas's under WIN32
198 gROOT->SetLineHasBeenProcessed();
199
200 //Needs to be done last
201 gApplication = this;
202 gROOT->SetApplication(this);
203
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// TApplication dtor.
208
210{
211 for (int i = 0; i < fArgc; i++)
212 if (fArgv[i]) delete [] fArgv[i];
213 delete [] fArgv;
214
215 if (fgApplications)
216 fgApplications->Remove(this);
217
218 // Reduce the risk of the files or sockets being closed after the
219 // end of 'main' (or more exactly before the library start being
220 // unloaded).
221 if (fgApplications == nullptr || fgApplications->FirstLink() == nullptr ) {
223 }
224
225 // Now that all the canvases and files have been closed we can
226 // delete the implementation.
228}
229
230////////////////////////////////////////////////////////////////////////////////
231/// Static method. This method should be called from static library
232/// initializers if the library needs the low level graphics system.
233
238
239////////////////////////////////////////////////////////////////////////////////
240/// Initialize the graphics environment.
241/// If @param only_web is specified, only web-related part of graphics is loaded
242
244{
246 return;
247
248 if (!only_web) {
249 // Load the graphics related libraries
251
252 // Try to load TrueType font renderer. Only try to load if not in batch
253 // mode and Root.UseTTFonts is true and Root.TTFontPath exists. Abort silently
254 // if libttf or libGX11TTF are not found in $ROOTSYS/lib or $ROOTSYS/ttf/lib.
255 const char *ttpath = gEnv->GetValue("Root.TTFontPath",
257 char *ttfont = gSystem->Which(ttpath, "arialbd.ttf", kReadPermission);
258 // Check for use of DFSG - fonts
259 if (!ttfont)
260 ttfont = gSystem->Which(ttpath, "FreeSansBold.ttf", kReadPermission);
261
262 #if !defined(R__WIN32)
263 if (!gROOT->IsBatch() && !strcmp(gVirtualX->GetName(), "X11") &&
264 ttfont && gEnv->GetValue("Root.UseTTFonts", 1)) {
265 if (gClassTable->GetDict("TGX11TTF")) {
266 // in principle we should not have linked anything against libGX11TTF
267 // but with ACLiC this can happen, initialize TGX11TTF by hand
268 // (normally this is done by the static library initializer)
269 ProcessLine("TGX11TTF::Activate();");
270 } else {
272 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", "x11ttf")))
273 if (h->LoadPlugin() == -1)
274 Info("InitializeGraphics", "no TTF support");
275 }
276 }
277 #endif
278 delete [] ttfont;
279 }
280
281 if (!only_web || !fAppImp) {
282 // Create WM dependent application environment
283 if (fAppImp)
284 delete fAppImp;
286 if (!fAppImp) {
287 MakeBatch();
289 }
290 }
291
292 // Create the canvas colors early so they are allocated before
293 // any color table expensive bitmaps get allocated in GUI routines (like
294 // creation of XPM bitmaps).
296
297 // Hook for further initializing the WM dependent application environment
298 Init();
299
300 // Set default screen factor (if not disabled in rc file)
301 if (!only_web && gEnv->GetValue("Canvas.UseScreenFactor", 1)) {
302 Int_t x, y;
303 UInt_t w, h;
304 if (gVirtualX) {
305 gVirtualX->GetGeometry(-1, x, y, w, h);
306 if (h > 0)
307 gStyle->SetScreenFactor(0.001 * h);
308 }
309 }
310}
311
312////////////////////////////////////////////////////////////////////////////////
313/// Clear list containing macro files passed as program arguments.
314/// This method is called from TRint::Run() to ensure that the macro
315/// files are only executed the first time Run() is called.
316
318{
319 if (fFiles) {
320 fFiles->Delete();
322 }
323}
324
325////////////////////////////////////////////////////////////////////////////////
326/// Return specified argument.
327
329{
330 if (fArgv) {
331 if (index >= fArgc) {
332 Error("Argv", "index (%d) >= number of arguments (%d)", index, fArgc);
333 return nullptr;
334 }
335 return fArgv[index];
336 }
337 return nullptr;
338}
339
340////////////////////////////////////////////////////////////////////////////////
341/// Get and handle command line options. Arguments handled are removed
342/// from the argument array. See CommandLineOptionsHelp.h for options.
343
345{
346 static char null[1] = { "" };
347
348 fNoLog = kFALSE;
349 fQuit = kFALSE;
350 fFiles = nullptr;
351
352 if (!argc)
353 return;
354
355 int i, j;
356 TString pwd;
357
358 for (i = 1; i < *argc; i++) {
359 if (!strcmp(argv[i], "-?") || !strncmp(argv[i], "-h", 2) ||
360 !strncmp(argv[i], "--help", 6)) {
362 Terminate(0);
363 } else if (!strncmp(argv[i], "--version", 9)) {
364 fprintf(stderr, "ROOT Version: %s\n", gROOT->GetVersion());
365 fprintf(stderr, "Built for %s on %s\n",
367 gROOT->GetGitDate());
368
369 fprintf(stderr, "From %s@%s\n",
370 gROOT->GetGitBranch(),
371 gROOT->GetGitCommit());
372
373 Terminate(0);
374 } else if (!strcmp(argv[i], "-config")) {
375 fprintf(stderr, "ROOT ./configure options:\n%s\n", gROOT->GetConfigOptions());
376 Terminate(0);
377 } else if (!strcmp(argv[i], "-a")) {
378 fprintf(stderr, "ROOT splash screen is not visible with root.exe, use root instead.\n");
379 Terminate(0);
380 } else if (!strcmp(argv[i], "-b")) {
381 MakeBatch();
382 argv[i] = null;
383 } else if (!strcmp(argv[i], "-n")) {
384 fNoLog = kTRUE;
385 argv[i] = null;
386 } else if (!strcmp(argv[i], "-t")) {
388 // EnableImplicitMT() only enables thread safety if IMT was configured;
389 // enable thread safety even with IMT off:
391 argv[i] = null;
392 } else if (!strcmp(argv[i], "-q")) {
393 fQuit = kTRUE;
394 argv[i] = null;
395 } else if (!strcmp(argv[i], "-l")) {
396 // used by front-end program to not display splash screen
397 fNoLogo = kTRUE;
398 argv[i] = null;
399 } else if (!strcmp(argv[i], "-x")) {
401 argv[i] = null;
402 } else if (!strcmp(argv[i], "-splash")) {
403 // used when started by front-end program to signal that
404 // splash screen can be popped down (TRint::PrintLogo())
405 argv[i] = null;
406 } else if (strncmp(argv[i], "--web", 5) == 0) {
407 // the web mode is requested
408 const char *opt = argv[i] + 5;
409 argv[i] = null;
410 gROOT->SetWebDisplay((*opt == '=') ? opt + 1 : "");
411 } else if (!strcmp(argv[i], "-e")) {
412 argv[i] = null;
413 ++i;
414
415 if ( i < *argc ) {
416 if (!fFiles) fFiles = new TObjArray;
417 TObjString *expr = new TObjString(argv[i]);
418 expr->SetBit(kExpression);
419 fFiles->Add(expr);
420 argv[i] = null;
421 } else {
422 Warning("GetOptions", "-e must be followed by an expression.");
423 }
424 } else if (!strcmp(argv[i], "--")) {
425 TObjString* macro = nullptr;
426 bool warnShown = false;
427
428 if (fFiles) {
429 for (auto f: *fFiles) {
430 TObjString *file = dynamic_cast<TObjString *>(f);
431 if (!file) {
432 if (!dynamic_cast<TNamed*>(f)) {
433 Error("GetOptions()", "Inconsistent file entry (not a TObjString)!");
434 if (f)
435 f->Dump();
436 } // else we did not find the file.
437 continue;
438 }
439
440 if (file->TestBit(kExpression))
441 continue;
442 if (file->String().EndsWith(".root"))
443 continue;
444 if (file->String().Contains('('))
445 continue;
446
447 if (macro && !warnShown && (warnShown = true))
448 Warning("GetOptions", "-- is used with several macros. "
449 "The arguments will be passed to the last one.");
450
451 macro = file;
452 }
453 }
454
455 if (macro) {
456 argv[i] = null;
457 ++i;
458 TString& str = macro->String();
459
460 str += '(';
461 for (; i < *argc; i++) {
462 str += argv[i];
463 str += ',';
464 argv[i] = null;
465 }
466 str.EndsWith(",") ? str[str.Length() - 1] = ')' : str += ')';
467 } else {
468 Warning("GetOptions", "no macro to pass arguments to was provided. "
469 "Everything after the -- will be ignored.");
470 for (; i < *argc; i++)
471 argv[i] = null;
472 }
473 } else if (argv[i][0] != '-' && argv[i][0] != '+') {
475 Long_t id, flags, modtime;
476 char *arg = strchr(argv[i], '(');
477 if (arg) *arg = '\0';
480 // ROOT-9959: we do not continue if we could not expand the path
481 continue;
482 }
484 // remove options and anchor to check the path
485 TString sfx = udir.GetFileAndOptions();
486 TString fln = udir.GetFile();
487 sfx.Replace(sfx.Index(fln), fln.Length(), "");
488 TString path = udir.GetFile();
489 if (strcmp(udir.GetProtocol(), "file")) {
490 path = udir.GetUrl();
491 path.Replace(path.Index(sfx), sfx.Length(), "");
492 }
493 // 'path' is the full URL without suffices (options and/or anchor)
494 if (arg) *arg = '(';
495 if (!arg && !gSystem->GetPathInfo(path.Data(), &id, &size, &flags, &modtime)) {
496 if ((flags & 2)) {
497 // if directory set it in fWorkDir
498 if (pwd == "") {
499 pwd = gSystem->WorkingDirectory();
502 argv[i] = null;
503 } else if (!strcmp(gROOT->GetName(), "Rint")) {
504 Warning("GetOptions", "only one directory argument can be specified (%s)", expandedDir.Data());
505 }
506 } else if (size > 0) {
507 // if file add to list of files to be processed
508 if (!fFiles) fFiles = new TObjArray;
509 fFiles->Add(new TObjString(path.Data()));
510 argv[i] = null;
511 } else {
512 Warning("GetOptions", "file %s has size 0, skipping", expandedDir.Data());
513 }
514 } else {
515 if (TString(udir.GetFile()).EndsWith(".root")) {
516 if (!strcmp(udir.GetProtocol(), "file")) {
517 // file ending on .root but does not exist, likely a typo
518 // warn user if plain root...
519 if (!strcmp(gROOT->GetName(), "Rint"))
520 Warning("GetOptions", "file %s not found", expandedDir.Data());
521 } else {
522 // remote file, give it the benefit of the doubt and add it to list of files
523 if (!fFiles) fFiles = new TObjArray;
524 fFiles->Add(new TObjString(argv[i]));
525 argv[i] = null;
526 }
527 } else {
530 char *mac;
531 if (!fFiles) fFiles = new TObjArray;
533 kReadPermission))) {
534 // if file add to list of files to be processed
535 fFiles->Add(new TObjString(argv[i]));
536 argv[i] = null;
537 delete [] mac;
538 } else {
539 // if file add an invalid entry to list of files to be processed
540 fFiles->Add(new TNamed("NOT FOUND!", argv[i]));
541 // only warn if we're plain root,
542 // other progs might have their own params
543 if (!strcmp(gROOT->GetName(), "Rint")) {
544 Error("GetOptions", "macro %s not found", fname.Data());
545 // Return 2 as the Python interpreter does in case the macro
546 // is not found.
547 Terminate(2);
548 }
549 }
550 }
551 }
552 }
553 // ignore unknown options
554 }
555
556 // go back to startup directory
557 if (pwd != "")
559
560 // remove handled arguments from argument array
561 j = 0;
562 for (i = 0; i < *argc; i++) {
563 if (strcmp(argv[i], "")) {
564 argv[j] = argv[i];
565 j++;
566 }
567 }
568
569 *argc = j;
570}
571
572////////////////////////////////////////////////////////////////////////////////
573/// Handle idle timeout. When this timer expires the registered idle command
574/// will be executed by this routine and a signal will be emitted.
575
577{
578 if (!fIdleCommand.IsNull())
580
581 Emit("HandleIdleTimer()");
582}
583
584////////////////////////////////////////////////////////////////////////////////
585/// Handle exceptions (kSigBus, kSigSegmentationViolation,
586/// kSigIllegalInstruction and kSigFloatingException) trapped in TSystem.
587/// Specific TApplication implementations may want something different here.
588
590{
591 if (TROOT::Initialized()) {
592 if (gException) {
593 gInterpreter->RewindDictionary();
594 gInterpreter->ClearFileBusy();
595 }
596 if (fExitOnException == kExit)
597 gSystem->Exit(128 + sig);
598 else if (fExitOnException == kAbort)
599 gSystem->Abort();
600 else
601 Throw(sig);
602 }
603 gSystem->Exit(128 + sig);
604}
605
606////////////////////////////////////////////////////////////////////////////////
607/// Set the exit on exception option. Setting this option determines what
608/// happens in HandleException() in case an exception (kSigBus,
609/// kSigSegmentationViolation, kSigIllegalInstruction or kSigFloatingException)
610/// is trapped. Choices are: kDontExit (default), kExit or kAbort.
611/// Returns the previous value.
612
619
620/////////////////////////////////////////////////////////////////////////////////
621/// The function generates and executes a command that loads the Doxygen URL in
622/// a browser. It works for Mac, Windows and Linux. In the case of Linux, the
623/// function also checks if the DISPLAY is set. If it isn't, a warning message
624/// and the URL will be displayed on the terminal.
625///
626/// \param[in] url web page to be displayed in a browser
627
629{
630 // We check what operating system the user has.
631#ifdef R__MACOSX
632 // Command for opening a browser on Mac.
633 TString cMac("open ");
634 // We generate the full command and execute it.
635 cMac.Append(url);
636 gSystem->Exec(cMac);
637#elif defined(R__WIN32)
638 // Command for opening a browser on Windows.
639 TString cWindows("start \"\" ");
640 cWindows.Append(url);
642#else
643 // Command for opening a browser in Linux.
644 TString cLinux("xdg-open ");
645 // For Linux we check if the DISPLAY is set.
646 if (gSystem->Getenv("DISPLAY")) {
647 // If the DISPLAY is set it will open the browser.
648 cLinux.Append(url);
650 } else {
651 // Else the user will have a warning and the URL in the terminal.
652 Warning("OpenInBrowser", "The $DISPLAY is not set! Please open (e.g. Ctrl-click) %s\n", url.Data());
653 return;
654 }
655#endif
656 Info("OpenInBrowser", "A new tab should have opened in your browser.");
657}
658
659namespace {
661////////////////////////////////////////////////////////////////////////////////
662/// The function generates a URL address for class or namespace (scopeName).
663/// This is the URL to the online reference guide, generated by Doxygen.
664/// With the enumeration "EUrl" we pick which case we need - the one for
665/// class (kURLforClass) or the one for namespace (kURLforNameSpace).
666///
667/// \param[in] scopeName the name of the class or the namespace
668/// \param[in] scopeType the enumerator for class or namespace
669
671{
672 // We start the URL with a static part, the same for all scopes and members.
673 TString url = "https://root.cern/doc/";
674 // Then we check the ROOT version used.
675 TPRegexp re4(R"(.*/(v\d)-(\d\d)-00-patches)");
676 const char *branchName = gROOT->GetGitBranch();
677 TObjArray *objarr = re4.MatchS(branchName);
679 // We extract the correct version name for the URL.
680 if (objarr && objarr->GetEntries() == 3) {
681 // We have a valid version of ROOT and we will extract the correct name for the URL.
682 version = ((TObjString *)objarr->At(1))->GetString() + ((TObjString *)objarr->At(2))->GetString();
683 } else {
684 // If it's not a supported version, we will go to "master" branch.
685 version = "master";
686 }
687 delete objarr;
688 url.Append(version);
689 url.Append("/");
690 // We will replace all "::" with "_1_1" and all "_" with "__" in the
691 // classes definitions, due to Doxygen syntax requirements.
692 scopeName.ReplaceAll("_", "__");
693 scopeName.ReplaceAll("::", "_1_1");
694 // We build the URL for the correct scope type and name.
695 if (scopeType == kURLforClass) {
696 url.Append("class");
697 } else if (scopeType == kURLforStruct) {
698 url.Append("struct");
699 } else {
700 url.Append("namespace");
701 }
702 url.Append(scopeName);
703 url.Append(".html");
704 return url;
705}
706} // namespace
707
708namespace {
709////////////////////////////////////////////////////////////////////////////////
710/// The function returns a TString with the arguments of a method from the
711/// scope (scopeName), but modified with respect to Doxygen syntax - spacing
712/// around special symbols and adding the missing scopes ("std::").
713/// "FormatMethodArgsForDoxygen" works for functions defined inside namespaces
714/// as well. We avoid looking up twice for the TFunction by passing "func".
715///
716/// \param[in] scopeName the name of the class/namespace/struct
717/// \param[in] func pointer to the method
718
720{
721 // With "GetSignature" we get the arguments of the method and put them in a TString.
723 // "methodArguments" is modified with respect of Doxygen requirements.
724 methodArguments.ReplaceAll(" = ", "=");
725 methodArguments.ReplaceAll("* ", " *");
726 methodArguments.ReplaceAll("*=", " *=");
727 methodArguments.ReplaceAll("*)", " *)");
728 methodArguments.ReplaceAll("*,", " *,");
729 methodArguments.ReplaceAll("*& ", " *&");
730 methodArguments.ReplaceAll("& ", " &");
731 // TODO: prepend "std::" to all stdlib classes!
732 methodArguments.ReplaceAll("ostream", "std::ostream");
733 methodArguments.ReplaceAll("istream", "std::istream");
734 methodArguments.ReplaceAll("map", "std::map");
735 methodArguments.ReplaceAll("vector", "std::vector");
736 // We need to replace the "currentClass::foo" with "foo" in the arguments.
737 // TODO: protect the global functions.
738 TString scopeNameRE("\\b");
739 scopeNameRE.Append(scopeName);
740 scopeNameRE.Append("::\\b");
742 argFix.Substitute(methodArguments, "");
743 return methodArguments;
744}
745} // namespace
746
747namespace {
748////////////////////////////////////////////////////////////////////////////////
749/// The function returns a TString with the text as an encoded url so that it
750/// can be passed to the function OpenInBrowser
751///
752/// \param[in] text the input text
753/// \return the text appropriately escaped
754
756{
757 text.ReplaceAll("\n","%0A");
758 text.ReplaceAll("#","%23");
759 text.ReplaceAll(";","%3B");
760 text.ReplaceAll("\"","%22");
761 text.ReplaceAll("`","%60");
762 text.ReplaceAll("+","%2B");
763 text.ReplaceAll("/","%2F");
764 return text;
765}
766} // namespace
767
768namespace {
769////////////////////////////////////////////////////////////////////////////////
770/// The function checks if a member function of a scope is defined as inline.
771/// If so, it also checks if it is virtual. Then the return type of "func" is
772/// modified for the need of Doxygen and with respect to the function
773/// definition. We pass pointer to the method (func) to not re-do the
774/// TFunction lookup.
775///
776/// \param[in] scopeName the name of the class/namespace/struct
777/// \param[in] func pointer to the method
778
780{
781 // We put the return type of "func" in a TString "returnType".
783 // If the return type is a type nested in the current class, it will appear scoped (Class::Enumeration).
784 // Below we make sure to remove the current class, because the syntax of Doxygen requires it.
785 TString scopeNameRE("\\b");
786 scopeNameRE.Append(scopeName);
787 scopeNameRE.Append("::\\b");
789 returnFix.Substitute(returnType, "");
790 // We check is if the method is defined as inline.
791 if (func->ExtraProperty() & kIsInlined) {
792 // We check if the function is defined as virtual.
793 if (func->Property() & kIsVirtual) {
794 // If the function is virtual, we append "virtual" before the return type.
795 returnType.Prepend("virtual ");
796 }
797 returnType.ReplaceAll(" *", "*");
798 } else {
799 // If the function is not inline we only change the spacing in "returnType"
800 returnType.ReplaceAll("*", " *");
801 }
802 // In any case (with no respect to virtual/inline check) we need to change
803 // the return type as following.
804 // TODO: prepend "std::" to all stdlib classes!
805 returnType.ReplaceAll("istream", "std::istream");
806 returnType.ReplaceAll("ostream", "std::ostream");
807 returnType.ReplaceAll("map", "std::map");
808 returnType.ReplaceAll("vector", "std::vector");
809 returnType.ReplaceAll("&", " &");
810 return returnType;
811}
812} // namespace
813
814namespace {
815////////////////////////////////////////////////////////////////////////////////
816/// The function generates a URL for "dataMemberName" defined in "scopeName".
817/// It returns a TString with the URL used in the online reference guide,
818/// generated with Doxygen. For data members the URL consist of 2 parts -
819/// URL for "scopeName" and a part for "dataMemberName".
820/// For enumerator, the URL could be separated into 3 parts - URL for
821/// "scopeName", part for the enumeration and a part for the enumerator.
822///
823/// \param[in] scopeName the name of the class/namespace/struct
824/// \param[in] dataMemberName the name of the data member/enumerator
825/// \param[in] dataMember pointer to the data member/enumerator
826/// \param[in] scopeType enumerator to the scope type
827
828static TString
830{
831 // We first check if the data member is not enumerator.
832 if (!dataMember->IsEnum()) {
833 // If we work with data members, we have to append a hashed with MD5 text, consisting of:
834 // "Type ClassName::DataMemberNameDataMemberName(arguments)".
835 // We first get the type of the data member.
836 TString md5DataMember(dataMember->GetFullTypeName());
837 md5DataMember.Append(" ");
838 // We append the scopeName and "::".
839 md5DataMember.Append(scopeName);
840 md5DataMember.Append("::");
841 // We append the dataMemberName twice.
844 // We call UrlGenerator for the scopeName.
846 // Then we append "#a" and the hashed text.
847 urlForDataMember.Append("#a");
848 urlForDataMember.Append(md5DataMember.MD5());
849 return urlForDataMember;
850 }
851 // If the data member is enumerator, then we first have to check if the enumeration is anonymous.
852 // Doxygen requires different syntax for anonymous enumeration ("scopeName::@1@1").
853 // We create a TString with the name of the scope and the enumeration from which the enumerator is.
854 TString scopeEnumeration = dataMember->GetTrueTypeName();
856 if (scopeEnumeration.Contains("(unnamed)")) {
857 // FIXME: need to investigate the numbering scheme.
858 md5EnumClass.Append(scopeName);
859 md5EnumClass.Append("::@1@1");
860 } else {
861 // If the enumeration is not anonymous we put "scopeName::Enumeration" in a TString,
862 // which will be hashed with MD5 later.
864 // We extract the part after "::" (this is the enumerator name).
866 // The syntax is "Class::EnumeratorEnumerator
868 }
869 // The next part of the URL is hashed "@ scopeName::EnumeratorEnumerator".
871 md5Enumerator.Append(scopeName);
872 md5Enumerator.Append("::");
875 // We make the URL for the "scopeName".
877 // Then we have to append the hashed text for the enumerator.
878 url.Append("#a");
879 url.Append(md5EnumClass.MD5());
880 // We append "a" and then the next hashed text.
881 url.Append("a");
882 url.Append(md5Enumerator.MD5());
883 return url;
884}
885} // namespace
886
887namespace {
888////////////////////////////////////////////////////////////////////////////////
889/// The function generates URL for enumeration. The hashed text consist of:
890/// "Class::EnumerationEnumeration".
891///
892/// \param[in] scopeName the name of the class/namespace/struct
893/// \param[in] enumeration the name of the enumeration
894/// \param[in] scopeType enumerator for class/namespace/struct
895
897{
898 // The URL consists of URL for the "scopeName", "#a" and hashed as MD5 text.
899 // The text is "Class::EnumerationEnumeration.
901 md5Enumeration.Append("::");
904 // We make the URL for the scope "scopeName".
906 // Then we have to append "#a" and the hashed text.
907 url.Append("#a");
908 url.Append(md5Enumeration.MD5());
909 return url;
910}
911} // namespace
912
913namespace {
914enum EMethodKind { kURLforMethod, kURLforStructor };
915////////////////////////////////////////////////////////////////////////////////
916/// The function generates URL for any member function (including Constructor/
917/// Destructor) of "scopeName". Doxygen first generates the URL for the scope.
918/// We do that with the help of "UrlGenerator". Then we append "#a" and a
919/// hashed with MD5 text. It consists of:
920/// "ReturnType ScopeName::MethodNameMethodName(Method arguments)".
921/// For constructor/destructor of a class, the return type is not appended.
922///
923/// \param[in] scopeName the name of the class/namespace/struct
924/// \param[in] methodName the name of the method from the scope
925/// \param[in] func pointer to the method
926/// \param[in] methodType enumerator for method or constructor
927/// \param[in] scopeType enumerator for class/namespace/struct
928
929static TString GetUrlForMethod(const TString &scopeName, const TString &methodName, TFunction *func,
930 EMethodKind methodType, EUrl scopeType)
931{
933 if (methodType == kURLforMethod) {
934 // In the case of method, we append the return type too.
935 // "FormatReturnTypeForDoxygen" modifies the return type with respect to Doxygen's requirement.
938 // We need to append "constexpr" if we work with constexpr functions in namespaces.
939 if (func->Property() & kIsConstexpr) {
940 md5Text.Prepend("constexpr ");
941 }
942 }
943 md5Text.Append(" ");
944 }
945 // We append ScopeName::MethodNameMethodName.
946 md5Text.Append(scopeName);
947 md5Text.Append("::");
948 md5Text.Append(methodName);
949 md5Text.Append(methodName);
950 // We use "FormatMethodArgsForDoxygen" to modify the arguments of Method with respect of Doxygen.
952 // We generate the URL for the class/namespace/struct.
954 url.Append("#a");
955 // We append the hashed text.
956 url.Append(md5Text.MD5());
957 return url;
958}
959} // namespace
960
961////////////////////////////////////////////////////////////////////////////////
962/// It gets the ROOT installation setup as TString
963///
964/// \return a string with several lines
965///
967{
968 std::vector<TString> lines;
969 lines.emplace_back("```");
970 lines.emplace_back(TString::Format("ROOT v%s",
971 gROOT->GetVersion()));
972 lines.emplace_back(TString::Format("Built for %s on %s", gSystem->GetBuildArch(), gROOT->GetGitDate()));
973 if (!strcmp(gROOT->GetGitBranch(), gROOT->GetGitCommit())) {
974 static const char *months[] = {"January","February","March","April","May",
975 "June","July","August","September","October",
976 "November","December"};
977 Int_t idatqq = gROOT->GetVersionDate();
978 Int_t iday = idatqq%100;
979 Int_t imonth = (idatqq/100)%100;
980 Int_t iyear = (idatqq/10000);
981
982 lines.emplace_back(TString::Format("From tag %s, %d %s %4d",
983 gROOT->GetGitBranch(),
984 iday,months[imonth-1],iyear));
985 } else {
986 // If branch and commit are identical - e.g. "v5-34-18" - then we have
987 // a release build. Else specify the git hash this build was made from.
988 lines.emplace_back(TString::Format("From %s@%s",
989 gROOT->GetGitBranch(),
990 gROOT->GetGitCommit()));
991 }
992 lines.emplace_back(TString::Format("With %s",
994 lines.emplace_back("Binary directory: "+ gROOT->GetBinDir());
995 lines.emplace_back("```");
996 TString setup = "";
997 for (auto& line : lines) {
998 setup.Append(line);
999 setup.Append('\n');
1000 }
1001 setup.Chop(); // trim final `\n`
1002 return setup;
1003}
1004
1005////////////////////////////////////////////////////////////////////////////////
1006/// It opens a Forum topic in a web browser with prefilled ROOT version
1007///
1008/// \param[in] type the issue type (only bug supported right now)
1009
1011{
1012 // https://meta.discourse.org/t/how-to-create-a-post-clicking-a-link/96197
1013
1014 if (type == "bug") {
1015 //OpenInBrowser("\"https://root-forum.cern.ch/new-topic?title=topic%20title&body=topic%20body&category=category/subcategory&tags=email,planned\"");
1017R"(___
1018_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)_
1019
1020### Describe the bug
1021<!--
1022A clear and concise description of what the wrong behavior is.
1023-->
1024### Expected behavior
1025<!--
1026A clear and concise description of what you expected to happen.
1027-->
1028
1029### To Reproduce
1030<!--
1031Steps to reproduce the behavior:
10321. Your code that triggers the issue: at least a part; ideally something we can run ourselves.
10332. Don't forget to attach the required input files!
10343. How to run your code and / or build it, e.g. `root myMacro.C`, ...
1035-->
1036
1037### Setup
1038)"+GetSetup()+
1039R"(
1040<!--
1041Please specify also how you obtained ROOT, such as `dnf install` / binary download / you built it yourself.
1042-->
1043
1044### Additional context
1045<!--
1046Add any other context about the problem here.
1047-->)";
1049
1050 OpenInBrowser("\"https://root-forum.cern.ch/new-topic?category=ROOT&tags=bug&body="+report_template+"&\"");
1051 } else {
1052 Warning("OpenForumTopic", "cannot find \"%s\" as type for a Forum topic\n"
1053 "Available types are 'bug'.", type.Data());
1054 }
1055}
1056
1057////////////////////////////////////////////////////////////////////////////////
1058/// It opens a GitHub issue in a web browser with prefilled ROOT version
1059///
1060/// \param[in] type the issue type (bug, feature or improvement)
1061
1063{
1064 // https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue#creating-an-issue-from-a-url-query
1065
1066 if (type == "bug") {
1068 "\"https://github.com/root-project/root/issues/new?labels=bug&template=bug_report.yml&root-version=" +
1069 FormatHttpUrl(GetSetup()) + "\"");
1070 } else if (type == "improvement") {
1071 OpenInBrowser("\"https://github.com/root-project/root/issues/"
1072 "new?labels=improvement&template=improvement_report.yml&root-version=" +
1073 FormatHttpUrl(GetSetup()) + "\"");
1074 } else if (type == "feature") {
1076 "\"https://github.com/root-project/root/issues/new?labels=new+feature&template=feature_request.yml\"");
1077 } else {
1078 Warning("OpenGitHubIssue",
1079 "Cannot find GitHub issue type \"%s\".\n"
1080 "Available types are 'bug', 'feature' and 'improvement'.",
1081 type.Data());
1082 }
1083}
1084
1085////////////////////////////////////////////////////////////////////////////////
1086/// It opens the online reference guide, generated with Doxygen, for the
1087/// chosen scope (class/namespace/struct) or member (method/function/
1088/// data member/enumeration/enumerator. If the user types incorrect value,
1089/// it will return an error or warning.
1090///
1091/// \param[in] strippedClass the scope or scope::member
1092
1094{
1095 // We check if the user is searching for a scope and if the scope exists.
1097 // We check what scope he is searching for (class/namespace/struct).
1098 // Enumerators will switch between the possible cases.
1099 EUrl scopeType;
1100 if (clas->Property() & kIsNamespace) {
1102 } else if (clas->Property() & kIsStruct) {
1104 } else {
1106 }
1107 // If the user search directly for a scope we open the URL for him with OpenInBrowser.
1109 return;
1110 }
1111 // Else we subtract the name of the method and remove it from the command.
1113 // Error out if "strippedClass" is un-scoped (and it's not a class, see `TClass::GetClass(strippedClass)` above).
1114 // TODO: Global functions.
1115 if (strippedClass == memberName) {
1116 Error("OpenReferenceGuideFor", "Unknown entity \"%s\" - global variables / functions not supported yet!",
1117 strippedClass.Data());
1118 return;
1119 }
1120 // Else we remove the member name to be left with the scope.
1121 TString scopeName = strippedClass(0, strippedClass.Length() - memberName.Length() - 2);
1122 // We check if the scope exists in ROOT.
1124 if (!cl) {
1125 // That's a member of something ROOT doesn't know.
1126 Warning("OpenReferenceGuideFor", "\"%s\" does not exist in ROOT!", scopeName.Data());
1127 return;
1128 }
1129 // We have enumerators for the three available cases - class, namespace and struct.
1130 EUrl scopeType;
1131 if (cl->Property() & kIsNamespace) {
1133 } else if (cl->Property() & kIsStruct) {
1135 } else {
1137 }
1138 // If the user wants to search for a method, we take its name (memberName) and
1139 // modify it - we delete everything starting at the first "(" so the user won't have to
1140 // do it by hand when they use Tab.
1141 int bracket = memberName.First("(");
1142 if (bracket > 0) {
1143 memberName.Remove(bracket);
1144 }
1145 // We check if "memberName" is a member function of "cl" or any of its base classes.
1146 if (TFunction *func = cl->GetMethodAllAny(memberName)) {
1147 // If so we find the name of the class that it belongs to.
1148 TString baseClName = ((TMethod *)func)->GetClass()->GetName();
1149 // We define an enumerator to distinguish between structor and method.
1150 EMethodKind methodType;
1151 // We check if "memberName" is a constructor.
1152 if (baseClName == memberName) {
1154 // We check if "memberName" is a destructor.
1155 } else if (memberName[0] == '~') {
1157 // We check if "memberName" is a method.
1158 } else {
1160 }
1161 // We call "GetUrlForMethod" for the correct class and scope.
1163 return;
1165 // We check if "memberName" is an enumeration.
1166 if (cl->GetListOfEnums()->FindObject(memberName)) {
1167 // If so with OpenInBrowser we open the URL generated with GetUrlForEnumeration
1168 // with respect to the "scopeType".
1170 return;
1171 }
1172
1173 // We check if "memberName" is enumerator defined in one the base classes of "scopeName".
1175 // We find the actual scope (might be in a base) and open the URL in a browser.
1176 TString baseClName = ((TMethod *)enumerator->GetClass())->GetName();
1178 return;
1179 }
1180
1181 // Warning message will appear if the user types the function name incorrectly
1182 // or the function is not a member function of "cl" or any of its base classes.
1183 Warning("OpenReferenceGuideFor", "cannot find \"%s\" as member of %s or its base classes! Check %s\n", memberName.Data(),
1184 scopeName.Data(), UrlGenerator(scopeName, scopeType).Data());
1186
1187////////////////////////////////////////////////////////////////////////////////
1188/// The function (".forum <type>") submits a new post on the ROOT forum
1189/// via web browser.
1190/// \note You can use "bug" as <type>.
1191/// \param[in] line command from the command line
1192
1193void TApplication::Forum(const char *line)
1194{
1195 // We first check if the user chose a correct syntax.
1197 if (!strippedCommand.BeginsWith(".forum ")) {
1198 Error("Forum", "Unknown command! Use 'bug' after '.forum '");
1199 return;
1200 }
1201 // We remove the command ".forum" from the TString.
1202 strippedCommand.Remove(0, 7);
1203 // We strip the command line after removing ".help" or ".?".
1205
1208
1209////////////////////////////////////////////////////////////////////////////////
1210/// The function (".gh <type>") submits a new issue on GitHub via web browser.
1211/// \note You can use "bug", "feature" or "improvement" as <type>.
1212/// \param[in] line command from the command line
1213
1214void TApplication::GitHub(const char *line)
1215{
1216 // We first check if the user chose a correct syntax.
1218 if (!strippedCommand.BeginsWith(".gh ")) {
1219 Error("GitHub", "Unknown command! Use 'bug', 'feature' or 'improvement' after '.gh '");
1220 return;
1221 }
1222 // We remove the command ".gh" from the TString.
1223 strippedCommand.Remove(0, 4);
1224 // We strip the command line after removing ".help" or ".?".
1226
1228}
1229
1230////////////////////////////////////////////////////////////////////////////////
1231/// The function lists useful commands (".help") or opens the online reference
1232/// guide, generated with Doxygen (".help scope" or ".help scope::member").
1233/// \note You can use ".?" as the short version of ".help"
1234/// \param[in] line command from the command line
1235
1236void TApplication::Help(const char *line)
1237{
1238 // We first check if the user wants to print the help on the interpreter.
1240 // If the user chooses ".help" or ".?".
1241 if ((strippedCommand == ".help") || (strippedCommand == ".?")) {
1242 gInterpreter->ProcessLine(line);
1243 Printf("\n ROOT special commands.");
1244 Printf(" ==============================================================================");
1245 Printf(" .L <filename>[flags]: load the given file with optional flags like\n"
1246 " + to compile or ++ to force recompile.\n"
1247 " Type .? TSystem::CompileMacro for a list of all flags.\n"
1248 " <filename> can also be a shared library; skip flags.");
1249 Printf(" .(x|X) <filename>[flags](args) :\n"
1250 " same as .L <filename>[flags] and runs then a function\n"
1251 " with signature: ret_type filename(args).");
1252 Printf(" .credits : show credits");
1253 Printf(" .demo : launch GUI demo");
1254 Printf(" .forum bug : ask for help with a bug or crash at the ROOT forum.");
1255 Printf(" .gh [bug|feature|improvement]\n"
1256 " : submit a bug report, feature or improvement suggestion");
1257 Printf(" .help Class::Member : open reference guide for that class member (or .?).\n"
1258 " Specifying '::Member' is optional.");
1259 Printf(" .help edit : show line editing shortcuts (or .?)");
1260 Printf(" .license : show license");
1261 Printf(" .libraries : show loaded libraries");
1262 Printf(" .ls : list contents of current TDirectory");
1263 Printf(" .pwd : show current TDirectory, pad and style");
1264 Printf(" .quit (or .exit) : quit ROOT (long form of .q)");
1265 Printf(" .R [user@]host[:dir] [-l user] [-d dbg] [script] :\n"
1266 " launch process in a remote host");
1267 Printf(" .qqq : quit ROOT - mandatory");
1268 Printf(" .qqqqq : exit process immediately");
1269 Printf(" .qqqqqqq : abort process");
1270 Printf(" .which [file] : show path of macro file");
1271 Printf(" .![OS_command] : execute OS-specific shell command");
1272 Printf(" .!root -? : print ROOT usage (CLI options)");
1273 return;
1274 } else {
1275 // If the user wants to use the extended ".help scopeName" command to access
1276 // the online reference guide, we first check if the command starts correctly.
1277 if ((!strippedCommand.BeginsWith(".help ")) && (!strippedCommand.BeginsWith(".? "))) {
1278 Error("Help", "Unknown command!");
1279 return;
1280 }
1281 // We remove the command ".help" or ".?" from the TString.
1282 if (strippedCommand.BeginsWith(".? ")) {
1283 strippedCommand.Remove(0, 3);
1284 } else {
1285 strippedCommand.Remove(0, 5);
1286 }
1287 // We strip the command line after removing ".help" or ".?".
1289
1290 if (strippedCommand == "edit") {
1291 Printf("\n ROOT terminal keyboard shortcuts (GNU-readline style).");
1292 #ifdef R__MACOSX
1293 #define FOOTNOTE " *"
1294 Printf("* Some of these commands might be intercepted by macOS predefined system shortcuts.");
1295 // https://apple.stackexchange.com/questions/18043/how-can-i-make-ctrlright-left-arrow-stop-changing-desktops-in-lion
1296 #else
1297 #define FOOTNOTE ""
1298 #endif
1299 Printf(" ==============================================================================");
1300 Printf(" Arrow_Left : move cursor left [Ctrl+B]");
1301 Printf(" Arrow_Right : move cursor right [Ctrl+F] [Ctrl+G]");
1302 #ifdef R__MACOSX
1303 Printf(" Fn+Arrow_Left : move cursor to beginning of line [Ctrl+A]");
1304 #else
1305 Printf(" Home : move cursor to beginning of line [Ctrl+A]");
1306 #endif
1307 #ifdef R__MACOSX
1308 Printf(" Fn+Arrow_Right : move cursor to end of line [Ctrl+E]");
1309 #else
1310 Printf(" End : move cursor to end of line [Ctrl+E]");
1311 #endif
1312 Printf(" Ctrl+Arrow_Left : jump to previous word [Esc,B] [Alt,B]" FOOTNOTE);
1313 Printf(" Ctrl+Arrow_Right : jump to next word [Esc,F] [Alt,F]" FOOTNOTE);
1314
1315 Printf(" Backspace : delete previous character [Ctrl+H]");
1316 Printf(" Del : delete next character [Ctrl+D]");
1317 Printf(" Esc,Backspace : delete previous word [Ctrl+W] [Esc,Ctrl+H] [Alt+Backspace] [Esc,Del] [Esc,Ctrl+Del]" FOOTNOTE);// Del is 0x7F on macOS
1318 Printf(" Ctrl+Del : delete next word [Esc,D] [Alt,D]" FOOTNOTE);
1319 Printf(" Ctrl+U : cut all characters between cursor and start of line");
1320 Printf(" Ctrl+K : cut all characters between cursor and end of line");
1321
1322 Printf(" Ctrl+T : transpose characters");
1323 Printf(" Esc,C : character to upper and jump to next word");
1324 Printf(" Esc,L : word to lower case and jump to its end");
1325 Printf(" Esc,U : word to upper case and jump to its end");
1326 Printf(" Ctrl+Shift+C : copy clipboard content");
1327 Printf(" Ctrl+Shift+V : paste clipboard content [Ctrl+Y] [Alt+Y]");
1328 #ifdef R__MACOSX
1329 Printf(" Fn+Enter : toggle overwrite mode");
1330 #else
1331 Printf(" Ins : toggle overwrite mode");
1332 #endif
1334 Printf(" Ctrl+_ : undo last keypress action");
1335 Printf(" Tab : autocomplete command or print suggestions [Ctrl+I] [Esc,Tab]");
1336 Printf(" Enter : execute command [Ctrl+J] [Ctrl+M]");
1337 Printf(" Ctrl+L : clear prompt screen");
1338 Printf(" Ctrl+D : quit ROOT (if empty line)");
1339 Printf(" Ctrl+C : send kSigInt interrupt signal");
1340 Printf(" Ctrl+Z : send kSigStop pause job signal");
1341 Printf(" Ctrl+\\ : send kSigQuit quit job signal");
1342
1343 Printf(" Arrow_Down : navigate downwards in command history [Ctrl+N]");
1344 Printf(" Arrow_Up : navigate upwards in command history [Ctrl+P]");
1345 Printf(" Ctrl+R ; Ctrl+S : search command in your history by typing a string.\n"
1346 " Use Backspace if you mistyped (but not arrows).\n"
1347 " Press Ctrl+R (Ctrl+S) repeateadly to navigate matches in reverse (forward) order");
1348 Printf(" Arrow_Right : after Ctrl+R (Ctrl+S), select current match of the history search\n"
1349 " [Ctrl+O] [Enter] [Ctrl+J] [Ctrl+M] [Arrow_Left] [Esc,Esc].\n"
1350 " Use Ctrl+F or Ctrl+G to cancel search and revert original line");
1351
1352 return;
1353 }
1354 // We call the function what handles the extended ".help scopeName" command.
1356 }
1357}
1358
1359/// Load shared libs necessary for graphics. These libraries are only
1360/// loaded when gROOT->IsBatch() is kFALSE.
1361
1363{
1364 if (gROOT->IsBatch())
1365 return;
1366
1367 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualPad"))
1368 if (h->LoadPlugin() == -1)
1369 return;
1370
1371 TString name;
1372 TString title1 = "ROOT interface to ";
1373 TString nativex, title;
1374
1375#ifdef R__WIN32
1376 nativex = "win32gdk";
1377 name = "Win32gdk";
1378 title = title1 + "Win32gdk";
1379#elif defined(R__HAS_COCOA)
1380 nativex = "quartz";
1381 name = "quartz";
1382 title = title1 + "Quartz";
1383#else
1384 nativex = "x11";
1385 name = "X11";
1386 title = title1 + "X11";
1387#endif
1388
1389 TString guiBackend = gEnv->GetValue("Gui.Backend", "native");
1390 guiBackend.ToLower();
1391 if (guiBackend == "native") {
1393 } else {
1394 name = guiBackend;
1396 }
1397
1398 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualX", guiBackend)) {
1399 if (h->LoadPlugin() == -1) {
1400 gROOT->SetBatch(kTRUE);
1401 return;
1402 }
1403 gVirtualX = (TVirtualX *) h->ExecPlugin(2, name.Data(), title.Data());
1405 }
1406
1407 TString guiFactory = gEnv->GetValue("Gui.Factory", "native");
1408 guiFactory.ToLower();
1409 if (guiFactory == "native")
1410 guiFactory = "root";
1411
1412 if (auto h = gROOT->GetPluginManager()->FindHandler("TGuiFactory", guiFactory)) {
1413 if (h->LoadPlugin() == -1) {
1414 gROOT->SetBatch(kTRUE);
1415 return;
1416 }
1417 gGuiFactory = (TGuiFactory *) h->ExecPlugin(0);
1418 }
1420
1421////////////////////////////////////////////////////////////////////////////////
1422/// Switch to batch mode.
1423
1425{
1426 gROOT->SetBatch();
1429#ifndef R__WIN32
1430 if (gVirtualX != gGXBatch) delete gVirtualX;
1431#endif
1433}
1434
1435////////////////////////////////////////////////////////////////////////////////
1436/// Parse the content of a line starting with ".R" (already stripped-off)
1437/// The format is
1438/// ~~~ {.cpp}
1439/// [user@]host[:dir] [-l user] [-d dbg] [script]
1440/// ~~~
1441/// The variable 'dir' is the remote directory to be used as working dir.
1442/// The username can be specified in two ways, "-l" having the priority
1443/// (as in ssh).
1444/// A 'dbg' value > 0 gives increasing verbosity.
1445/// The last argument 'script' allows to specify an alternative script to
1446/// be executed remotely to startup the session.
1447
1449 TString &hostdir, TString &user,
1451{
1452 if (!ln || strlen(ln) <= 0)
1453 return 0;
1454
1455 Int_t rc = 0;
1460
1461 TString line(ln);
1462 TString tkn;
1463 Int_t from = 0;
1464 while (line.Tokenize(tkn, from, " ")) {
1465 if (tkn == "-l") {
1466 // Next is a user name
1467 isUser = kTRUE;
1468 } else if (tkn == "-d") {
1469 isDbg = kTRUE;
1470 } else if (tkn == "-close") {
1471 rc = 1;
1472 } else if (tkn.BeginsWith("-")) {
1473 ::Warning("TApplication::ParseRemoteLine","unknown option: %s", tkn.Data());
1474 } else {
1475 if (isUser) {
1476 user = tkn;
1477 isUser = kFALSE;
1478 } else if (isDbg) {
1479 dbg = tkn.Atoi();
1480 isDbg = kFALSE;
1481 } else if (isHostDir) {
1482 hostdir = tkn;
1483 hostdir.ReplaceAll(":","/");
1484 isHostDir = kFALSE;
1486 } else if (isScript) {
1487 // Add everything left
1488 script = tkn;
1489 script.Insert(0, "\"");
1490 script += "\"";
1491 // isScript = kFALSE; // [clang-tidy] never read
1492 break;
1493 }
1494 }
1495 }
1496
1497 // Done
1498 return rc;
1499}
1500
1501////////////////////////////////////////////////////////////////////////////////
1502/// Process the content of a line starting with ".R" (already stripped-off)
1503/// The format is
1504/// ~~~ {.cpp}
1505/// [user@]host[:dir] [-l user] [-d dbg] [script] | [host] -close
1506/// ~~~
1507/// The variable 'dir' is the remote directory to be used as working dir.
1508/// The username can be specified in two ways, "-l" having the priority
1509/// (as in ssh).
1510/// A 'dbg' value > 0 gives increasing verbosity.
1511/// The last argument 'script' allows to specify an alternative script to
1512/// be executed remotely to startup the session.
1513
1515{
1516 if (!line) return 0;
1517
1518 if (!strncmp(line, "-?", 2) || !strncmp(line, "-h", 2) ||
1519 !strncmp(line, "--help", 6)) {
1520 Info("ProcessRemote", "remote session help:");
1521 Printf(".R [user@]host[:dir] [-l user] [-d dbg] [[<]script] | [host] -close");
1522 Printf("Create a ROOT session on the specified remote host.");
1523 Printf("The variable \"dir\" is the remote directory to be used as working dir.");
1524 Printf("The username can be specified in two ways, \"-l\" having the priority");
1525 Printf("(as in ssh). A \"dbg\" value > 0 gives increasing verbosity.");
1526 Printf("The last argument \"script\" allows to specify an alternative script to");
1527 Printf("be executed remotely to startup the session, \"roots\" being");
1528 Printf("the default. If the script is preceded by a \"<\" the script will be");
1529 Printf("sourced, after which \"roots\" is executed. The sourced script can be ");
1530 Printf("used to change the PATH and other variables, allowing an alternative");
1531 Printf("\"roots\" script to be found.");
1532 Printf("To close down a session do \".R host -close\".");
1533 Printf("To switch between sessions do \".R host\", to switch to the local");
1534 Printf("session do \".R\".");
1535 Printf("To list all open sessions do \"gApplication->GetApplications()->Print()\".");
1536 return 0;
1537 }
1538
1539 TString hostdir, user, script;
1540 Int_t dbg = 0;
1542 if (hostdir.Length() <= 0) {
1543 // Close the remote application if required
1544 if (rc == 1) {
1546 delete fAppRemote;
1547 }
1548 // Return to local run
1549 fAppRemote = nullptr;
1550 // Done
1551 return 1;
1552 } else if (rc == 1) {
1553 // close an existing remote application
1554 TApplication *ap = TApplication::Open(hostdir, 0, nullptr);
1555 if (ap) {
1557 delete ap;
1558 }
1559 }
1560 // Attach or start a remote application
1561 if (user.Length() > 0)
1562 hostdir.Insert(0, TString::Format("%s@", user.Data()));
1563 const char *sc = (script.Length() > 0) ? script.Data() : nullptr;
1565 if (ap) {
1566 fAppRemote = ap;
1567 }
1568
1569 // Done
1570 return 1;
1571}
1572
1573namespace {
1574 static int PrintFile(const char* filename) {
1578 Error("ProcessLine()", "Cannot find file %s", filename);
1579 return 1;
1580 }
1581 std::ifstream instr(sFileName);
1583 content.ReadFile(instr);
1584 Printf("%s", content.Data());
1585 return 0;
1586 }
1587 } // namespace
1588
1589////////////////////////////////////////////////////////////////////////////////
1590/// Process a single command line, either a C++ statement or an interpreter
1591/// command starting with a ".".
1592/// Return the return value of the command cast to a long.
1593
1595{
1596 if (!line || !*line) return 0;
1597
1598 // If we are asked to go remote do it
1599 if (!strncmp(line, ".R", 2)) {
1600 Int_t n = 2;
1601 while (*(line+n) == ' ')
1602 n++;
1603 return ProcessRemote(line+n, err);
1604 }
1605
1606 // Redirect, if requested
1609 return fAppRemote->ProcessLine(line, err);
1610 }
1611
1612 if (!strncasecmp(line, ".qqqqqqq", 7)) {
1613 gSystem->Abort();
1614 } else if (!strncasecmp(line, ".qqqqq", 5)) {
1615 Info("ProcessLine", "Bye... (try '.qqqqqqq' if still running)");
1616 gSystem->Exit(1);
1617 } else if (!strncasecmp(line, ".exit", 4) || !strncasecmp(line, ".quit", 2)) {
1618 Terminate(0);
1619 return 0;
1620 }
1621
1622 if (!strncmp(line, ".gh", 3)) {
1623 GitHub(line);
1624 return 1;
1625 }
1626
1627 if (!strncmp(line, ".forum", 6)) {
1628 Forum(line);
1629 return 1;
1630 }
1631
1632 if (!strncmp(line, ".?", 2) || !strncmp(line, ".help", 5)) {
1633 Help(line);
1634 return 1;
1635 }
1636
1637 if (!strncmp(line, ".demo", 5)) {
1638 if (gROOT->IsBatch()) {
1639 Error("ProcessLine", "Cannot show demos in batch mode!");
1640 return 1;
1641 }
1642 ProcessLine(".x " + TROOT::GetTutorialDir() + "/demos.C");
1643 return 0;
1644 }
1645
1646 if (!strncmp(line, ".license", 8)) {
1647 return PrintFile(TROOT::GetDocDir() + "/LICENSE");
1648 }
1649
1650 if (!strncmp(line, ".credits", 8)) {
1651 TString credits = TROOT::GetDocDir() + "/CREDITS";
1653 credits = TROOT::GetDocDir() + "/README/CREDITS";
1654 return PrintFile(credits);
1655 }
1656
1657 if (!strncmp(line, ".pwd", 4)) {
1658 if (gDirectory)
1659 Printf("Current directory: %s", gDirectory->GetPath());
1660 if (gPad)
1661 Printf("Current pad: %s", gPad->GetName());
1662 if (gStyle)
1663 Printf("Current style: %s", gStyle->GetName());
1664 return 1;
1665 }
1666
1667 if (!strncmp(line, ".ls", 3)) {
1668 const char *opt = nullptr;
1669 if (line[3]) opt = &line[3];
1670 if (gDirectory) gDirectory->ls(opt);
1671 return 1;
1672 }
1673
1674 if (!strncmp(line, ".which", 6)) {
1675 char *fn = Strip(line+7);
1676 char *s = strtok(fn, "+("); // this method does not need to be reentrant
1678 if (!mac)
1679 Printf("No macro %s in path %s", s, TROOT::GetMacroPath());
1680 else
1681 Printf("%s", mac);
1682 delete [] fn;
1683 delete [] mac;
1684 return mac ? 1 : 0;
1685 }
1686
1687 if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2)) {
1688 TString aclicMode, arguments, io;
1689 TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
1690
1692 if (arguments.Length())
1693 Warning("ProcessLine", "argument(s) \"%s\" ignored with .%c", arguments.Data(), line[1]);
1694 Longptr_t retval = 0;
1695 if (!mac) {
1696 Error("ProcessLine", "macro %s not found in path %s", fname.Data(), TROOT::GetMacroPath());
1697 } else {
1698 TString cmd(line + 1);
1699 Ssiz_t posSpace = cmd.Index(' ');
1700 if (posSpace == kNPOS)
1701 cmd.Remove(1);
1702 else
1703 cmd.Remove(posSpace);
1704 auto tempbuf = TString::Format(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(), io.Data());
1705 delete[] mac;
1706 if (sync)
1707 retval = gInterpreter->ProcessLineSynch(tempbuf.Data(), (TInterpreter::EErrorCode *)err);
1708 else
1709 retval = gInterpreter->ProcessLine(tempbuf.Data(), (TInterpreter::EErrorCode *)err);
1710 }
1711
1712 InitializeGraphics(gROOT->IsWebDisplay());
1713
1714 return retval;
1715 }
1716
1717 if (!strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
1718 return ProcessFile(line+3, err, line[2] == 'k');
1719 }
1721 if (!strcmp(line, ".reset")) {
1722 // Do nothing, .reset disabled in Cling because too many side effects
1723 Printf("*** .reset not allowed, please use gROOT->Reset() ***");
1724 return 0;
1725
1726#if 0
1727 // delete the ROOT dictionary since CINT will destroy all objects
1728 // referenced by the dictionary classes (TClass et. al.)
1729 gROOT->GetListOfClasses()->Delete();
1730 // fall through
1731#endif
1732 }
1733
1734 if (!strcmp(line, ".libraries")) {
1735 // List the loaded libraries
1737 return 0;
1738 }
1739
1740 if (sync)
1741 return gInterpreter->ProcessLineSynch(line, (TInterpreter::EErrorCode*)err);
1742 else
1743 return gInterpreter->ProcessLine(line, (TInterpreter::EErrorCode*)err);
1744}
1745
1746////////////////////////////////////////////////////////////////////////////////
1747/// Process a file containing a C++ macro.
1748
1749Longptr_t TApplication::ProcessFile(const char *file, Int_t *error, Bool_t keep)
1750{
1751 return ExecuteFile(file, error, keep);
1752}
1753
1754////////////////////////////////////////////////////////////////////////////////
1755/// Execute a file containing a C++ macro (static method). Can be used
1756/// while TApplication is not yet created.
1757
1758Longptr_t TApplication::ExecuteFile(const char *file, Int_t *error, Bool_t keep)
1759{
1760 static const Int_t kBufSize = 1024;
1761
1762 if (!file || !*file) return 0;
1763
1765 TString arguments;
1766 TString io;
1767 TString fname = gSystem->SplitAclicMode(file, aclicMode, arguments, io);
1768
1770 if (!exnam) {
1771 ::Error("TApplication::ExecuteFile", "macro %s not found in path %s", fname.Data(),
1773 delete [] exnam;
1774 if (error)
1776 return 0;
1777 }
1778
1779 ::std::ifstream macro(exnam, std::ios::in);
1780 if (!macro.good()) {
1781 ::Error("TApplication::ExecuteFile", "%s no such file", exnam);
1782 if (error)
1784 delete [] exnam;
1785 return 0;
1786 }
1787
1788 char currentline[kBufSize];
1789 char dummyline[kBufSize];
1790 int tempfile = 0;
1791 int comment = 0;
1792 int ifndefc = 0;
1793 int ifdef = 0;
1794 char *s = nullptr;
1795 Bool_t execute = kFALSE;
1796 Longptr_t retval = 0;
1797
1798 while (1) {
1799 bool res = (bool)macro.getline(currentline, kBufSize);
1800 if (macro.eof()) break;
1801 if (!res) {
1802 // Probably only read kBufSize, let's ignore the remainder of
1803 // the line.
1804 macro.clear();
1805 while (!macro.getline(dummyline, kBufSize) && !macro.eof()) {
1806 macro.clear();
1807 }
1808 }
1809 s = currentline;
1810 while (s && (*s == ' ' || *s == '\t')) s++; // strip-off leading blanks
1811
1812 // very simple minded pre-processor parsing, only works in case macro file
1813 // starts with "#ifndef __CINT__". In that case everything till next
1814 // "#else" or "#endif" will be skipped.
1815 if (*s == '#') {
1816 char *cs = Compress(currentline);
1817 if (strstr(cs, "#ifndef__CINT__") ||
1818 strstr(cs, "#if!defined(__CINT__)"))
1819 ifndefc = 1;
1820 else if (ifndefc && (strstr(cs, "#ifdef") || strstr(cs, "#ifndef") ||
1821 strstr(cs, "#ifdefined") || strstr(cs, "#if!defined")))
1822 ifdef++;
1823 else if (ifndefc && strstr(cs, "#endif")) {
1824 if (ifdef)
1825 ifdef--;
1826 else
1827 ifndefc = 0;
1828 } else if (ifndefc && !ifdef && strstr(cs, "#else"))
1829 ifndefc = 0;
1830 delete [] cs;
1831 }
1832 if (!*s || *s == '#' || ifndefc || !strncmp(s, "//", 2)) continue;
1833
1834 if (!comment && (!strncmp(s, ".X", 2) || !strncmp(s, ".x", 2))) {
1835 retval = ExecuteFile(s+3);
1836 execute = kTRUE;
1837 continue;
1838 }
1839
1840 if (!strncmp(s, "/*", 2)) comment = 1;
1841 if (comment) {
1842 // handle slightly more complex cases like: /* */ /*
1843again:
1844 s = strstr(s, "*/");
1845 if (s) {
1846 comment = 0;
1847 s += 2;
1848
1849 while (s && (*s == ' ' || *s == '\t')) s++; // strip-off leading blanks
1850 if (!*s) continue;
1851 if (!strncmp(s, "//", 2)) continue;
1852 if (!strncmp(s, "/*", 2)) {
1853 comment = 1;
1854 goto again;
1855 }
1856 }
1857 }
1858 if (!comment && *s == '{') tempfile = 1;
1859 if (!comment) break;
1861 macro.close();
1862
1863 if (!execute) {
1865 if (!tempfile) {
1866 // We have a script that does NOT contain an unnamed macro,
1867 // so we can call the script compiler on it.
1868 exname += aclicMode;
1869 }
1870 exname += arguments;
1871 exname += io;
1872
1875 tempbuf.Form(".x %s", exname.Data());
1876 } else {
1877 tempbuf.Form(".X%s %s", keep ? "k" : " ", exname.Data());
1878 }
1879 retval = gInterpreter->ProcessLineSynch(tempbuf,(TInterpreter::EErrorCode*)error);
1880 }
1881
1882 delete [] exnam;
1883 return retval;
1884}
1886////////////////////////////////////////////////////////////////////////////////
1887/// Main application eventloop. Calls system dependent eventloop via gSystem.
1888
1890{
1892
1893 fIsRunning = kTRUE;
1894
1895 gSystem->Run();
1897}
1898
1899////////////////////////////////////////////////////////////////////////////////
1900/// Set the command to be executed after the system has been idle for
1901/// idleTimeInSec seconds. Normally called via TROOT::Idle(...).
1902
1904{
1909}
1910
1911////////////////////////////////////////////////////////////////////////////////
1912/// Remove idle timer. Normally called via TROOT::Idle(0).
1913
1915{
1916 if (fIdleTimer) {
1917 // timers are removed from the gSystem timer list by their dtor
1919 }
1920}
1921
1922////////////////////////////////////////////////////////////////////////////////
1923/// Called when system starts idleing.
1924
1926{
1928 fIdleTimer->Reset();
1930 }
1931}
1932
1933////////////////////////////////////////////////////////////////////////////////
1934/// Called when system stops idleing.
1935
1937{
1938 if (fIdleTimer)
1940}
1942////////////////////////////////////////////////////////////////////////////////
1943/// What to do when tab is pressed. Re-implemented by TRint.
1944/// See TTabCom::Hook() for meaning of return values.
1945
1946Int_t TApplication::TabCompletionHook(char* /*buf*/, int* /*pLoc*/, std::ostream& /*out*/)
1947{
1948 return -1;
1950
1951
1952////////////////////////////////////////////////////////////////////////////////
1953/// Terminate the application by call TSystem::Exit() unless application has
1954/// been told to return from Run(), by a call to SetReturnFromRun().
1955
1956void TApplication::Terminate(Int_t status)
1958 Emit("Terminate(Int_t)", status);
1959
1960 if (fReturnFromRun)
1961 gSystem->ExitLoop();
1962 else {
1963 gSystem->Exit(status);
1964 }
1965}
1966
1967////////////////////////////////////////////////////////////////////////////////
1968/// Emit signal when a line has been processed.
1969
1970void TApplication::LineProcessed(const char *line)
1971{
1972 Emit("LineProcessed(const char*)", line);
1973}
1974
1975////////////////////////////////////////////////////////////////////////////////
1976/// Emit signal when console keyboard key was pressed.
1977
1979{
1980 Emit("KeyPressed(Int_t)", key);
1981}
1982
1983////////////////////////////////////////////////////////////////////////////////
1984/// Emit signal when return key was pressed.
1985
1987{
1988 Emit("ReturnPressed(char*)", text);
1989}
1990
1991////////////////////////////////////////////////////////////////////////////////
1992/// Set console echo mode:
1993///
1994/// - mode = kTRUE - echo input symbols
1995/// - mode = kFALSE - noecho input symbols
1996
1998{
2000
2001////////////////////////////////////////////////////////////////////////////////
2002/// Static function used to create a default application environment.
2003
2005{
2007 // gApplication is set at the end of 'new TApplication.
2008 if (!gApplication) {
2009 char *a = StrDup("RootApp");
2010 char *b = StrDup("-b");
2011 char *argv[2];
2012 Int_t argc = 2;
2013 argv[0] = a;
2014 argv[1] = b;
2015 new TApplication("RootApp", &argc, argv, nullptr, 0);
2016 if (gDebug > 0)
2017 Printf("<TApplication::CreateApplication>: "
2018 "created default TApplication");
2019 delete [] a; delete [] b;
2021 }
2022}
2023
2024////////////////////////////////////////////////////////////////////////////////
2025/// Static function used to attach to an existing remote application
2026/// or to start one.
2027
2029 Int_t debug, const char *script)
2030{
2031 TApplication *ap = nullptr;
2032 TUrl nu(url);
2033 Int_t nnew = 0;
2034
2035 // Look among the existing ones
2036 if (fgApplications) {
2038 while ((ap = (TApplication *) nxa())) {
2039 TString apn(ap->ApplicationName());
2040 if (apn == url) {
2041 // Found matching application
2042 return ap;
2043 } else {
2044 // Check if same machine and user
2045 TUrl au(apn);
2046 if (strlen(au.GetUser()) > 0 && strlen(nu.GetUser()) > 0 &&
2047 !strcmp(au.GetUser(), nu.GetUser())) {
2048 if (!strncmp(au.GetHost(), nu.GetHost(), strlen(nu.GetHost())))
2049 // New session on a known machine
2050 nnew++;
2051 }
2052 }
2053 }
2054 } else {
2055 ::Error("TApplication::Open", "list of applications undefined - protocol error");
2056 return ap;
2057 }
2058
2059 // If new session on a known machine pass the number as option
2060 if (nnew > 0) {
2061 nnew++;
2062 nu.SetOptions(TString::Format("%d", nnew).Data());
2063 }
2064
2065 // Instantiate the TApplication object to be run
2066 TPluginHandler *h = nullptr;
2067 if ((h = gROOT->GetPluginManager()->FindHandler("TApplication","remote"))) {
2068 if (h->LoadPlugin() == 0) {
2069 ap = (TApplication *) h->ExecPlugin(3, nu.GetUrl(), debug, script);
2070 } else {
2071 ::Error("TApplication::Open", "failed to load plugin for TApplicationRemote");
2072 }
2073 } else {
2074 ::Error("TApplication::Open", "failed to find plugin for TApplicationRemote");
2075 }
2076
2077 // Add to the list
2078 if (ap && !(ap->TestBit(kInvalidObject))) {
2079 fgApplications->Add(ap);
2080 gROOT->GetListOfBrowsables()->Add(ap, ap->ApplicationName());
2081 TIter next(gROOT->GetListOfBrowsers());
2082 TBrowser *b;
2083 while ((b = (TBrowser*) next()))
2084 b->Add(ap, ap->ApplicationName());
2085 gROOT->RefreshBrowsers();
2086 } else {
2088 ::Error("TApplication::Open",
2089 "TApplicationRemote for %s could not be instantiated", url);
2090 }
2091
2092 // Done
2093 return ap;
2094}
2095
2096////////////////////////////////////////////////////////////////////////////////
2097/// Static function used to close a remote application
2098
2100{
2101 if (app) {
2102 app->Terminate(0);
2104 gROOT->GetListOfBrowsables()->RecursiveRemove(app);
2105 TIter next(gROOT->GetListOfBrowsers());
2106 TBrowser *b;
2107 while ((b = (TBrowser*) next()))
2109 gROOT->RefreshBrowsers();
2110 }
2111}
2112
2113////////////////////////////////////////////////////////////////////////////////
2114/// Show available sessions
2115
2116void TApplication::ls(Option_t *opt) const
2117{
2118 if (fgApplications) {
2120 TApplication *a = nullptr;
2121 while ((a = (TApplication *) nxa())) {
2122 a->Print(opt);
2123 }
2124 } else {
2125 Print(opt);
2126 }
2127}
2128
2129////////////////////////////////////////////////////////////////////////////////
2130/// Static method returning the list of available applications
2131
2133{
2134 return fgApplications;
2135}
#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
#define ClassImp(name)
Definition Rtypes.h:376
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:2579
char * Strip(const char *str, char c=' ')
Strip leading and trailing c (blanks by default) from a string.
Definition TString.cxx:2528
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2510
char * StrDup(const char *str)
Duplicate the string str.
Definition TString.cxx:2564
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:428
void Add(TObject *obj, const char *name=nullptr, Int_t check=-1)
Add object with name to browser.
Definition TBrowser.cxx:303
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:3890
TList * GetListOfEnums(Bool_t load=kTRUE)
Return a list containing the TEnums of a class.
Definition TClass.cxx:3714
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6129
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
Definition TClass.cxx:4412
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:2974
static void InitializeColors()
Initialize colors used by the TCanvas based graphics (via TColor objects).
Definition TColor.cxx:1173
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:491
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:410
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:576
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:458
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:1058
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:865
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1072
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1100
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:656
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:1046
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:2765
static void ShutDown()
Shut down ROOT.
Definition TROOT.cxx:3192
static const TString & GetTTFFontDir()
Get the fonts directory in the installation. Static utility function.
Definition TROOT.cxx:3245
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition TROOT.cxx:2914
static const TString & GetTutorialDir()
Get the tutorials directory in the installation. Static utility function.
Definition TROOT.cxx:3171
static const TString & GetDocDir()
Get the documentation directory in the installation. Static utility function.
Definition TROOT.cxx:3134
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:2251
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition TString.cxx:1171
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:2385
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:311
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1287
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1678
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4284
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition TSystem.cxx:653
virtual void ListLibraries(const char *regexp="")
List the loaded shared libraries.
Definition TSystem.cxx:2098
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:1411
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:1309
virtual void Run()
System event loop.
Definition TSystem.cxx:343
virtual void ExitLoop()
Exit from event loop.
Definition TSystem.cxx:392
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition TSystem.cxx:874
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition TSystem.cxx:471
virtual const char * GetBuildCompilerVersionStr() const
Return the build compiler version identifier string.
Definition TSystem.cxx:3925
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition TSystem.cxx:727
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:883
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1561
virtual void SetProgname(const char *name)
Set the application name (from command line, argv[0]) and copy it in gProgName.
Definition TSystem.cxx:226
virtual const char * GetBuildArch() const
Return the build architecture.
Definition TSystem.cxx:3901
virtual void Abort(int code=0)
Abort the application.
Definition TSystem.cxx:736
virtual TTimer * RemoveTimer(TTimer *t)
Remove timer from list of system timers.
Definition TSystem.cxx:481
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
void Reset()
Reset the timer.
Definition TTimer.cxx:163
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'.