00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "RConfigure.h"
00025 #include "Riostream.h"
00026 #include "TApplication.h"
00027 #include "TException.h"
00028 #include "TGuiFactory.h"
00029 #include "TVirtualX.h"
00030 #include "TROOT.h"
00031 #include "TSystem.h"
00032 #include "TString.h"
00033 #include "TError.h"
00034 #include "TObjArray.h"
00035 #include "TObjString.h"
00036 #include "TTimer.h"
00037 #include "TInterpreter.h"
00038 #include "TStyle.h"
00039 #include "TVirtualPad.h"
00040 #include "TEnv.h"
00041 #include "TColor.h"
00042 #include "TClassTable.h"
00043 #include "TPluginManager.h"
00044 #include "TClassTable.h"
00045 #include "TBrowser.h"
00046 #include "TUrl.h"
00047
00048 TApplication *gApplication = 0;
00049 Bool_t TApplication::fgGraphNeeded = kFALSE;
00050 Bool_t TApplication::fgGraphInit = kFALSE;
00051 TList *TApplication::fgApplications = 0;
00052
00053
00054 class TIdleTimer : public TTimer {
00055 public:
00056 TIdleTimer(Long_t ms) : TTimer(ms, kTRUE) { }
00057 Bool_t Notify();
00058 };
00059
00060
00061 Bool_t TIdleTimer::Notify()
00062 {
00063
00064 gApplication->HandleIdleTimer();
00065 Reset();
00066 return kFALSE;
00067 }
00068
00069
00070 ClassImp(TApplication)
00071
00072
00073 TApplication::TApplication()
00074 {
00075
00076
00077 fArgc = 0;
00078 fArgv = 0;
00079 fAppImp = 0;
00080 fAppRemote = 0;
00081 fIsRunning = kFALSE;
00082 fReturnFromRun = kFALSE;
00083 fNoLog = kFALSE;
00084 fNoLogo = kFALSE;
00085 fQuit = kFALSE;
00086 fUseMemstat = kFALSE;
00087 fFiles = 0;
00088 fIdleTimer = 0;
00089 fSigHandler = 0;
00090 fExitOnException = kDontExit;
00091 ResetBit(kProcessRemotely);
00092 }
00093
00094
00095 TApplication::TApplication(const char *appClassName,
00096 Int_t *argc, char **argv, void *options,
00097 Int_t numOptions)
00098 {
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 if (gApplication && gApplication->TestBit(kDefaultApplication)) {
00113
00114 delete gApplication;
00115 gApplication = 0;
00116 gROOT->SetBatch(kFALSE);
00117 fgGraphInit = kFALSE;
00118 }
00119
00120 if (gApplication) {
00121 Error("TApplication", "only one instance of TApplication allowed");
00122 return;
00123 }
00124
00125 if (!gROOT)
00126 ::Fatal("TApplication::TApplication", "ROOT system not initialized");
00127
00128 if (!gSystem)
00129 ::Fatal("TApplication::TApplication", "gSystem not initialized");
00130
00131 gApplication = this;
00132 gROOT->SetApplication(this);
00133 gROOT->SetName(appClassName);
00134
00135
00136 if (!fgApplications)
00137 fgApplications = new TList;
00138 fgApplications->Add(this);
00139
00140 if (options) { }
00141
00142
00143 if (argc && *argc > 0) {
00144 fArgc = *argc;
00145 fArgv = (char **)new char*[fArgc];
00146 } else {
00147 fArgc = 0;
00148 fArgv = 0;
00149 }
00150
00151 for (int i = 0; i < fArgc; i++)
00152 fArgv[i] = StrDup(argv[i]);
00153
00154 fNoLog = kFALSE;
00155 fNoLogo = kFALSE;
00156 fQuit = kFALSE;
00157 fUseMemstat = kFALSE;
00158 fExitOnException = kDontExit;
00159 fAppImp = 0;
00160
00161 if (numOptions >= 0)
00162 GetOptions(argc, argv);
00163
00164 if (fArgv)
00165 gSystem->SetProgname(fArgv[0]);
00166
00167
00168 gSystem->NotifyApplicationCreated();
00169
00170 fIdleTimer = 0;
00171 fSigHandler = 0;
00172 fIsRunning = kFALSE;
00173 fReturnFromRun = kFALSE;
00174 fAppImp = gGuiFactory->CreateApplicationImp(appClassName, argc, argv);
00175 fAppRemote = 0;
00176 ResetBit(kProcessRemotely);
00177
00178
00179 gInterpreter->EnableAutoLoading();
00180
00181
00182 if (gClassTable->GetDict("TPad")) {
00183 fgGraphNeeded = kTRUE;
00184 InitializeGraphics();
00185 }
00186
00187
00188
00189 gInterpreter->InitializeDictionaries();
00190 gInterpreter->UpdateListOfTypes();
00191
00192
00193 gInterpreter->SaveContext();
00194 gInterpreter->SaveGlobalsContext();
00195
00196
00197 gROOT->SetLineHasBeenProcessed();
00198
00199
00200 if (fUseMemstat || gEnv->GetValue("Root.TMemStat", 0)) {
00201 fUseMemstat = kTRUE;
00202 Int_t buffersize = gEnv->GetValue("Root.TMemStat.buffersize", 100000);
00203 Int_t maxcalls = gEnv->GetValue("Root.TMemStat.maxcalls", 5000000);
00204 const char *ssystem = gEnv->GetValue("Root.TMemStat.system","gnubuiltin");
00205 if (maxcalls > 0) {
00206 gROOT->ProcessLine(Form("new TMemStat(\"%s\",%d,%d);",ssystem,buffersize,maxcalls));
00207 }
00208 }
00209 }
00210
00211
00212 TApplication::~TApplication()
00213 {
00214
00215
00216 for (int i = 0; i < fArgc; i++)
00217 if (fArgv[i]) delete [] fArgv[i];
00218 delete [] fArgv;
00219 SafeDelete(fAppImp);
00220 if (fgApplications)
00221 fgApplications->Remove(this);
00222
00223
00224 if (fUseMemstat) {
00225 ProcessLine("TMemStat::Close()");
00226 fUseMemstat = kFALSE;
00227 }
00228 }
00229
00230
00231 void TApplication::NeedGraphicsLibs()
00232 {
00233
00234
00235
00236 fgGraphNeeded = kTRUE;
00237 }
00238
00239
00240 void TApplication::InitializeGraphics()
00241 {
00242
00243
00244 if (fgGraphInit || !fgGraphNeeded)
00245 return;
00246
00247 fgGraphInit = kTRUE;
00248
00249
00250 LoadGraphicsLibs();
00251
00252
00253
00254
00255 const char *ttpath = gEnv->GetValue("Root.TTFontPath",
00256 #ifdef TTFFONTDIR
00257 TTFFONTDIR);
00258 #else
00259 "$(ROOTSYS)/fonts");
00260 #endif
00261 char *ttfont = gSystem->Which(ttpath, "arialbd.ttf", kReadPermission);
00262
00263 if (!ttfont)
00264 ttfont = gSystem->Which(ttpath, "FreeSansBold.ttf", kReadPermission);
00265
00266 #if !defined(R__WIN32)
00267 if (!gROOT->IsBatch() && !strcmp(gVirtualX->GetName(), "X11") &&
00268 ttfont && gEnv->GetValue("Root.UseTTFonts", 1)) {
00269 if (gClassTable->GetDict("TGX11TTF")) {
00270
00271
00272
00273 ProcessLine("TGX11TTF::Activate();");
00274 } else {
00275 TPluginHandler *h;
00276 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", "x11ttf")))
00277 if (h->LoadPlugin() == -1)
00278 Info("InitializeGraphics", "no TTF support");
00279 }
00280 }
00281 #endif
00282 delete [] ttfont;
00283
00284
00285 if (fAppImp)
00286 delete fAppImp;
00287 fAppImp = gGuiFactory->CreateApplicationImp(gROOT->GetName(), &fArgc, fArgv);
00288 if (!fAppImp) {
00289 MakeBatch();
00290 fAppImp = gGuiFactory->CreateApplicationImp(gROOT->GetName(), &fArgc, fArgv);
00291 }
00292
00293
00294
00295
00296 TColor::InitializeColors();
00297
00298
00299 Init();
00300
00301
00302 if (gEnv->GetValue("Canvas.UseScreenFactor", 1)) {
00303 Int_t x, y;
00304 UInt_t w, h;
00305 if (gVirtualX) {
00306 gVirtualX->GetGeometry(-1, x, y, w, h);
00307 if (h > 0 && h < 1000) gStyle->SetScreenFactor(0.0011*h);
00308 }
00309 }
00310 }
00311
00312
00313 void TApplication::ClearInputFiles()
00314 {
00315
00316
00317
00318
00319 if (fFiles) {
00320 fFiles->Delete();
00321 SafeDelete(fFiles);
00322 }
00323 }
00324
00325
00326 char *TApplication::Argv(Int_t index) const
00327 {
00328
00329
00330 if (fArgv) {
00331 if (index >= fArgc) {
00332 Error("Argv", "index (%d) >= number of arguments (%d)", index, fArgc);
00333 return 0;
00334 }
00335 return fArgv[index];
00336 }
00337 return 0;
00338 }
00339
00340
00341 void TApplication::GetOptions(Int_t *argc, char **argv)
00342 {
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 static char null[1] = { "" };
00374
00375 fNoLog = kFALSE;
00376 fQuit = kFALSE;
00377 fFiles = 0;
00378
00379 if (!argc)
00380 return;
00381
00382 int i, j;
00383 TString pwd;
00384
00385 for (i = 1; i < *argc; i++) {
00386 if (!strcmp(argv[i], "-?") || !strncmp(argv[i], "-h", 2) ||
00387 !strncmp(argv[i], "--help", 6)) {
00388 fprintf(stderr, "Usage: %s [-l] [-b] [-n] [-q] [dir] [[file:]data.root] [file1.C ... fileN.C]\n", argv[0]);
00389 fprintf(stderr, "Options:\n");
00390 fprintf(stderr, " -b : run in batch mode without graphics\n");
00391 fprintf(stderr, " -x : exit on exception\n");
00392 fprintf(stderr, " -n : do not execute logon and logoff macros as specified in .rootrc\n");
00393 fprintf(stderr, " -q : exit after processing command line macro files\n");
00394 fprintf(stderr, " -l : do not show splash screen\n");
00395 fprintf(stderr, " dir : if dir is a valid directory cd to it before executing\n");
00396 fprintf(stderr, "\n");
00397 fprintf(stderr, " -? : print usage\n");
00398 fprintf(stderr, " -h : print usage\n");
00399 fprintf(stderr, " --help : print usage\n");
00400 fprintf(stderr, " -config : print ./configure options\n");
00401 fprintf(stderr, " -memstat : run with memory usage monitoring\n");
00402 fprintf(stderr, "\n");
00403 Terminate(0);
00404 } else if (!strcmp(argv[i], "-config")) {
00405 fprintf(stderr, "ROOT ./configure options:\n%s\n", gROOT->GetConfigOptions());
00406 Terminate(0);
00407 } else if (!strcmp(argv[i], "-memstat")) {
00408 fUseMemstat = kTRUE;
00409 argv[i] = null;
00410 } else if (!strcmp(argv[i], "-b")) {
00411 MakeBatch();
00412 argv[i] = null;
00413 } else if (!strcmp(argv[i], "-n")) {
00414 fNoLog = kTRUE;
00415 argv[i] = null;
00416 } else if (!strcmp(argv[i], "-q")) {
00417 fQuit = kTRUE;
00418 argv[i] = null;
00419 } else if (!strcmp(argv[i], "-l")) {
00420
00421 fNoLogo = kTRUE;
00422 argv[i] = null;
00423 } else if (!strcmp(argv[i], "-x")) {
00424 fExitOnException = kExit;
00425 argv[i] = null;
00426 } else if (!strcmp(argv[i], "-splash")) {
00427
00428
00429 argv[i] = null;
00430 } else if (argv[i][0] != '-' && argv[i][0] != '+') {
00431 Long64_t size;
00432 Long_t id, flags, modtime;
00433 char *arg = strchr(argv[i], '(');
00434 if (arg) *arg = '\0';
00435 char *dir = gSystem->ExpandPathName(argv[i]);
00436 TUrl udir(dir, kTRUE);
00437 if (arg) *arg = '(';
00438 if (!gSystem->GetPathInfo(dir, &id, &size, &flags, &modtime)) {
00439 if ((flags & 2)) {
00440
00441 if (pwd == "") {
00442 pwd = gSystem->WorkingDirectory();
00443 fWorkDir = dir;
00444 gSystem->ChangeDirectory(dir);
00445 argv[i] = null;
00446 } else if (!strcmp(gROOT->GetName(), "Rint")) {
00447 Warning("GetOptions", "only one directory argument can be specified (%s)", dir);
00448 }
00449 } else if (size > 0) {
00450
00451 if (!fFiles) fFiles = new TObjArray;
00452 fFiles->Add(new TObjString(argv[i]));
00453 argv[i] = null;
00454 } else {
00455 Warning("GetOptions", "file %s has size 0, skipping", dir);
00456 }
00457 } else {
00458 if (TString(udir.GetFile()).EndsWith(".root")) {
00459 if (!strcmp(udir.GetProtocol(), "file")) {
00460
00461
00462 if (!strcmp(gROOT->GetName(), "Rint"))
00463 Warning("GetOptions", "file %s not found", dir);
00464 } else {
00465
00466 if (!fFiles) fFiles = new TObjArray;
00467 fFiles->Add(new TObjString(argv[i]));
00468 argv[i] = null;
00469 }
00470 } else {
00471 TString mode,fargs,io;
00472 TString fname = gSystem->SplitAclicMode(dir,mode,fargs,io);
00473 char *mac;
00474 if ((mac = gSystem->Which(TROOT::GetMacroPath(), fname,
00475 kReadPermission))) {
00476
00477 if (!fFiles) fFiles = new TObjArray;
00478 fFiles->Add(new TObjString(argv[i]));
00479 argv[i] = null;
00480 delete [] mac;
00481 } else {
00482
00483
00484 if (!strcmp(gROOT->GetName(), "Rint"))
00485 Warning("GetOptions", "macro %s not found", fname.Data());
00486 }
00487 }
00488 }
00489 delete [] dir;
00490 }
00491
00492 }
00493
00494
00495 if (pwd != "")
00496 gSystem->ChangeDirectory(pwd);
00497
00498
00499 j = 0;
00500 for (i = 0; i < *argc; i++) {
00501 if (strcmp(argv[i], "")) {
00502 argv[j] = argv[i];
00503 j++;
00504 }
00505 }
00506
00507 *argc = j;
00508 }
00509
00510
00511 void TApplication::HandleIdleTimer()
00512 {
00513
00514
00515
00516 if (!fIdleCommand.IsNull())
00517 ProcessLine(GetIdleCommand());
00518
00519 Emit("HandleIdleTimer()");
00520 }
00521
00522
00523 void TApplication::HandleException(Int_t sig)
00524 {
00525
00526
00527
00528
00529 if (TROOT::Initialized()) {
00530 if (gException) {
00531 gInterpreter->RewindDictionary();
00532 gInterpreter->ClearFileBusy();
00533 }
00534 if (fExitOnException == kExit)
00535 gSystem->Exit(sig);
00536 else if (fExitOnException == kAbort)
00537 gSystem->Abort();
00538 else
00539 Throw(sig);
00540 }
00541 gSystem->Exit(sig);
00542 }
00543
00544
00545 TApplication::EExitOnException TApplication::ExitOnException(TApplication::EExitOnException opt)
00546 {
00547
00548
00549
00550
00551
00552
00553 EExitOnException old = fExitOnException;
00554 fExitOnException = opt;
00555 return old;
00556 }
00557
00558
00559 void TApplication::Help(const char *line)
00560 {
00561
00562
00563 gInterpreter->ProcessLine(line);
00564
00565 Printf("\nROOT special commands.");
00566 Printf("===========================================================================");
00567 Printf(" pwd : show current directory, pad and style");
00568 Printf(" ls : list contents of current directory");
00569 Printf(" which [file] : shows path of macro file");
00570 }
00571
00572
00573 void TApplication::LoadGraphicsLibs()
00574 {
00575
00576
00577
00578 if (gROOT->IsBatch()) return;
00579
00580 TPluginHandler *h;
00581 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPad")))
00582 if (h->LoadPlugin() == -1)
00583 return;
00584
00585 TString name;
00586 TString title1 = "ROOT interface to ";
00587 TString nativex, title;
00588 TString nativeg = "root";
00589 #ifndef R__WIN32
00590 nativex = "x11";
00591 name = "X11";
00592 title = title1 + "X11";
00593 #else
00594 nativex = "win32gdk";
00595 name = "Win32gdk";
00596 title = title1 + "Win32gdk";
00597 #endif
00598
00599 TString guiBackend(gEnv->GetValue("Gui.Backend", "native"));
00600 guiBackend.ToLower();
00601 if (guiBackend == "native") {
00602 guiBackend = nativex;
00603 } else {
00604 name = guiBackend;
00605 title = title1 + guiBackend;
00606 }
00607 TString guiFactory(gEnv->GetValue("Gui.Factory", "native"));
00608 guiFactory.ToLower();
00609 if (guiFactory == "native")
00610 guiFactory = nativeg;
00611
00612 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", guiBackend))) {
00613 if (h->LoadPlugin() == -1) {
00614 gROOT->SetBatch(kTRUE);
00615 return;
00616 }
00617 gVirtualX = (TVirtualX *) h->ExecPlugin(2, name.Data(), title.Data());
00618 }
00619 if ((h = gROOT->GetPluginManager()->FindHandler("TGuiFactory", guiFactory))) {
00620 if (h->LoadPlugin() == -1) {
00621 gROOT->SetBatch(kTRUE);
00622 return;
00623 }
00624 gGuiFactory = (TGuiFactory *) h->ExecPlugin(0);
00625 }
00626 }
00627
00628
00629 void TApplication::MakeBatch()
00630 {
00631
00632
00633 gROOT->SetBatch();
00634 if (gGuiFactory != gBatchGuiFactory) delete gGuiFactory;
00635 gGuiFactory = gBatchGuiFactory;
00636 #ifndef R__WIN32
00637 if (gVirtualX != gGXBatch) delete gVirtualX;
00638 #endif
00639 gVirtualX = gGXBatch;
00640 }
00641
00642
00643 Int_t TApplication::ParseRemoteLine(const char *ln,
00644 TString &hostdir, TString &user,
00645 Int_t &dbg, TString &script)
00646 {
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 if (!ln || strlen(ln) <= 0)
00658 return 0;
00659
00660 Int_t rc = 0;
00661 Bool_t isHostDir = kTRUE;
00662 Bool_t isScript = kFALSE;
00663 Bool_t isUser = kFALSE;
00664 Bool_t isDbg = kFALSE;
00665
00666 TString line(ln);
00667 TString tkn;
00668 Int_t from = 0;
00669 while (line.Tokenize(tkn, from, " ")) {
00670 if (tkn == "-l") {
00671
00672 isUser = kTRUE;
00673 } else if (tkn == "-d") {
00674 isDbg = kTRUE;
00675 } else if (tkn == "-close") {
00676 rc = 1;
00677 } else if (tkn.BeginsWith("-")) {
00678 ::Warning("TApplication::ParseRemoteLine","unknown option: %s", tkn.Data());
00679 } else {
00680 if (isUser) {
00681 user = tkn;
00682 isUser = kFALSE;
00683 } else if (isDbg) {
00684 dbg = tkn.Atoi();
00685 isDbg = kFALSE;
00686 } else if (isHostDir) {
00687 hostdir = tkn;
00688 hostdir.ReplaceAll(":","/");
00689 isHostDir = kFALSE;
00690 isScript = kTRUE;
00691 } else if (isScript) {
00692
00693 script = tkn;
00694 script.Insert(0, "\"");
00695 script += "\"";
00696 isScript = kFALSE;
00697 break;
00698 }
00699 }
00700 }
00701
00702
00703 return rc;
00704 }
00705
00706
00707 Long_t TApplication::ProcessRemote(const char *line, Int_t *)
00708 {
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 if (!line) return 0;
00720
00721 if (!strncmp(line, "-?", 2) || !strncmp(line, "-h", 2) ||
00722 !strncmp(line, "--help", 6)) {
00723 Info("ProcessRemote", "remote session help:");
00724 Printf(".R [user@]host[:dir] [-l user] [-d dbg] [[<]script] | [host] -close");
00725 Printf("Create a ROOT session on the specified remote host.");
00726 Printf("The variable \"dir\" is the remote directory to be used as working dir.");
00727 Printf("The username can be specified in two ways, \"-l\" having the priority");
00728 Printf("(as in ssh). A \"dbg\" value > 0 gives increasing verbosity.");
00729 Printf("The last argument \"script\" allows to specify an alternative script to");
00730 Printf("be executed remotely to startup the session, \"roots\" being");
00731 Printf("the default. If the script is preceeded by a \"<\" the script will be");
00732 Printf("sourced, after which \"roots\" is executed. The sourced script can be ");
00733 Printf("used to change the PATH and other variables, allowing an alternative");
00734 Printf("\"roots\" script to be found.");
00735 Printf("To close down a session do \".R host -close\".");
00736 Printf("To switch between sessions do \".R host\", to switch to the local");
00737 Printf("session do \".R\".");
00738 Printf("To list all open sessions do \"gApplication->GetApplications()->Print()\".");
00739 return 0;
00740 }
00741
00742 TString hostdir, user, script;
00743 Int_t dbg = 0;
00744 Int_t rc = ParseRemoteLine(line, hostdir, user, dbg, script);
00745 if (hostdir.Length() <= 0) {
00746
00747 if (rc == 1) {
00748 TApplication::Close(fAppRemote);
00749 delete fAppRemote;
00750 }
00751
00752 fAppRemote = 0;
00753
00754 return 1;
00755 } else if (rc == 1) {
00756
00757 TApplication *ap = TApplication::Open(hostdir, 0, 0);
00758 if (ap) {
00759 TApplication::Close(ap);
00760 delete ap;
00761 }
00762 }
00763
00764 if (user.Length() > 0)
00765 hostdir.Insert(0,Form("%s@", user.Data()));
00766 const char *sc = (script.Length() > 0) ? script.Data() : 0;
00767 TApplication *ap = TApplication::Open(hostdir, dbg, sc);
00768 if (ap) {
00769 fAppRemote = ap;
00770 }
00771
00772
00773 return 1;
00774 }
00775
00776
00777 Long_t TApplication::ProcessLine(const char *line, Bool_t sync, Int_t *err)
00778 {
00779
00780
00781
00782
00783 if (!line || !*line) return 0;
00784
00785
00786 if (!strncmp(line, ".R", 2)) {
00787 Int_t n = 2;
00788 while (*(line+n) == ' ')
00789 n++;
00790 return ProcessRemote(line+n, err);
00791 }
00792
00793
00794 if (fAppRemote && TestBit(kProcessRemotely)) {
00795 ResetBit(kProcessRemotely);
00796 return fAppRemote->ProcessLine(line, err);
00797 }
00798
00799 if (!strncasecmp(line, ".qqqqqqq", 7)) {
00800 gSystem->Abort();
00801 } else if (!strncasecmp(line, ".qqqqq", 5)) {
00802 Info("ProcessLine", "Bye... (try '.qqqqqqq' if still running)");
00803 gSystem->Exit(1);
00804 } else if (!strncasecmp(line, ".exit", 4) || !strncasecmp(line, ".quit", 2)) {
00805 gInterpreter->ResetGlobals();
00806 Terminate(0);
00807 return 0;
00808 }
00809
00810 if (!strncmp(line, "?", 1)) {
00811 Help(line);
00812 return 1;
00813 }
00814
00815 if (!strncmp(line, ".pwd", 4)) {
00816 if (gDirectory)
00817 Printf("Current directory: %s", gDirectory->GetPath());
00818 if (gPad)
00819 Printf("Current pad: %s", gPad->GetName());
00820 if (gStyle)
00821 Printf("Current style: %s", gStyle->GetName());
00822 return 1;
00823 }
00824
00825 if (!strncmp(line, ".ls", 3)) {
00826 const char *opt = 0;
00827 if (line[3]) opt = &line[3];
00828 if (gDirectory) gDirectory->ls(opt);
00829 return 1;
00830 }
00831
00832 if (!strncmp(line, ".which", 6)) {
00833 char *fn = Strip(line+7);
00834 char *s = strtok(fn, "+(");
00835 char *mac = gSystem->Which(TROOT::GetMacroPath(), s, kReadPermission);
00836 if (!mac)
00837 Printf("No macro %s in path %s", s, TROOT::GetMacroPath());
00838 else
00839 Printf("%s", mac);
00840 delete [] fn;
00841 delete [] mac;
00842 return mac ? 1 : 0;
00843 }
00844
00845 if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2)) {
00846 TString aclicMode;
00847 TString arguments;
00848 TString io;
00849 TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
00850
00851 char *mac = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
00852 if (arguments.Length()) {
00853 Warning("ProcessLine", "argument(s) \"%s\" ignored with .%c", arguments.Data(),
00854 line[1]);
00855 }
00856 Long_t retval = 0;
00857 if (!mac)
00858 Error("ProcessLine", "macro %s not found in path %s", fname.Data(),
00859 TROOT::GetMacroPath());
00860 else {
00861 TString cmd(line+1);
00862 Ssiz_t posSpace = cmd.Index(' ');
00863 if (posSpace == -1) cmd.Remove(1);
00864 else cmd.Remove(posSpace);
00865 static TString tempbuf;
00866 if (sync) {
00867 tempbuf.Form(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(),io.Data());
00868 retval = gInterpreter->ProcessLineSynch(tempbuf,
00869 (TInterpreter::EErrorCode*)err);
00870 } else {
00871 tempbuf.Form(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(),io.Data());
00872 retval = gInterpreter->ProcessLine(tempbuf,
00873 (TInterpreter::EErrorCode*)err);
00874 }
00875 }
00876
00877 delete [] mac;
00878
00879 InitializeGraphics();
00880
00881 return retval;
00882 }
00883
00884 if (!strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
00885 return ProcessFile(line+3, err, line[2] == 'k');
00886 }
00887
00888 if (!strcmp(line, ".reset")) {
00889
00890 Printf("*** .reset not allowed, please use gROOT->Reset() ***");
00891 return 0;
00892
00893 #if 0
00894
00895
00896 gROOT->GetListOfClasses()->Delete();
00897
00898 #endif
00899 }
00900
00901 if (sync)
00902 return gInterpreter->ProcessLineSynch(line, (TInterpreter::EErrorCode*)err);
00903 else
00904 return gInterpreter->ProcessLine(line, (TInterpreter::EErrorCode*)err);
00905 }
00906
00907
00908 Long_t TApplication::ProcessFile(const char *file, Int_t *error, Bool_t keep)
00909 {
00910
00911
00912 return ExecuteFile(file, error, keep);
00913 }
00914
00915
00916 Long_t TApplication::ExecuteFile(const char *file, Int_t *error, Bool_t keep)
00917 {
00918
00919
00920
00921 static const Int_t kBufSize = 1024;
00922
00923 if (!file || !*file) return 0;
00924
00925 TString aclicMode;
00926 TString arguments;
00927 TString io;
00928 TString fname = gSystem->SplitAclicMode(file, aclicMode, arguments, io);
00929
00930 char *exnam = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
00931 if (!exnam) {
00932 ::Error("TApplication::ExecuteFile", "macro %s not found in path %s", fname.Data(),
00933 TROOT::GetMacroPath());
00934 delete [] exnam;
00935 return 0;
00936 }
00937
00938 ::ifstream macro(exnam, ios::in);
00939 if (!macro.good()) {
00940 ::Error("TApplication::ExecuteFile", "%s no such file", exnam);
00941 delete [] exnam;
00942 return 0;
00943 }
00944
00945 char currentline[kBufSize];
00946 char dummyline[kBufSize];
00947 int tempfile = 0;
00948 int comment = 0;
00949 int ifndefc = 0;
00950 int ifdef = 0;
00951 char *s = 0;
00952 Bool_t execute = kFALSE;
00953 Long_t retval = 0;
00954
00955 while (1) {
00956 bool res = macro.getline(currentline, kBufSize);
00957 if (macro.eof()) break;
00958 if (!res) {
00959
00960
00961 macro.clear();
00962 while (!macro.getline(dummyline, kBufSize) && !macro.eof()) {
00963 macro.clear();
00964 }
00965 }
00966 s = currentline;
00967 while (s && (*s == ' ' || *s == '\t')) s++;
00968
00969
00970
00971
00972 if (*s == '#') {
00973 char *cs = Compress(currentline);
00974 if (strstr(cs, "#ifndef__CINT__") ||
00975 strstr(cs, "#if!defined(__CINT__)"))
00976 ifndefc = 1;
00977 else if (ifndefc && (strstr(cs, "#ifdef") || strstr(cs, "#ifndef") ||
00978 strstr(cs, "#ifdefined") || strstr(cs, "#if!defined")))
00979 ifdef++;
00980 else if (ifndefc && strstr(cs, "#endif")) {
00981 if (ifdef)
00982 ifdef--;
00983 else
00984 ifndefc = 0;
00985 } else if (ifndefc && !ifdef && strstr(cs, "#else"))
00986 ifndefc = 0;
00987 delete [] cs;
00988 }
00989 if (!*s || *s == '#' || ifndefc || !strncmp(s, "//", 2)) continue;
00990
00991 if (!comment && (!strncmp(s, ".X", 2) || !strncmp(s, ".x", 2))) {
00992 retval = ExecuteFile(s+3);
00993 execute = kTRUE;
00994 continue;
00995 }
00996
00997 if (!strncmp(s, "/*", 2)) comment = 1;
00998 if (comment) {
00999
01000 again:
01001 s = strstr(s, "*/");
01002 if (s) {
01003 comment = 0;
01004 s += 2;
01005
01006 while (s && (*s == ' ' || *s == '\t')) s++;
01007 if (!*s) continue;
01008 if (!strncmp(s, "//", 2)) continue;
01009 if (!strncmp(s, "/*", 2)) {
01010 comment = 1;
01011 goto again;
01012 }
01013 }
01014 }
01015 if (!comment && *s == '{') tempfile = 1;
01016 if (!comment) break;
01017 }
01018 macro.close();
01019
01020 if (!execute) {
01021 TString exname = exnam;
01022 if (!tempfile) {
01023
01024
01025 exname += aclicMode;
01026 }
01027 exname += arguments;
01028 exname += io;
01029
01030 static TString tempbuf;
01031 if (tempfile) {
01032 tempbuf.Form(".x %s", exname.Data());
01033 } else {
01034 tempbuf.Form(".X%s %s", keep ? "k" : " ", exname.Data());
01035 }
01036 retval = gInterpreter->ProcessLineSynch(tempbuf,(TInterpreter::EErrorCode*)error);
01037 }
01038
01039 delete [] exnam;
01040 return retval;
01041 }
01042
01043
01044 void TApplication::Run(Bool_t retrn)
01045 {
01046
01047
01048 SetReturnFromRun(retrn);
01049
01050 fIsRunning = kTRUE;
01051
01052 gSystem->Run();
01053 fIsRunning = kFALSE;
01054 }
01055
01056
01057 void TApplication::SetIdleTimer(UInt_t idleTimeInSec, const char *command)
01058 {
01059
01060
01061
01062 if (fIdleTimer) RemoveIdleTimer();
01063 fIdleCommand = command;
01064 fIdleTimer = new TIdleTimer(idleTimeInSec*1000);
01065 gSystem->AddTimer(fIdleTimer);
01066 }
01067
01068
01069 void TApplication::RemoveIdleTimer()
01070 {
01071
01072
01073 if (fIdleTimer) {
01074
01075 SafeDelete(fIdleTimer);
01076 }
01077 }
01078
01079
01080 void TApplication::StartIdleing()
01081 {
01082
01083
01084 if (fIdleTimer) {
01085 fIdleTimer->Reset();
01086 gSystem->AddTimer(fIdleTimer);
01087 }
01088 }
01089
01090
01091 void TApplication::StopIdleing()
01092 {
01093
01094
01095 if (fIdleTimer)
01096 gSystem->RemoveTimer(fIdleTimer);
01097 }
01098
01099
01100 void TApplication::Terminate(Int_t status)
01101 {
01102
01103
01104
01105
01106 if (fUseMemstat) {
01107 ProcessLine("TMemStat::Close()");
01108 fUseMemstat = kFALSE;
01109 }
01110
01111 Emit("Terminate(Int_t)", status);
01112
01113 if (fReturnFromRun)
01114 gSystem->ExitLoop();
01115 else
01116 gSystem->Exit(status);
01117 }
01118
01119
01120 void TApplication::LineProcessed(const char *line)
01121 {
01122
01123
01124 Emit("LineProcessed(const char*)", line);
01125 }
01126
01127
01128 void TApplication::KeyPressed(Int_t key)
01129 {
01130
01131
01132 Emit("KeyPressed(Int_t)", key);
01133 }
01134
01135
01136 void TApplication::ReturnPressed(char *text )
01137 {
01138
01139
01140 Emit("ReturnPressed(char*)", text);
01141 }
01142
01143
01144 void TApplication::SetEchoMode(Bool_t)
01145 {
01146
01147
01148
01149
01150 }
01151
01152
01153 void TApplication::CreateApplication()
01154 {
01155
01156
01157 if (!gApplication) {
01158 char *a = StrDup("RootApp");
01159 char *b = StrDup("-b");
01160 char *argv[2];
01161 Int_t argc = 2;
01162 argv[0] = a;
01163 argv[1] = b;
01164 new TApplication("RootApp", &argc, argv, 0, 0);
01165 if (gDebug > 0)
01166 Printf("<TApplication::CreateApplication>: "
01167 "created default TApplication");
01168 delete [] a; delete [] b;
01169 gApplication->SetBit(kDefaultApplication);
01170 }
01171 }
01172
01173
01174 TApplication *TApplication::Open(const char *url,
01175 Int_t debug, const char *script)
01176 {
01177
01178
01179
01180 TApplication *ap = 0;
01181 TUrl nu(url);
01182 Int_t nnew = 0;
01183
01184
01185 if (fgApplications) {
01186 TIter nxa(fgApplications);
01187 while ((ap = (TApplication *) nxa())) {
01188 TString apn(ap->ApplicationName());
01189 if (apn == url) {
01190
01191 return ap;
01192 } else {
01193
01194 TUrl au(apn);
01195 if (strlen(au.GetUser()) > 0 && strlen(nu.GetUser()) > 0 &&
01196 !strcmp(au.GetUser(), nu.GetUser())) {
01197 if (!strncmp(au.GetHost(), nu.GetHost(), strlen(nu.GetHost())))
01198
01199 nnew++;
01200 }
01201 }
01202 }
01203 } else {
01204 ::Error("TApplication::Open", "list of applications undefined - protocol error");
01205 return ap;
01206 }
01207
01208
01209 if (nnew > 0) {
01210 nnew++;
01211 nu.SetOptions(Form("%d", nnew));
01212 }
01213
01214
01215 TPluginHandler *h = 0;
01216 if ((h = gROOT->GetPluginManager()->FindHandler("TApplication","remote"))) {
01217 if (h->LoadPlugin() == 0) {
01218 ap = (TApplication *) h->ExecPlugin(3, nu.GetUrl(), debug, script);
01219 } else {
01220 ::Error("TApplication::Open", "failed to load plugin for TApplicationRemote");
01221 }
01222 } else {
01223 ::Error("TApplication::Open", "failed to find plugin for TApplicationRemote");
01224 }
01225
01226
01227 if (ap && !(ap->TestBit(kInvalidObject))) {
01228 fgApplications->Add(ap);
01229 gROOT->GetListOfBrowsables()->Add(ap, ap->ApplicationName());
01230 TIter next(gROOT->GetListOfBrowsers());
01231 TBrowser *b;
01232 while ((b = (TBrowser*) next()))
01233 b->Add(ap, ap->ApplicationName());
01234 gROOT->RefreshBrowsers();
01235 } else {
01236 SafeDelete(ap);
01237 ::Error("TApplication::Open",
01238 "TApplicationRemote for %s could not be instantiated", url);
01239 }
01240
01241
01242 return ap;
01243 }
01244
01245
01246 void TApplication::Close(TApplication *app)
01247 {
01248
01249
01250 if (app) {
01251 app->Terminate(0);
01252 fgApplications->Remove(app);
01253 gROOT->GetListOfBrowsables()->RecursiveRemove(app);
01254 TIter next(gROOT->GetListOfBrowsers());
01255 TBrowser *b;
01256 while ((b = (TBrowser*) next()))
01257 b->RecursiveRemove(app);
01258 gROOT->RefreshBrowsers();
01259 }
01260 }
01261
01262
01263 void TApplication::ls(Option_t *opt) const
01264 {
01265
01266
01267 if (fgApplications) {
01268 TIter nxa(fgApplications);
01269 TApplication *a = 0;
01270 while ((a = (TApplication *) nxa())) {
01271 a->Print(opt);
01272 }
01273 } else {
01274 Print(opt);
01275 }
01276 }
01277
01278
01279 TList *TApplication::GetApplications()
01280 {
01281
01282
01283 return fgApplications;
01284 }