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
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")) {
191 InitializeGraphics(gROOT->IsWebDisplay());
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/// If @param only_web is specified, only web-related part of graphics is loaded
243
245{
247 return;
248
249 if (!only_web) {
250 // Load the graphics related libraries
252
253 // Try to load TrueType font renderer. Only try to load if not in batch
254 // mode and Root.UseTTFonts is true and Root.TTFontPath exists. Abort silently
255 // if libttf or libGX11TTF are not found in $ROOTSYS/lib or $ROOTSYS/ttf/lib.
256 const char *ttpath = gEnv->GetValue("Root.TTFontPath",
258 char *ttfont = gSystem->Which(ttpath, "arialbd.ttf", kReadPermission);
259 // Check for use of DFSG - fonts
260 if (!ttfont)
261 ttfont = gSystem->Which(ttpath, "FreeSansBold.ttf", kReadPermission);
262
263 #if !defined(R__WIN32)
264 if (!gROOT->IsBatch() && !strcmp(gVirtualX->GetName(), "X11") &&
265 ttfont && gEnv->GetValue("Root.UseTTFonts", 1)) {
266 if (gClassTable->GetDict("TGX11TTF")) {
267 // in principle we should not have linked anything against libGX11TTF
268 // but with ACLiC this can happen, initialize TGX11TTF by hand
269 // (normally this is done by the static library initializer)
270 ProcessLine("TGX11TTF::Activate();");
271 } else {
273 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", "x11ttf")))
274 if (h->LoadPlugin() == -1)
275 Info("InitializeGraphics", "no TTF support");
276 }
277 }
278 #endif
279 delete [] ttfont;
280 }
281
282 if (!only_web || !fAppImp) {
283 // Create WM dependent application environment
284 if (fAppImp)
285 delete fAppImp;
287 if (!fAppImp) {
288 MakeBatch();
290 }
291 }
292
293 // Create the canvas colors early so they are allocated before
294 // any color table expensive bitmaps get allocated in GUI routines (like
295 // creation of XPM bitmaps).
297
298 // Hook for further initializing the WM dependent application environment
299 Init();
300
301 // Set default screen factor (if not disabled in rc file)
302 if (!only_web && gEnv->GetValue("Canvas.UseScreenFactor", 1)) {
303 Int_t x, y;
304 UInt_t w, h;
305 if (gVirtualX) {
306 gVirtualX->GetGeometry(-1, x, y, w, h);
307 if (h > 0)
308 gStyle->SetScreenFactor(0.001 * h);
309 }
310 }
311}
312
313////////////////////////////////////////////////////////////////////////////////
314/// Clear list containing macro files passed as program arguments.
315/// This method is called from TRint::Run() to ensure that the macro
316/// files are only executed the first time Run() is called.
317
319{
320 if (fFiles) {
321 fFiles->Delete();
323 }
324}
325
326////////////////////////////////////////////////////////////////////////////////
327/// Return specified argument.
328
330{
331 if (fArgv) {
332 if (index >= fArgc) {
333 Error("Argv", "index (%d) >= number of arguments (%d)", index, fArgc);
334 return nullptr;
335 }
336 return fArgv[index];
337 }
338 return nullptr;
339}
340
341////////////////////////////////////////////////////////////////////////////////
342/// Get and handle command line options. Arguments handled are removed
343/// from the argument array. See CommandLineOptionsHelp.h for options.
344
345void TApplication::GetOptions(Int_t *argc, char **argv)
346{
347 static char null[1] = { "" };
348
349 fNoLog = kFALSE;
350 fQuit = kFALSE;
351 fFiles = nullptr;
352
353 if (!argc)
354 return;
355
356 int i, j;
357 TString pwd;
358
359 for (i = 1; i < *argc; i++) {
360 if (!strcmp(argv[i], "-?") || !strncmp(argv[i], "-h", 2) ||
361 !strncmp(argv[i], "--help", 6)) {
362 fprintf(stderr, kCommandLineOptionsHelp);
363 Terminate(0);
364 } else if (!strncmp(argv[i], "--version", 9)) {
365 fprintf(stderr, "ROOT Version: %s\n", gROOT->GetVersion());
366 fprintf(stderr, "Built for %s on %s\n",
368 gROOT->GetGitDate());
369
370 fprintf(stderr, "From %s@%s\n",
371 gROOT->GetGitBranch(),
372 gROOT->GetGitCommit());
373
374 Terminate(0);
375 } else if (!strcmp(argv[i], "-config")) {
376 fprintf(stderr, "ROOT ./configure options:\n%s\n", gROOT->GetConfigOptions());
377 Terminate(0);
378 } else if (!strcmp(argv[i], "-b")) {
379 MakeBatch();
380 argv[i] = null;
381 } else if (!strcmp(argv[i], "-n")) {
382 fNoLog = kTRUE;
383 argv[i] = null;
384 } else if (!strcmp(argv[i], "-t")) {
386 // EnableImplicitMT() only enables thread safety if IMT was configured;
387 // enable thread safety even with IMT off:
389 argv[i] = null;
390 } else if (!strcmp(argv[i], "-q")) {
391 fQuit = kTRUE;
392 argv[i] = null;
393 } else if (!strcmp(argv[i], "-l")) {
394 // used by front-end program to not display splash screen
395 fNoLogo = kTRUE;
396 argv[i] = null;
397 } else if (!strcmp(argv[i], "-x")) {
399 argv[i] = null;
400 } else if (!strcmp(argv[i], "-splash")) {
401 // used when started by front-end program to signal that
402 // splash screen can be popped down (TRint::PrintLogo())
403 argv[i] = null;
404 } else if (strncmp(argv[i], "--web", 5) == 0) {
405 // the web mode is requested
406 const char *opt = argv[i] + 5;
407 argv[i] = null;
408 if (strcmp(opt, "=off") == 0)
409 gROOT->SetWebDisplay("off");
410 else {
411 printf("\nWARNING!\n");
412 printf("Web mode switch --web is disabled for security reasons.\n");
413 printf("See https://root.cern/about/security/#2023-11-26-open-port-for-control-of-web-gui-allows-read-and-write-access-to-file-system for more information.\n");
414 printf("For environments controlling the security issues you can enable web display by calling\n");
415 printf("gROOT->SetWebDisplay(); in ROOT prompt or in startup scripts\n\n");
416 // gROOT->SetWebDisplay((*opt == '=') ? opt + 1 : "");
417 }
418 } else if (!strcmp(argv[i], "-e")) {
419 argv[i] = null;
420 ++i;
421
422 if ( i < *argc ) {
423 if (!fFiles) fFiles = new TObjArray;
424 TObjString *expr = new TObjString(argv[i]);
425 expr->SetBit(kExpression);
426 fFiles->Add(expr);
427 argv[i] = null;
428 } else {
429 Warning("GetOptions", "-e must be followed by an expression.");
430 }
431 } else if (!strcmp(argv[i], "--")) {
432 TObjString* macro = nullptr;
433 bool warnShown = false;
434
435 if (fFiles) {
436 for (auto f: *fFiles) {
437 TObjString *file = dynamic_cast<TObjString *>(f);
438 if (!file) {
439 if (!dynamic_cast<TNamed*>(f)) {
440 Error("GetOptions()", "Inconsistent file entry (not a TObjString)!");
441 if (f)
442 f->Dump();
443 } // else we did not find the file.
444 continue;
445 }
446
447 if (file->TestBit(kExpression))
448 continue;
449 if (file->String().EndsWith(".root"))
450 continue;
451 if (file->String().Contains('('))
452 continue;
453
454 if (macro && !warnShown && (warnShown = true))
455 Warning("GetOptions", "-- is used with several macros. "
456 "The arguments will be passed to the last one.");
457
458 macro = file;
459 }
460 }
461
462 if (macro) {
463 argv[i] = null;
464 ++i;
465 TString& str = macro->String();
466
467 str += '(';
468 for (; i < *argc; i++) {
469 str += argv[i];
470 str += ',';
471 argv[i] = null;
472 }
473 str.EndsWith(",") ? str[str.Length() - 1] = ')' : str += ')';
474 } else {
475 Warning("GetOptions", "no macro to pass arguments to was provided. "
476 "Everything after the -- will be ignored.");
477 for (; i < *argc; i++)
478 argv[i] = null;
479 }
480 } else if (argv[i][0] != '-' && argv[i][0] != '+') {
482 Long_t id, flags, modtime;
483 char *arg = strchr(argv[i], '(');
484 if (arg) *arg = '\0';
485 char *dir = gSystem->ExpandPathName(argv[i]);
486 // ROOT-9959: we do not continue if we could not expand the path
487 if (!dir) continue;
488 TUrl udir(dir, kTRUE);
489 // remove options and anchor to check the path
490 TString sfx = udir.GetFileAndOptions();
491 TString fln = udir.GetFile();
492 sfx.Replace(sfx.Index(fln), fln.Length(), "");
493 TString path = udir.GetFile();
494 if (strcmp(udir.GetProtocol(), "file")) {
495 path = udir.GetUrl();
496 path.Replace(path.Index(sfx), sfx.Length(), "");
497 }
498 // 'path' is the full URL without suffices (options and/or anchor)
499 if (arg) *arg = '(';
500 if (!arg && !gSystem->GetPathInfo(path.Data(), &id, &size, &flags, &modtime)) {
501 if ((flags & 2)) {
502 // if directory set it in fWorkDir
503 if (pwd == "") {
504 pwd = gSystem->WorkingDirectory();
505 fWorkDir = dir;
507 argv[i] = null;
508 } else if (!strcmp(gROOT->GetName(), "Rint")) {
509 Warning("GetOptions", "only one directory argument can be specified (%s)", dir);
510 }
511 } else if (size > 0) {
512 // if file add to list of files to be processed
513 if (!fFiles) fFiles = new TObjArray;
514 fFiles->Add(new TObjString(path.Data()));
515 argv[i] = null;
516 } else {
517 Warning("GetOptions", "file %s has size 0, skipping", dir);
518 }
519 } else {
520 if (TString(udir.GetFile()).EndsWith(".root")) {
521 if (!strcmp(udir.GetProtocol(), "file")) {
522 // file ending on .root but does not exist, likely a typo
523 // warn user if plain root...
524 if (!strcmp(gROOT->GetName(), "Rint"))
525 Warning("GetOptions", "file %s not found", dir);
526 } else {
527 // remote file, give it the benefit of the doubt and add it to list of files
528 if (!fFiles) fFiles = new TObjArray;
529 fFiles->Add(new TObjString(argv[i]));
530 argv[i] = null;
531 }
532 } else {
533 TString mode,fargs,io;
534 TString fname = gSystem->SplitAclicMode(dir,mode,fargs,io);
535 char *mac;
536 if (!fFiles) fFiles = new TObjArray;
537 if ((mac = gSystem->Which(TROOT::GetMacroPath(), fname,
538 kReadPermission))) {
539 // if file add to list of files to be processed
540 fFiles->Add(new TObjString(argv[i]));
541 argv[i] = null;
542 delete [] mac;
543 } else {
544 // if file add an invalid entry to list of files to be processed
545 fFiles->Add(new TNamed("NOT FOUND!", argv[i]));
546 // only warn if we're plain root,
547 // other progs might have their own params
548 if (!strcmp(gROOT->GetName(), "Rint"))
549 Warning("GetOptions", "macro %s not found", fname.Data());
550 }
551 }
552 }
553 delete [] dir;
554 }
555 // ignore unknown options
556 }
557
558 // go back to startup directory
559 if (pwd != "")
561
562 // remove handled arguments from argument array
563 j = 0;
564 for (i = 0; i < *argc; i++) {
565 if (strcmp(argv[i], "")) {
566 argv[j] = argv[i];
567 j++;
568 }
569 }
570
571 *argc = j;
572}
573
574////////////////////////////////////////////////////////////////////////////////
575/// Handle idle timeout. When this timer expires the registered idle command
576/// will be executed by this routine and a signal will be emitted.
577
579{
580 if (!fIdleCommand.IsNull())
582
583 Emit("HandleIdleTimer()");
584}
585
586////////////////////////////////////////////////////////////////////////////////
587/// Handle exceptions (kSigBus, kSigSegmentationViolation,
588/// kSigIllegalInstruction and kSigFloatingException) trapped in TSystem.
589/// Specific TApplication implementations may want something different here.
590
592{
593 if (TROOT::Initialized()) {
594 if (gException) {
595 gInterpreter->RewindDictionary();
596 gInterpreter->ClearFileBusy();
597 }
598 if (fExitOnException == kExit)
599 gSystem->Exit(128 + sig);
600 else if (fExitOnException == kAbort)
601 gSystem->Abort();
602 else
603 Throw(sig);
604 }
605 gSystem->Exit(128 + sig);
606}
607
608////////////////////////////////////////////////////////////////////////////////
609/// Set the exit on exception option. Setting this option determines what
610/// happens in HandleException() in case an exception (kSigBus,
611/// kSigSegmentationViolation, kSigIllegalInstruction or kSigFloatingException)
612/// is trapped. Choices are: kDontExit (default), kExit or kAbort.
613/// Returns the previous value.
614
616{
618 fExitOnException = opt;
619 return old;
620}
621
622/////////////////////////////////////////////////////////////////////////////////
623/// The function generates and executes a command that loads the Doxygen URL in
624/// a browser. It works for Mac, Windows and Linux. In the case of Linux, the
625/// function also checks if the DISPLAY is set. If it isn't, a warning message
626/// and the URL will be displayed on the terminal.
627///
628/// \param[in] url web page to be displayed in a browser
629
631{
632 // We check what operating system the user has.
633#ifdef R__MACOSX
634 // Command for opening a browser on Mac.
635 TString cMac("open ");
636 // We generate the full command and execute it.
637 cMac.Append(url);
638 gSystem->Exec(cMac);
639#elif defined(R__WIN32)
640 // Command for opening a browser on Windows.
641 TString cWindows("start \"\" ");
642 cWindows.Append(url);
643 gSystem->Exec(cWindows);
644#else
645 // Command for opening a browser in Linux.
646 TString cLinux("xdg-open ");
647 // For Linux we check if the DISPLAY is set.
648 if (gSystem->Getenv("DISPLAY")) {
649 // If the DISPLAY is set it will open the browser.
650 cLinux.Append(url);
651 gSystem->Exec(cLinux);
652 } else {
653 // Else the user will have a warning and the URL in the terminal.
654 Warning("OpenInBrowser", "The $DISPLAY is not set! Please open (e.g. Ctrl-click) %s\n", url.Data());
655 }
656#endif
657}
658
659namespace {
660enum EUrl { kURLforClass, kURLforNameSpace, kURLforStruct };
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
670static TString UrlGenerator(TString scopeName, EUrl scopeType)
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);
678 TString version;
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
719static TString FormatMethodArgsForDoxygen(const TString &scopeName, TFunction *func)
720{
721 // With "GetSignature" we get the arguments of the method and put them in a TString.
722 TString methodArguments = func->GetSignature();
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");
741 TPRegexp argFix(scopeNameRE);
742 argFix.Substitute(methodArguments, "");
743 return methodArguments;
744}
745} // namespace
746
747namespace {
748////////////////////////////////////////////////////////////////////////////////
749/// The function checks if a member function of a scope is defined as inline.
750/// If so, it also checks if it is virtual. Then the return type of "func" is
751/// modified for the need of Doxygen and with respect to the function
752/// definition. We pass pointer to the method (func) to not re-do the
753/// TFunction lookup.
754///
755/// \param[in] scopeName the name of the class/namespace/struct
756/// \param[in] func pointer to the method
757
758static TString FormatReturnTypeForDoxygen(const TString &scopeName, TFunction *func)
759{
760 // We put the return type of "func" in a TString "returnType".
761 TString returnType = func->GetReturnTypeName();
762 // If the return type is a type nested in the current class, it will appear scoped (Class::Enumeration).
763 // Below we make sure to remove the current class, because the syntax of Doxygen requires it.
764 TString scopeNameRE("\\b");
765 scopeNameRE.Append(scopeName);
766 scopeNameRE.Append("::\\b");
767 TPRegexp returnFix(scopeNameRE);
768 returnFix.Substitute(returnType, "");
769 // We check is if the method is defined as inline.
770 if (func->ExtraProperty() & kIsInlined) {
771 // We check if the function is defined as virtual.
772 if (func->Property() & kIsVirtual) {
773 // If the function is virtual, we append "virtual" before the return type.
774 returnType.Prepend("virtual ");
775 }
776 returnType.ReplaceAll(" *", "*");
777 } else {
778 // If the function is not inline we only change the spacing in "returnType"
779 returnType.ReplaceAll("*", " *");
780 }
781 // In any case (with no respect to virtual/inline check) we need to change
782 // the return type as following.
783 // TODO: prepend "std::" to all stdlib classes!
784 returnType.ReplaceAll("istream", "std::istream");
785 returnType.ReplaceAll("ostream", "std::ostream");
786 returnType.ReplaceAll("map", "std::map");
787 returnType.ReplaceAll("vector", "std::vector");
788 returnType.ReplaceAll("&", " &");
789 return returnType;
790}
791} // namespace
792
793namespace {
794////////////////////////////////////////////////////////////////////////////////
795/// The function generates a URL for "dataMemberName" defined in "scopeName".
796/// It returns a TString with the URL used in the online reference guide,
797/// generated with Doxygen. For data members the URL consist of 2 parts -
798/// URL for "scopeName" and a part for "dataMemberName".
799/// For enumerator, the URL could be separated into 3 parts - URL for
800/// "scopeName", part for the enumeration and a part for the enumerator.
801///
802/// \param[in] scopeName the name of the class/namespace/struct
803/// \param[in] dataMemberName the name of the data member/enumerator
804/// \param[in] dataMember pointer to the data member/enumerator
805/// \param[in] scopeType enumerator to the scope type
806
807static TString
808GetUrlForDataMember(const TString &scopeName, const TString &dataMemberName, TDataMember *dataMember, EUrl scopeType)
809{
810 // We first check if the data member is not enumerator.
811 if (!dataMember->IsEnum()) {
812 // If we work with data members, we have to append a hashed with MD5 text, consisting of:
813 // "Type ClassName::DataMemberNameDataMemberName(arguments)".
814 // We first get the type of the data member.
815 TString md5DataMember(dataMember->GetFullTypeName());
816 md5DataMember.Append(" ");
817 // We append the scopeName and "::".
818 md5DataMember.Append(scopeName);
819 md5DataMember.Append("::");
820 // We append the dataMemberName twice.
821 md5DataMember.Append(dataMemberName);
822 md5DataMember.Append(dataMemberName);
823 // We call UrlGenerator for the scopeName.
824 TString urlForDataMember = UrlGenerator(scopeName, scopeType);
825 // Then we append "#a" and the hashed text.
826 urlForDataMember.Append("#a");
827 urlForDataMember.Append(md5DataMember.MD5());
828 return urlForDataMember;
829 }
830 // If the data member is enumerator, then we first have to check if the enumeration is anonymous.
831 // Doxygen requires different syntax for anonymous enumeration ("scopeName::@1@1").
832 // We create a TString with the name of the scope and the enumeration from which the enumerator is.
833 TString scopeEnumeration = dataMember->GetTrueTypeName();
834 TString md5EnumClass;
835 if (scopeEnumeration.Contains("(unnamed)")) {
836 // FIXME: need to investigate the numbering scheme.
837 md5EnumClass.Append(scopeName);
838 md5EnumClass.Append("::@1@1");
839 } else {
840 // If the enumeration is not anonymous we put "scopeName::Enumeration" in a TString,
841 // which will be hashed with MD5 later.
842 md5EnumClass.Append(scopeEnumeration);
843 // We extract the part after "::" (this is the enumerator name).
844 TString enumOnlyName = TClassEdit::GetUnqualifiedName(scopeEnumeration);
845 // The syntax is "Class::EnumeratorEnumerator
846 md5EnumClass.Append(enumOnlyName);
847 }
848 // The next part of the URL is hashed "@ scopeName::EnumeratorEnumerator".
849 TString md5Enumerator("@ ");
850 md5Enumerator.Append(scopeName);
851 md5Enumerator.Append("::");
852 md5Enumerator.Append(dataMemberName);
853 md5Enumerator.Append(dataMemberName);
854 // We make the URL for the "scopeName".
855 TString url = UrlGenerator(scopeName, scopeType);
856 // Then we have to append the hashed text for the enumerator.
857 url.Append("#a");
858 url.Append(md5EnumClass.MD5());
859 // We append "a" and then the next hashed text.
860 url.Append("a");
861 url.Append(md5Enumerator.MD5());
862 return url;
863}
864} // namespace
865
866namespace {
867////////////////////////////////////////////////////////////////////////////////
868/// The function generates URL for enumeration. The hashed text consist of:
869/// "Class::EnumerationEnumeration".
870///
871/// \param[in] scopeName the name of the class/namespace/struct
872/// \param[in] enumeration the name of the enumeration
873/// \param[in] scopeType enumerator for class/namespace/struct
874
875static TString GetUrlForEnumeration(TString scopeName, const TString &enumeration, EUrl scopeType)
876{
877 // The URL consists of URL for the "scopeName", "#a" and hashed as MD5 text.
878 // The text is "Class::EnumerationEnumeration.
879 TString md5Enumeration(scopeName);
880 md5Enumeration.Append("::");
881 md5Enumeration.Append(enumeration);
882 md5Enumeration.Append(enumeration);
883 // We make the URL for the scope "scopeName".
884 TString url(UrlGenerator(scopeName, scopeType));
885 // Then we have to append "#a" and the hashed text.
886 url.Append("#a");
887 url.Append(md5Enumeration.MD5());
888 return url;
889}
890} // namespace
891
892namespace {
893enum EMethodKind { kURLforMethod, kURLforStructor };
894////////////////////////////////////////////////////////////////////////////////
895/// The function generates URL for any member function (including Constructor/
896/// Destructor) of "scopeName". Doxygen first generates the URL for the scope.
897/// We do that with the help of "UrlGenerator". Then we append "#a" and a
898/// hashed with MD5 text. It consists of:
899/// "ReturnType ScopeName::MethodNameMethodName(Method arguments)".
900/// For constructor/destructor of a class, the return type is not appended.
901///
902/// \param[in] scopeName the name of the class/namespace/struct
903/// \param[in] methodName the name of the method from the scope
904/// \param[in] func pointer to the method
905/// \param[in] methodType enumerator for method or constructor
906/// \param[in] scopeType enumerator for class/namespace/struct
907
908static TString GetUrlForMethod(const TString &scopeName, const TString &methodName, TFunction *func,
909 EMethodKind methodType, EUrl scopeType)
910{
911 TString md5Text;
912 if (methodType == kURLforMethod) {
913 // In the case of method, we append the return type too.
914 // "FormatReturnTypeForDoxygen" modifies the return type with respect to Doxygen's requirement.
915 md5Text.Append((FormatReturnTypeForDoxygen(scopeName, func)));
916 if (scopeType == kURLforNameSpace) {
917 // We need to append "constexpr" if we work with constexpr functions in namespaces.
918 if (func->Property() & kIsConstexpr) {
919 md5Text.Prepend("constexpr ");
920 }
921 }
922 md5Text.Append(" ");
923 }
924 // We append ScopeName::MethodNameMethodName.
925 md5Text.Append(scopeName);
926 md5Text.Append("::");
927 md5Text.Append(methodName);
928 md5Text.Append(methodName);
929 // We use "FormatMethodArgsForDoxygen" to modify the arguments of Method with respect of Doxygen.
930 md5Text.Append(FormatMethodArgsForDoxygen(scopeName, func));
931 // We generate the URL for the class/namespace/struct.
932 TString url = UrlGenerator(scopeName, scopeType);
933 url.Append("#a");
934 // We append the hashed text.
935 url.Append(md5Text.MD5());
936 return url;
937}
938} // namespace
939
940
941////////////////////////////////////////////////////////////////////////////////
942/// It opens the online reference guide, generated with Doxygen, for the
943/// chosen scope (class/namespace/struct) or member (method/function/
944/// data member/enumeration/enumerator. If the user types incorrect value,
945/// it will return an error or warning.
946///
947/// \param[in] strippedClass the scope or scope::member
948
950{
951 // We check if the user is searching for a scope and if the scope exists.
952 if (TClass *clas = TClass::GetClass(strippedClass)) {
953 // We check what scope he is searching for (class/namespace/struct).
954 // Enumerators will switch between the possible cases.
955 EUrl scopeType;
956 if (clas->Property() & kIsNamespace) {
957 scopeType = kURLforNameSpace;
958 } else if (clas->Property() & kIsStruct) {
959 scopeType = kURLforStruct;
960 } else {
961 scopeType = kURLforClass;
962 }
963 // If the user search directly for a scope we open the URL for him with OpenInBrowser.
964 OpenInBrowser(UrlGenerator(strippedClass, scopeType));
965 return;
966 }
967 // Else we subtract the name of the method and remove it from the command.
968 TString memberName = TClassEdit::GetUnqualifiedName(strippedClass);
969 // Error out if "strippedClass" is un-scoped (and it's not a class, see `TClass::GetClass(strippedClass)` above).
970 // TODO: Global functions.
971 if (strippedClass == memberName) {
972 Error("OpenReferenceGuideFor", "Unknown entity \"%s\" - global variables / functions not supported yet!",
973 strippedClass.Data());
974 return;
975 }
976 // Else we remove the member name to be left with the scope.
977 TString scopeName = strippedClass(0, strippedClass.Length() - memberName.Length() - 2);
978 // We check if the scope exists in ROOT.
979 TClass *cl = TClass::GetClass(scopeName);
980 if (!cl) {
981 // That's a member of something ROOT doesn't know.
982 Warning("OpenReferenceGuideFor", "\"%s\" does not exist in ROOT!", scopeName.Data());
983 return;
984 }
985 // We have enumerators for the three available cases - class, namespace and struct.
986 EUrl scopeType;
987 if (cl->Property() & kIsNamespace) {
988 scopeType = kURLforNameSpace;
989 } else if (cl->Property() & kIsStruct) {
990 scopeType = kURLforStruct;
991 } else {
992 scopeType = kURLforClass;
993 }
994 // If the user wants to search for a method, we take its name (memberName) and
995 // modify it - we delete everything starting at the first "(" so the user won't have to
996 // do it by hand when they use Tab.
997 int bracket = memberName.First("(");
998 if (bracket > 0) {
999 memberName.Remove(bracket);
1000 }
1001 // We check if "memberName" is a member function of "cl" or any of its base classes.
1002 if (TFunction *func = cl->GetMethodAllAny(memberName)) {
1003 // If so we find the name of the class that it belongs to.
1004 TString baseClName = ((TMethod *)func)->GetClass()->GetName();
1005 // We define an enumerator to distinguish between structor and method.
1006 EMethodKind methodType;
1007 // We check if "memberName" is a constructor.
1008 if (baseClName == memberName) {
1009 methodType = kURLforStructor;
1010 // We check if "memberName" is a destructor.
1011 } else if (memberName[0] == '~') {
1012 methodType = kURLforStructor;
1013 // We check if "memberName" is a method.
1014 } else {
1015 methodType = kURLforMethod;
1016 }
1017 // We call "GetUrlForMethod" for the correct class and scope.
1018 OpenInBrowser(GetUrlForMethod(baseClName, memberName, func, methodType, scopeType));
1019 return;
1020 }
1021 // We check if "memberName" is an enumeration.
1022 if (cl->GetListOfEnums()->FindObject(memberName)) {
1023 // If so with OpenInBrowser we open the URL generated with GetUrlForEnumeration
1024 // with respect to the "scopeType".
1025 OpenInBrowser(GetUrlForEnumeration(scopeName, memberName, scopeType));
1026 return;
1027 }
1028
1029 // We check if "memberName" is enumerator defined in one the base classes of "scopeName".
1030 if (auto enumerator = (TDataMember *)cl->GetListOfAllPublicDataMembers()->FindObject(memberName)) {
1031 // We find the actual scope (might be in a base) and open the URL in a browser.
1032 TString baseClName = ((TMethod *)enumerator->GetClass())->GetName();
1033 OpenInBrowser(GetUrlForDataMember(baseClName, memberName, enumerator, scopeType));
1034 return;
1035 }
1036
1037 // Warning message will appear if the user types the function name incorrectly
1038 // or the function is not a member function of "cl" or any of its base classes.
1039 Warning("Help", "cannot find \"%s\" as member of %s or its base classes! Check %s\n", memberName.Data(),
1040 scopeName.Data(), UrlGenerator(scopeName, scopeType).Data());
1041}
1042
1043////////////////////////////////////////////////////////////////////////////////
1044/// The function lists useful commands (".help") or opens the online reference
1045/// guide, generated with Doxygen (".help scope" or ".help scope::member").
1046/// \note You can use ".?" as the short version of ".help"
1047/// \param[in] line command from the command line
1048
1049void TApplication::Help(const char *line)
1050{
1051 // We first check if the user wants to print the help on the interpreter.
1052 TString strippedCommand = TString(line).Strip(TString::kBoth);
1053 // If the user chooses ".help" or ".?".
1054 if ((strippedCommand == ".help") || (strippedCommand == ".?")) {
1055 gInterpreter->ProcessLine(line);
1056 Printf("\n ROOT special commands.");
1057 Printf(" ==============================================================================");
1058 Printf(" .L <filename>[flags]: load the given file with optional flags like\n"
1059 " + to compile or ++ to force recompile.\n"
1060 " Type .? TSystem::CompileMacro for a list of all flags.");
1061 Printf(" .(x|X) <filename>[flags](args) :\n"
1062 " same as .L <filename>[flags] and runs then a function\n"
1063 " with signature: ret_type filename(args).");
1064 Printf(" .credits : show credits");
1065 Printf(" .demo : launch GUI demo");
1066 Printf(" .help Class::Member : open reference guide for that class member (or .?).\n"
1067 " Specifying '::Member' is optional.");
1068 Printf(" .help edit : show line editing shortcuts (or .?)");
1069 Printf(" .license : show license");
1070 Printf(" .ls : list contents of current TDirectory");
1071 Printf(" .pwd : show current TDirectory, pad and style");
1072 Printf(" .quit (or .exit) : quit ROOT (long form of .q)");
1073 Printf(" .R [user@]host[:dir] [-l user] [-d dbg] [script] :\n"
1074 " launch process in a remote host");
1075 Printf(" .qqq : quit ROOT - mandatory");
1076 Printf(" .qqqqq : exit process immediately");
1077 Printf(" .qqqqqqq : abort process");
1078 Printf(" .which [file] : show path of macro file");
1079 Printf(" .![OS_command] : execute OS-specific shell command");
1080 Printf(" .!root -? : print ROOT usage (CLI options)");
1081 return;
1082 } else {
1083 // If the user wants to use the extended ".help scopeName" command to access
1084 // the online reference guide, we first check if the command starts correctly.
1085 if ((!strippedCommand.BeginsWith(".help ")) && (!strippedCommand.BeginsWith(".? "))) {
1086 Error("Help", "Unknown command!");
1087 return;
1088 }
1089 // We remove the command ".help" or ".?" from the TString.
1090 if (strippedCommand.BeginsWith(".? ")) {
1091 strippedCommand.Remove(0, 3);
1092 } else {
1093 strippedCommand.Remove(0, 5);
1094 }
1095 // We strip the command line after removing ".help" or ".?".
1096 strippedCommand = strippedCommand.Strip(TString::kBoth);
1097
1098 if (strippedCommand == "edit") {
1099 Printf("\n ROOT terminal keyboard shortcuts (GNU-readline style).");
1100 #ifdef R__MACOSX
1101 #define FOOTNOTE " *"
1102 Printf("* Some of these commands might be intercepted by macOS predefined system shortcuts.");
1103 // https://apple.stackexchange.com/questions/18043/how-can-i-make-ctrlright-left-arrow-stop-changing-desktops-in-lion
1104 #else
1105 #define FOOTNOTE ""
1106 #endif
1107 Printf(" ==============================================================================");
1108 Printf(" Arrow_Left : move cursor left [Ctrl+B]");
1109 Printf(" Arrow_Right : move cursor right [Ctrl+F] [Ctrl+G]");
1110 #ifdef R__MACOSX
1111 Printf(" Fn+Arrow_Left : move cursor to beginning of line [Ctrl+A]");
1112 #else
1113 Printf(" Home : move cursor to beginning of line [Ctrl+A]");
1114 #endif
1115 #ifdef R__MACOSX
1116 Printf(" Fn+Arrow_Right : move cursor to end of line [Ctrl+E]");
1117 #else
1118 Printf(" End : move cursor to end of line [Ctrl+E]");
1119 #endif
1120 Printf(" Ctrl+Arrow_Left : jump to previous word [Esc,B] [Alt,B]" FOOTNOTE);
1121 Printf(" Ctrl+Arrow_Right : jump to next word [Esc,F] [Alt,F]" FOOTNOTE);
1122
1123 Printf(" Backspace : delete previous character [Ctrl+H]");
1124 Printf(" Del : delete next character [Ctrl+D]");
1125 Printf(" Esc,Backspace : delete previous word [Ctrl+W] [Esc,Ctrl+H] [Alt+Backspace] [Esc,Del] [Esc,Ctrl+Del]" FOOTNOTE);// Del is 0x7F on macOS
1126 Printf(" Ctrl+Del : delete next word [Esc,D] [Alt,D]" FOOTNOTE);
1127 Printf(" Ctrl+U : cut all characters between cursor and start of line");
1128 Printf(" Ctrl+K : cut all characters between cursor and end of line");
1129
1130 Printf(" Ctrl+T : transpose characters");
1131 Printf(" Esc,C : character to upper and jump to next word");
1132 Printf(" Esc,L : word to lower case and jump to its end");
1133 Printf(" Esc,U : word to upper case and jump to its end");
1134 Printf(" Ctrl+Shift+C : copy clipboard content");
1135 Printf(" Ctrl+Shift+V : paste clipboard content [Ctrl+Y] [Alt+Y]");
1136 #ifdef R__MACOSX
1137 Printf(" Fn+Enter : toggle overwrite mode");
1138 #else
1139 Printf(" Ins : toggle overwrite mode");
1140 #endif
1141
1142 Printf(" Ctrl+_ : undo last keypress action");
1143 Printf(" Tab : autocomplete command or print suggestions [Ctrl+I] [Esc,Tab]");
1144 Printf(" Enter : execute command [Ctrl+J] [Ctrl+M]");
1145 Printf(" Ctrl+L : clear prompt screen");
1146 Printf(" Ctrl+D : quit ROOT (if empty line)");
1147 Printf(" Ctrl+C : send kSigInt interrupt signal");
1148 Printf(" Ctrl+Z : send kSigStop pause job signal");
1149
1150 Printf(" Arrow_Down : navigate downwards in command history [Ctrl+N]");
1151 Printf(" Arrow_Up : navigate upwards in command history [Ctrl+P]");
1152 Printf(" Ctrl+R ; Ctrl+S : search command in your history by typing a string.\n"
1153 " Use Backspace if you mistyped (but not arrows).\n"
1154 " Press Ctrl+R (Ctrl+S) repeateadly to navigate matches in reverse (forward) order");
1155 Printf(" Arrow_Right : after Ctrl+R (Ctrl+S), select current match of the history search\n"
1156 " [Ctrl+O] [Enter] [Ctrl+J] [Ctrl+M] [Arrow_Left] [Esc,Esc].\n"
1157 " Use Ctrl+F or Ctrl+G to cancel search and revert original line");
1158
1159 return;
1160 }
1161 // We call the function what handles the extended ".help scopeName" command.
1162 OpenReferenceGuideFor(strippedCommand);
1163 }
1164}
1165
1166/// Load shared libs necessary for graphics. These libraries are only
1167/// loaded when gROOT->IsBatch() is kFALSE.
1168
1170{
1171 if (gROOT->IsBatch())
1172 return;
1173
1174 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualPad"))
1175 if (h->LoadPlugin() == -1)
1176 return;
1177
1178 TString name;
1179 TString title1 = "ROOT interface to ";
1180 TString nativex, title;
1181
1182#ifdef R__WIN32
1183 nativex = "win32gdk";
1184 name = "Win32gdk";
1185 title = title1 + "Win32gdk";
1186#elif defined(R__HAS_COCOA)
1187 nativex = "quartz";
1188 name = "quartz";
1189 title = title1 + "Quartz";
1190#else
1191 nativex = "x11";
1192 name = "X11";
1193 title = title1 + "X11";
1194#endif
1195
1196 TString guiBackend = gEnv->GetValue("Gui.Backend", "native");
1197 guiBackend.ToLower();
1198 if (guiBackend == "native") {
1199 guiBackend = nativex;
1200 } else {
1201 name = guiBackend;
1202 title = title1 + guiBackend;
1203 }
1204
1205 if (auto h = gROOT->GetPluginManager()->FindHandler("TVirtualX", guiBackend)) {
1206 if (h->LoadPlugin() == -1) {
1207 gROOT->SetBatch(kTRUE);
1208 return;
1209 }
1210 gVirtualX = (TVirtualX *) h->ExecPlugin(2, name.Data(), title.Data());
1212 }
1213
1214 TString guiFactory = gEnv->GetValue("Gui.Factory", "native");
1215 guiFactory.ToLower();
1216 if (guiFactory == "native")
1217 guiFactory = "root";
1218
1219 if (auto h = gROOT->GetPluginManager()->FindHandler("TGuiFactory", guiFactory)) {
1220 if (h->LoadPlugin() == -1) {
1221 gROOT->SetBatch(kTRUE);
1222 return;
1223 }
1224 gGuiFactory = (TGuiFactory *) h->ExecPlugin(0);
1225 }
1226}
1227
1228////////////////////////////////////////////////////////////////////////////////
1229/// Switch to batch mode.
1230
1232{
1233 gROOT->SetBatch();
1236#ifndef R__WIN32
1237 if (gVirtualX != gGXBatch) delete gVirtualX;
1238#endif
1240}
1241
1242////////////////////////////////////////////////////////////////////////////////
1243/// Parse the content of a line starting with ".R" (already stripped-off)
1244/// The format is
1245/// ~~~ {.cpp}
1246/// [user@]host[:dir] [-l user] [-d dbg] [script]
1247/// ~~~
1248/// The variable 'dir' is the remote directory to be used as working dir.
1249/// The username can be specified in two ways, "-l" having the priority
1250/// (as in ssh).
1251/// A 'dbg' value > 0 gives increasing verbosity.
1252/// The last argument 'script' allows to specify an alternative script to
1253/// be executed remotely to startup the session.
1254
1256 TString &hostdir, TString &user,
1257 Int_t &dbg, TString &script)
1258{
1259 if (!ln || strlen(ln) <= 0)
1260 return 0;
1261
1262 Int_t rc = 0;
1263 Bool_t isHostDir = kTRUE;
1264 Bool_t isScript = kFALSE;
1265 Bool_t isUser = kFALSE;
1266 Bool_t isDbg = kFALSE;
1267
1268 TString line(ln);
1269 TString tkn;
1270 Int_t from = 0;
1271 while (line.Tokenize(tkn, from, " ")) {
1272 if (tkn == "-l") {
1273 // Next is a user name
1274 isUser = kTRUE;
1275 } else if (tkn == "-d") {
1276 isDbg = kTRUE;
1277 } else if (tkn == "-close") {
1278 rc = 1;
1279 } else if (tkn.BeginsWith("-")) {
1280 ::Warning("TApplication::ParseRemoteLine","unknown option: %s", tkn.Data());
1281 } else {
1282 if (isUser) {
1283 user = tkn;
1284 isUser = kFALSE;
1285 } else if (isDbg) {
1286 dbg = tkn.Atoi();
1287 isDbg = kFALSE;
1288 } else if (isHostDir) {
1289 hostdir = tkn;
1290 hostdir.ReplaceAll(":","/");
1291 isHostDir = kFALSE;
1292 isScript = kTRUE;
1293 } else if (isScript) {
1294 // Add everything left
1295 script = tkn;
1296 script.Insert(0, "\"");
1297 script += "\"";
1298 // isScript = kFALSE; // [clang-tidy] never read
1299 break;
1300 }
1301 }
1302 }
1303
1304 // Done
1305 return rc;
1306}
1307
1308////////////////////////////////////////////////////////////////////////////////
1309/// Process the content of a line starting with ".R" (already stripped-off)
1310/// The format is
1311/// ~~~ {.cpp}
1312/// [user@]host[:dir] [-l user] [-d dbg] [script] | [host] -close
1313/// ~~~
1314/// The variable 'dir' is the remote directory to be used as working dir.
1315/// The username can be specified in two ways, "-l" having the priority
1316/// (as in ssh).
1317/// A 'dbg' value > 0 gives increasing verbosity.
1318/// The last argument 'script' allows to specify an alternative script to
1319/// be executed remotely to startup the session.
1320
1322{
1323 if (!line) return 0;
1324
1325 if (!strncmp(line, "-?", 2) || !strncmp(line, "-h", 2) ||
1326 !strncmp(line, "--help", 6)) {
1327 Info("ProcessRemote", "remote session help:");
1328 Printf(".R [user@]host[:dir] [-l user] [-d dbg] [[<]script] | [host] -close");
1329 Printf("Create a ROOT session on the specified remote host.");
1330 Printf("The variable \"dir\" is the remote directory to be used as working dir.");
1331 Printf("The username can be specified in two ways, \"-l\" having the priority");
1332 Printf("(as in ssh). A \"dbg\" value > 0 gives increasing verbosity.");
1333 Printf("The last argument \"script\" allows to specify an alternative script to");
1334 Printf("be executed remotely to startup the session, \"roots\" being");
1335 Printf("the default. If the script is preceded by a \"<\" the script will be");
1336 Printf("sourced, after which \"roots\" is executed. The sourced script can be ");
1337 Printf("used to change the PATH and other variables, allowing an alternative");
1338 Printf("\"roots\" script to be found.");
1339 Printf("To close down a session do \".R host -close\".");
1340 Printf("To switch between sessions do \".R host\", to switch to the local");
1341 Printf("session do \".R\".");
1342 Printf("To list all open sessions do \"gApplication->GetApplications()->Print()\".");
1343 return 0;
1344 }
1345
1346 TString hostdir, user, script;
1347 Int_t dbg = 0;
1348 Int_t rc = ParseRemoteLine(line, hostdir, user, dbg, script);
1349 if (hostdir.Length() <= 0) {
1350 // Close the remote application if required
1351 if (rc == 1) {
1353 delete fAppRemote;
1354 }
1355 // Return to local run
1356 fAppRemote = nullptr;
1357 // Done
1358 return 1;
1359 } else if (rc == 1) {
1360 // close an existing remote application
1361 TApplication *ap = TApplication::Open(hostdir, 0, nullptr);
1362 if (ap) {
1364 delete ap;
1365 }
1366 }
1367 // Attach or start a remote application
1368 if (user.Length() > 0)
1369 hostdir.Insert(0,Form("%s@", user.Data()));
1370 const char *sc = (script.Length() > 0) ? script.Data() : nullptr;
1371 TApplication *ap = TApplication::Open(hostdir, dbg, sc);
1372 if (ap) {
1373 fAppRemote = ap;
1374 }
1375
1376 // Done
1377 return 1;
1378}
1379
1380namespace {
1381 static int PrintFile(const char* filename) {
1382 TString sFileName(filename);
1383 gSystem->ExpandPathName(sFileName);
1384 if (gSystem->AccessPathName(sFileName)) {
1385 Error("ProcessLine()", "Cannot find file %s", filename);
1386 return 1;
1387 }
1388 std::ifstream instr(sFileName);
1389 TString content;
1390 content.ReadFile(instr);
1391 Printf("%s", content.Data());
1392 return 0;
1393 }
1394 } // namespace
1395
1396////////////////////////////////////////////////////////////////////////////////
1397/// Process a single command line, either a C++ statement or an interpreter
1398/// command starting with a ".".
1399/// Return the return value of the command cast to a long.
1400
1402{
1403 if (!line || !*line) return 0;
1404
1405 // If we are asked to go remote do it
1406 if (!strncmp(line, ".R", 2)) {
1407 Int_t n = 2;
1408 while (*(line+n) == ' ')
1409 n++;
1410 return ProcessRemote(line+n, err);
1411 }
1412
1413 // Redirect, if requested
1416 return fAppRemote->ProcessLine(line, err);
1417 }
1418
1419 if (!strncasecmp(line, ".qqqqqqq", 7)) {
1420 gSystem->Abort();
1421 } else if (!strncasecmp(line, ".qqqqq", 5)) {
1422 Info("ProcessLine", "Bye... (try '.qqqqqqq' if still running)");
1423 gSystem->Exit(1);
1424 } else if (!strncasecmp(line, ".exit", 4) || !strncasecmp(line, ".quit", 2)) {
1425 Terminate(0);
1426 return 0;
1427 }
1428
1429 if (!strncmp(line, ".?", 2) || !strncmp(line, ".help", 5)) {
1430 Help(line);
1431 return 1;
1432 }
1433
1434 if (!strncmp(line, ".demo", 5)) {
1435 if (gROOT->IsBatch()) {
1436 Error("ProcessLine", "Cannot show demos in batch mode!");
1437 return 1;
1438 }
1439 ProcessLine(".x " + TROOT::GetTutorialDir() + "/demos.C");
1440 return 0;
1441 }
1442
1443 if (!strncmp(line, ".license", 8)) {
1444 return PrintFile(TROOT::GetDocDir() + "/LICENSE");
1445 }
1446
1447 if (!strncmp(line, ".credits", 8)) {
1448 TString credits = TROOT::GetDocDir() + "/CREDITS";
1449 if (gSystem->AccessPathName(credits, kReadPermission))
1450 credits = TROOT::GetDocDir() + "/README/CREDITS";
1451 return PrintFile(credits);
1452 }
1453
1454 if (!strncmp(line, ".pwd", 4)) {
1455 if (gDirectory)
1456 Printf("Current directory: %s", gDirectory->GetPath());
1457 if (gPad)
1458 Printf("Current pad: %s", gPad->GetName());
1459 if (gStyle)
1460 Printf("Current style: %s", gStyle->GetName());
1461 return 1;
1462 }
1463
1464 if (!strncmp(line, ".ls", 3)) {
1465 const char *opt = nullptr;
1466 if (line[3]) opt = &line[3];
1467 if (gDirectory) gDirectory->ls(opt);
1468 return 1;
1469 }
1470
1471 if (!strncmp(line, ".which", 6)) {
1472 char *fn = Strip(line+7);
1473 char *s = strtok(fn, "+("); // this method does not need to be reentrant
1475 if (!mac)
1476 Printf("No macro %s in path %s", s, TROOT::GetMacroPath());
1477 else
1478 Printf("%s", mac);
1479 delete [] fn;
1480 delete [] mac;
1481 return mac ? 1 : 0;
1482 }
1483
1484 if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2)) {
1485 TString aclicMode, arguments, io;
1486 TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
1487
1488 char *mac = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
1489 if (arguments.Length())
1490 Warning("ProcessLine", "argument(s) \"%s\" ignored with .%c", arguments.Data(), line[1]);
1491 Longptr_t retval = 0;
1492 if (!mac) {
1493 Error("ProcessLine", "macro %s not found in path %s", fname.Data(), TROOT::GetMacroPath());
1494 } else {
1495 TString cmd(line + 1);
1496 Ssiz_t posSpace = cmd.Index(' ');
1497 if (posSpace == kNPOS)
1498 cmd.Remove(1);
1499 else
1500 cmd.Remove(posSpace);
1501 auto tempbuf = TString::Format(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(), io.Data());
1502 delete[] mac;
1503 if (sync)
1504 retval = gInterpreter->ProcessLineSynch(tempbuf.Data(), (TInterpreter::EErrorCode *)err);
1505 else
1506 retval = gInterpreter->ProcessLine(tempbuf.Data(), (TInterpreter::EErrorCode *)err);
1507 }
1508
1509 InitializeGraphics(gROOT->IsWebDisplay());
1510
1511 return retval;
1512 }
1513
1514 if (!strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
1515 return ProcessFile(line+3, err, line[2] == 'k');
1516 }
1517
1518 if (!strcmp(line, ".reset")) {
1519 // Do nothing, .reset disabled in Cling because too many side effects
1520 Printf("*** .reset not allowed, please use gROOT->Reset() ***");
1521 return 0;
1522
1523#if 0
1524 // delete the ROOT dictionary since CINT will destroy all objects
1525 // referenced by the dictionary classes (TClass et. al.)
1526 gROOT->GetListOfClasses()->Delete();
1527 // fall through
1528#endif
1529 }
1530
1531 if (sync)
1532 return gInterpreter->ProcessLineSynch(line, (TInterpreter::EErrorCode*)err);
1533 else
1534 return gInterpreter->ProcessLine(line, (TInterpreter::EErrorCode*)err);
1535}
1536
1537////////////////////////////////////////////////////////////////////////////////
1538/// Process a file containing a C++ macro.
1539
1541{
1542 return ExecuteFile(file, error, keep);
1543}
1544
1545////////////////////////////////////////////////////////////////////////////////
1546/// Execute a file containing a C++ macro (static method). Can be used
1547/// while TApplication is not yet created.
1548
1550{
1551 static const Int_t kBufSize = 1024;
1552
1553 if (!file || !*file) return 0;
1554
1555 TString aclicMode;
1556 TString arguments;
1557 TString io;
1558 TString fname = gSystem->SplitAclicMode(file, aclicMode, arguments, io);
1559
1560 char *exnam = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
1561 if (!exnam) {
1562 ::Error("TApplication::ExecuteFile", "macro %s not found in path %s", fname.Data(),
1564 delete [] exnam;
1565 if (error)
1567 return 0;
1568 }
1569
1570 ::std::ifstream macro(exnam, std::ios::in);
1571 if (!macro.good()) {
1572 ::Error("TApplication::ExecuteFile", "%s no such file", exnam);
1573 if (error)
1575 delete [] exnam;
1576 return 0;
1577 }
1578
1579 char currentline[kBufSize];
1580 char dummyline[kBufSize];
1581 int tempfile = 0;
1582 int comment = 0;
1583 int ifndefc = 0;
1584 int ifdef = 0;
1585 char *s = nullptr;
1586 Bool_t execute = kFALSE;
1587 Longptr_t retval = 0;
1588
1589 while (1) {
1590 bool res = (bool)macro.getline(currentline, kBufSize);
1591 if (macro.eof()) break;
1592 if (!res) {
1593 // Probably only read kBufSize, let's ignore the remainder of
1594 // the line.
1595 macro.clear();
1596 while (!macro.getline(dummyline, kBufSize) && !macro.eof()) {
1597 macro.clear();
1598 }
1599 }
1600 s = currentline;
1601 while (s && (*s == ' ' || *s == '\t')) s++; // strip-off leading blanks
1602
1603 // very simple minded pre-processor parsing, only works in case macro file
1604 // starts with "#ifndef __CINT__". In that case everything till next
1605 // "#else" or "#endif" will be skipped.
1606 if (*s == '#') {
1607 char *cs = Compress(currentline);
1608 if (strstr(cs, "#ifndef__CINT__") ||
1609 strstr(cs, "#if!defined(__CINT__)"))
1610 ifndefc = 1;
1611 else if (ifndefc && (strstr(cs, "#ifdef") || strstr(cs, "#ifndef") ||
1612 strstr(cs, "#ifdefined") || strstr(cs, "#if!defined")))
1613 ifdef++;
1614 else if (ifndefc && strstr(cs, "#endif")) {
1615 if (ifdef)
1616 ifdef--;
1617 else
1618 ifndefc = 0;
1619 } else if (ifndefc && !ifdef && strstr(cs, "#else"))
1620 ifndefc = 0;
1621 delete [] cs;
1622 }
1623 if (!*s || *s == '#' || ifndefc || !strncmp(s, "//", 2)) continue;
1624
1625 if (!comment && (!strncmp(s, ".X", 2) || !strncmp(s, ".x", 2))) {
1626 retval = ExecuteFile(s+3);
1627 execute = kTRUE;
1628 continue;
1629 }
1630
1631 if (!strncmp(s, "/*", 2)) comment = 1;
1632 if (comment) {
1633 // handle slightly more complex cases like: /* */ /*
1634again:
1635 s = strstr(s, "*/");
1636 if (s) {
1637 comment = 0;
1638 s += 2;
1639
1640 while (s && (*s == ' ' || *s == '\t')) s++; // strip-off leading blanks
1641 if (!*s) continue;
1642 if (!strncmp(s, "//", 2)) continue;
1643 if (!strncmp(s, "/*", 2)) {
1644 comment = 1;
1645 goto again;
1646 }
1647 }
1648 }
1649 if (!comment && *s == '{') tempfile = 1;
1650 if (!comment) break;
1651 }
1652 macro.close();
1653
1654 if (!execute) {
1655 TString exname = exnam;
1656 if (!tempfile) {
1657 // We have a script that does NOT contain an unnamed macro,
1658 // so we can call the script compiler on it.
1659 exname += aclicMode;
1660 }
1661 exname += arguments;
1662 exname += io;
1663
1664 TString tempbuf;
1665 if (tempfile) {
1666 tempbuf.Form(".x %s", exname.Data());
1667 } else {
1668 tempbuf.Form(".X%s %s", keep ? "k" : " ", exname.Data());
1669 }
1670 retval = gInterpreter->ProcessLineSynch(tempbuf,(TInterpreter::EErrorCode*)error);
1671 }
1672
1673 delete [] exnam;
1674 return retval;
1675}
1676
1677////////////////////////////////////////////////////////////////////////////////
1678/// Main application eventloop. Calls system dependent eventloop via gSystem.
1679
1681{
1682 SetReturnFromRun(retrn);
1683
1684 fIsRunning = kTRUE;
1685
1686 gSystem->Run();
1688}
1689
1690////////////////////////////////////////////////////////////////////////////////
1691/// Set the command to be executed after the system has been idle for
1692/// idleTimeInSec seconds. Normally called via TROOT::Idle(...).
1693
1694void TApplication::SetIdleTimer(UInt_t idleTimeInSec, const char *command)
1695{
1697 fIdleCommand = command;
1698 fIdleTimer = new TIdleTimer(idleTimeInSec*1000);
1700}
1701
1702////////////////////////////////////////////////////////////////////////////////
1703/// Remove idle timer. Normally called via TROOT::Idle(0).
1704
1706{
1707 if (fIdleTimer) {
1708 // timers are removed from the gSystem timer list by their dtor
1710 }
1711}
1712
1713////////////////////////////////////////////////////////////////////////////////
1714/// Called when system starts idleing.
1715
1717{
1718 if (fIdleTimer) {
1719 fIdleTimer->Reset();
1721 }
1722}
1723
1724////////////////////////////////////////////////////////////////////////////////
1725/// Called when system stops idleing.
1726
1728{
1729 if (fIdleTimer)
1731}
1732
1733////////////////////////////////////////////////////////////////////////////////
1734/// What to do when tab is pressed. Re-implemented by TRint.
1735/// See TTabCom::Hook() for meaning of return values.
1736
1737Int_t TApplication::TabCompletionHook(char* /*buf*/, int* /*pLoc*/, std::ostream& /*out*/)
1738{
1739 return -1;
1740}
1741
1742
1743////////////////////////////////////////////////////////////////////////////////
1744/// Terminate the application by call TSystem::Exit() unless application has
1745/// been told to return from Run(), by a call to SetReturnFromRun().
1746
1748{
1749 Emit("Terminate(Int_t)", status);
1750
1751 if (fReturnFromRun)
1752 gSystem->ExitLoop();
1753 else {
1754 gSystem->Exit(status);
1755 }
1756}
1757
1758////////////////////////////////////////////////////////////////////////////////
1759/// Emit signal when a line has been processed.
1760
1762{
1763 Emit("LineProcessed(const char*)", line);
1764}
1765
1766////////////////////////////////////////////////////////////////////////////////
1767/// Emit signal when console keyboard key was pressed.
1768
1770{
1771 Emit("KeyPressed(Int_t)", key);
1772}
1773
1774////////////////////////////////////////////////////////////////////////////////
1775/// Emit signal when return key was pressed.
1776
1778{
1779 Emit("ReturnPressed(char*)", text);
1780}
1781
1782////////////////////////////////////////////////////////////////////////////////
1783/// Set console echo mode:
1784///
1785/// - mode = kTRUE - echo input symbols
1786/// - mode = kFALSE - noecho input symbols
1787
1789{
1790}
1791
1792////////////////////////////////////////////////////////////////////////////////
1793/// Static function used to create a default application environment.
1794
1796{
1798 // gApplication is set at the end of 'new TApplication.
1799 if (!gApplication) {
1800 char *a = StrDup("RootApp");
1801 char *b = StrDup("-b");
1802 char *argv[2];
1803 Int_t argc = 2;
1804 argv[0] = a;
1805 argv[1] = b;
1806 new TApplication("RootApp", &argc, argv, nullptr, 0);
1807 if (gDebug > 0)
1808 Printf("<TApplication::CreateApplication>: "
1809 "created default TApplication");
1810 delete [] a; delete [] b;
1812 }
1813}
1814
1815////////////////////////////////////////////////////////////////////////////////
1816/// Static function used to attach to an existing remote application
1817/// or to start one.
1818
1820 Int_t debug, const char *script)
1821{
1822 TApplication *ap = nullptr;
1823 TUrl nu(url);
1824 Int_t nnew = 0;
1825
1826 // Look among the existing ones
1827 if (fgApplications) {
1828 TIter nxa(fgApplications);
1829 while ((ap = (TApplication *) nxa())) {
1830 TString apn(ap->ApplicationName());
1831 if (apn == url) {
1832 // Found matching application
1833 return ap;
1834 } else {
1835 // Check if same machine and user
1836 TUrl au(apn);
1837 if (strlen(au.GetUser()) > 0 && strlen(nu.GetUser()) > 0 &&
1838 !strcmp(au.GetUser(), nu.GetUser())) {
1839 if (!strncmp(au.GetHost(), nu.GetHost(), strlen(nu.GetHost())))
1840 // New session on a known machine
1841 nnew++;
1842 }
1843 }
1844 }
1845 } else {
1846 ::Error("TApplication::Open", "list of applications undefined - protocol error");
1847 return ap;
1848 }
1849
1850 // If new session on a known machine pass the number as option
1851 if (nnew > 0) {
1852 nnew++;
1853 nu.SetOptions(TString::Format("%d", nnew).Data());
1854 }
1855
1856 // Instantiate the TApplication object to be run
1857 TPluginHandler *h = nullptr;
1858 if ((h = gROOT->GetPluginManager()->FindHandler("TApplication","remote"))) {
1859 if (h->LoadPlugin() == 0) {
1860 ap = (TApplication *) h->ExecPlugin(3, nu.GetUrl(), debug, script);
1861 } else {
1862 ::Error("TApplication::Open", "failed to load plugin for TApplicationRemote");
1863 }
1864 } else {
1865 ::Error("TApplication::Open", "failed to find plugin for TApplicationRemote");
1866 }
1867
1868 // Add to the list
1869 if (ap && !(ap->TestBit(kInvalidObject))) {
1870 fgApplications->Add(ap);
1871 gROOT->GetListOfBrowsables()->Add(ap, ap->ApplicationName());
1872 TIter next(gROOT->GetListOfBrowsers());
1873 TBrowser *b;
1874 while ((b = (TBrowser*) next()))
1875 b->Add(ap, ap->ApplicationName());
1876 gROOT->RefreshBrowsers();
1877 } else {
1878 SafeDelete(ap);
1879 ::Error("TApplication::Open",
1880 "TApplicationRemote for %s could not be instantiated", url);
1881 }
1882
1883 // Done
1884 return ap;
1885}
1886
1887////////////////////////////////////////////////////////////////////////////////
1888/// Static function used to close a remote application
1889
1891{
1892 if (app) {
1893 app->Terminate(0);
1894 fgApplications->Remove(app);
1895 gROOT->GetListOfBrowsables()->RecursiveRemove(app);
1896 TIter next(gROOT->GetListOfBrowsers());
1897 TBrowser *b;
1898 while ((b = (TBrowser*) next()))
1899 b->RecursiveRemove(app);
1900 gROOT->RefreshBrowsers();
1901 }
1902}
1903
1904////////////////////////////////////////////////////////////////////////////////
1905/// Show available sessions
1906
1908{
1909 if (fgApplications) {
1910 TIter nxa(fgApplications);
1911 TApplication *a = nullptr;
1912 while ((a = (TApplication *) nxa())) {
1913 a->Print(opt);
1914 }
1915 } else {
1916 Print(opt);
1917 }
1918}
1919
1920////////////////////////////////////////////////////////////////////////////////
1921/// Static method returning the list of available applications
1922
1924{
1925 return fgApplications;
1926}
#define SafeDelete(p)
Definition RConfig.hxx:540
#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
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
long Long_t
Definition RtypesCore.h:54
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
static void CallEndOfProcessCleanups()
#define FOOTNOTE
TApplication * gApplication
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:97
@ 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:386
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:197
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.
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 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:376
Int_t gDebug
Definition TROOT.cxx:585
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:405
char * Compress(const char *str)
Remove all blanks from the string str.
Definition TString.cxx:2550
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
char * Strip(const char *str, char c=' ')
Strip leading and trailing c (blanks by default) from a string.
Definition TString.cxx:2499
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2481
char * StrDup(const char *str)
Duplicate the string str.
Definition TString.cxx:2535
R__EXTERN TStyle * gStyle
Definition TStyle.h:414
@ kReadPermission
Definition TSystem.h:47
R__EXTERN TSystem * gSystem
Definition TSystem.h:560
#define R__LOCKGUARD(mutex)
#define gPad
#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...
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.
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 const char * ApplicationName() const
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.
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.
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.
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:406
void Add(TObject *obj, const char *name=nullptr, Int_t check=-1)
Add object with name to browser.
Definition TBrowser.cxx:301
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:3862
TList * GetListOfEnums(Bool_t load=kTRUE)
Return a list containing the TEnums of a class.
Definition TClass.cxx:3686
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6086
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
Definition TClass.cxx:4384
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:2968
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*".
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:379
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.
void Delete(Option_t *option="") override
Remove all objects from the array AND delete all heap based objects.
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:439
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition TObject.cxx:653
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:956
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:774
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:970
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:998
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:630
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:944
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:2729
static void ShutDown()
Shut down ROOT.
Definition TROOT.cxx:3068
static const TString & GetTTFFontDir()
Get the fonts directory in the installation. Static utility function.
Definition TROOT.cxx:3121
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition TROOT.cxx:2849
static const TString & GetTutorialDir()
Get the tutorials directory in the installation. Static utility function.
Definition TROOT.cxx:3047
static const TString & GetDocDir()
Get the documentation directory in the installation. Static utility function.
Definition TROOT.cxx:3010
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:421
void ToLower()
Change string to lower-case.
Definition TString.cxx:1170
TString & Insert(Ssiz_t pos, const char *s)
Definition TString.h:661
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1966
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2222
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition TString.cxx:1151
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:694
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition TString.cxx:531
const char * Data() const
Definition TString.h:380
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
TString MD5() const
Return the MD5 digest for this string, in a string representation.
Definition TString.cxx:933
@ kBoth
Definition TString.h:278
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:627
TString & Prepend(const char *cs)
Definition TString.h:673
Bool_t IsNull() const
Definition TString.h:418
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:685
TString & Append(const char *cs)
Definition TString.h:576
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:2356
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2334
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
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:1277
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1666
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4251
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition TSystem.cxx:656
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:1401
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:1299
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:865
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:874
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1549
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:3868
virtual void Abort(int code=0)
Abort the application.
Definition TSystem.cxx:728
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
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()
Enable support for multi-threading within the ROOT code in particular, enables the global mutex to ma...
Definition TROOT.cxx:493
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
Definition file.py:1