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