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