00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "TROOT.h"
00022 #include "TClass.h"
00023 #include "TVirtualX.h"
00024 #include "TStyle.h"
00025 #include "TObjectTable.h"
00026 #include "TClassTable.h"
00027 #include "TStopwatch.h"
00028 #include "TBenchmark.h"
00029 #include "TRint.h"
00030 #include "TSystem.h"
00031 #include "TEnv.h"
00032 #include "TSysEvtHandler.h"
00033 #include "TSystemDirectory.h"
00034 #include "TError.h"
00035 #include "TException.h"
00036 #include "TInterpreter.h"
00037 #include "TObjArray.h"
00038 #include "TObjString.h"
00039 #include "TTabCom.h"
00040 #include "TError.h"
00041 #include <stdlib.h>
00042
00043 #ifdef R__BUILDEDITLINE
00044 #include "Getline_el.h"
00045 #else
00046 #include "Getline.h"
00047 #endif
00048
00049 #ifdef R__UNIX
00050 #include <signal.h>
00051 #endif
00052
00053 R__EXTERN void *gMmallocDesc;
00054
00055
00056 static Int_t Key_Pressed(Int_t key)
00057 {
00058 gApplication->KeyPressed(key);
00059 return 0;
00060 }
00061
00062
00063 static Int_t BeepHook()
00064 {
00065 if (!gSystem) return 0;
00066 gSystem->Beep();
00067 return 1;
00068 }
00069
00070
00071 static void ResetTermAtExit()
00072 {
00073
00074
00075 Getlinem(kCleanUp, 0);
00076 }
00077
00078
00079
00080
00081 class TInterruptHandler : public TSignalHandler {
00082 public:
00083 TInterruptHandler() : TSignalHandler(kSigInterrupt, kFALSE) { }
00084 Bool_t Notify();
00085 };
00086
00087
00088 Bool_t TInterruptHandler::Notify()
00089 {
00090
00091
00092 if (fDelay) {
00093 fDelay++;
00094 return kTRUE;
00095 }
00096
00097
00098 gMmallocDesc = 0;
00099
00100 if (!gCint->GetSecurityError())
00101 gCint->GenericError("\n *** Break *** keyboard interrupt");
00102 else {
00103 Break("TInterruptHandler::Notify", "keyboard interrupt");
00104 if (TROOT::Initialized()) {
00105 Getlinem(kInit, "Root > ");
00106 gCint->RewindDictionary();
00107 Throw(GetSignal());
00108 }
00109 }
00110 return kTRUE;
00111 }
00112
00113
00114
00115 class TTermInputHandler : public TFileHandler {
00116 public:
00117 TTermInputHandler(Int_t fd) : TFileHandler(fd, 1) { }
00118 Bool_t Notify();
00119 Bool_t ReadNotify() { return Notify(); }
00120 };
00121
00122
00123 Bool_t TTermInputHandler::Notify()
00124 {
00125
00126
00127 return gApplication->HandleTermInput();
00128 }
00129
00130
00131 ClassImp(TRint)
00132
00133
00134 TRint::TRint(const char *appClassName, Int_t *argc, char **argv, void *options,
00135 Int_t numOptions, Bool_t noLogo)
00136 : TApplication(appClassName, argc, argv, options, numOptions)
00137 {
00138
00139
00140
00141
00142
00143 fNcmd = 0;
00144 fDefaultPrompt = "root [%d] ";
00145 fInterrupt = kFALSE;
00146
00147 gBenchmark = new TBenchmark();
00148
00149 if (!noLogo && !NoLogoOpt()) {
00150 Bool_t lite = (Bool_t) gEnv->GetValue("Rint.WelcomeLite", 0);
00151 PrintLogo(lite);
00152 }
00153
00154
00155 Int_t includes = gEnv->GetValue("Rint.Includes", 1);
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 if (includes > 0) {
00168 ProcessLine("#include <iostream>", kTRUE);
00169 ProcessLine("#include <string>", kTRUE);
00170 ProcessLine("#include <DllImport.h>", kTRUE);
00171 if (includes > 1) {
00172 ProcessLine("#include <vector>", kTRUE);
00173 ProcessLine("#include <pair>", kTRUE);
00174
00175 }
00176 }
00177
00178
00179 const char *logon;
00180 logon = gEnv->GetValue("Rint.Load", (char*)0);
00181 if (logon) {
00182 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
00183 if (mac)
00184 ProcessLine(Form(".L %s",logon), kTRUE);
00185 delete [] mac;
00186 }
00187
00188
00189 ExecLogon();
00190
00191
00192 gCint->SaveContext();
00193 gCint->SaveGlobalsContext();
00194
00195
00196 TInterruptHandler *ih = new TInterruptHandler();
00197 ih->Add();
00198 SetSignalHandler(ih);
00199
00200
00201 fInputHandler = new TTermInputHandler(0);
00202 fInputHandler->Add();
00203
00204
00205 char defhist[kMAXPATHLEN];
00206 snprintf(defhist, sizeof(defhist), "%s/.root_hist", gSystem->HomeDirectory());
00207 logon = gEnv->GetValue("Rint.History", defhist);
00208
00209
00210
00211
00212 int hist_size = gEnv->GetValue("Rint.HistorySize", 500);
00213 if (hist_size == 500)
00214 hist_size = gEnv->GetValue("Rint.HistSize", 500);
00215 int hist_save = gEnv->GetValue("Rint.HistorySave", 400);
00216 if (hist_save == 400)
00217 hist_save = gEnv->GetValue("Rint.HistSave", 400);
00218 const char *envHist = gSystem->Getenv("ROOT_HIST");
00219 if (envHist) {
00220 hist_size = atoi(envHist);
00221 envHist = strchr(envHist, ':');
00222 if (envHist)
00223 hist_save = atoi(envHist+1);
00224 }
00225 Gl_histsize(hist_size, hist_save);
00226 Gl_histinit((char *)logon);
00227
00228 #ifdef R__BUILDEDITLINE
00229
00230 static const char* defaultColorsBW[] = {
00231 "bold blue", "magenta", "bold green", "bold red underlined", "default"
00232 };
00233 static const char* defaultColorsWB[] = {
00234 "yellow", "magenta", "bold green", "bold red underlined", "default"
00235 };
00236
00237 const char** defaultColors = defaultColorsBW;
00238 TString revColor = gEnv->GetValue("Rint.ReverseColor", "no");
00239 if (revColor.Contains("yes", TString::kIgnoreCase)) {
00240 defaultColors = defaultColorsWB;
00241 }
00242 TString colorType = gEnv->GetValue("Rint.TypeColor", defaultColors[0]);
00243 TString colorTabCom = gEnv->GetValue("Rint.TabComColor", defaultColors[1]);
00244 TString colorBracket = gEnv->GetValue("Rint.BracketColor", defaultColors[2]);
00245 TString colorBadBracket = gEnv->GetValue("Rint.BadBracketColor", defaultColors[3]);
00246 TString colorPrompt = gEnv->GetValue("Rint.PromptColor", defaultColors[4]);
00247 Gl_setColors(colorType, colorTabCom, colorBracket, colorBadBracket, colorPrompt);
00248 #endif
00249
00250 Gl_windowchanged();
00251
00252 atexit(ResetTermAtExit);
00253
00254
00255 gTabCom = new TTabCom;
00256 Gl_in_key = &Key_Pressed;
00257 Gl_beep_hook = &BeepHook;
00258
00259
00260 gCint->SetGetline(Getline, Gl_histadd);
00261 }
00262
00263
00264 TRint::~TRint()
00265 {
00266
00267
00268 delete gTabCom;
00269 gTabCom = 0;
00270 Gl_in_key = 0;
00271 Gl_beep_hook = 0;
00272 fInputHandler->Remove();
00273 delete fInputHandler;
00274
00275
00276
00277
00278
00279
00280 }
00281
00282
00283 void TRint::ExecLogon()
00284 {
00285
00286
00287
00288
00289
00290
00291
00292
00293 if (NoLogOpt()) return;
00294
00295 TString name = ".rootlogon.C";
00296 TString sname = "system";
00297 sname += name;
00298 #ifdef ROOTETCDIR
00299 char *s = gSystem->ConcatFileName(ROOTETCDIR, sname);
00300 #else
00301 TString etc = gRootDir;
00302 #ifdef WIN32
00303 etc += "\\etc";
00304 #else
00305 etc += "/etc";
00306 #endif
00307 char *s = gSystem->ConcatFileName(etc, sname);
00308 #endif
00309 if (!gSystem->AccessPathName(s, kReadPermission)) {
00310 ProcessFile(s);
00311 }
00312 delete [] s;
00313 s = gSystem->ConcatFileName(gSystem->HomeDirectory(), name);
00314 if (!gSystem->AccessPathName(s, kReadPermission)) {
00315 ProcessFile(s);
00316 }
00317 delete [] s;
00318
00319 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
00320 if (!gSystem->AccessPathName(name, kReadPermission))
00321 ProcessFile(name);
00322 }
00323
00324
00325 const char *logon = gEnv->GetValue("Rint.Logon", (char*)0);
00326 if (logon) {
00327 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
00328 if (mac)
00329 ProcessFile(logon);
00330 delete [] mac;
00331 }
00332 }
00333
00334
00335 void TRint::Run(Bool_t retrn)
00336 {
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 Getlinem(kInit, GetPrompt());
00347
00348 Long_t retval = 0;
00349 Int_t error = 0;
00350 volatile Bool_t needGetlinemInit = kFALSE;
00351
00352 if (strlen(WorkingDirectory())) {
00353
00354 gSystem->ChangeDirectory(WorkingDirectory());
00355 TSystemDirectory *workdir = new TSystemDirectory("workdir", gSystem->WorkingDirectory());
00356 TObject *w = gROOT->GetListOfBrowsables()->FindObject("workdir");
00357 TObjLink *lnk = gROOT->GetListOfBrowsables()->FirstLink();
00358 while (lnk) {
00359 if (lnk->GetObject() == w) {
00360 lnk->SetObject(workdir);
00361 lnk->SetOption(gSystem->WorkingDirectory());
00362 break;
00363 }
00364 lnk = lnk->Next();
00365 }
00366 delete w;
00367 }
00368
00369
00370 if (InputFiles()) {
00371
00372
00373 fInputHandler->DeActivate();
00374 TIter next(InputFiles());
00375 RETRY {
00376 retval = 0; error = 0;
00377 Int_t nfile = 0;
00378 TObjString *file;
00379 while ((file = (TObjString *)next())) {
00380 char cmd[kMAXPATHLEN+50];
00381 if (!fNcmd)
00382 printf("\n");
00383 if (file->String().EndsWith(".root") || file->String().BeginsWith("file:")) {
00384 file->String().ReplaceAll("\\","/");
00385 const char *rfile = (const char*)file->String();
00386 Printf("Attaching file %s as _file%d...", rfile, nfile);
00387 snprintf(cmd, kMAXPATHLEN+50, "TFile *_file%d = TFile::Open(\"%s\")", nfile++, rfile);
00388 } else {
00389 Printf("Processing %s...", (const char*)file->String());
00390 snprintf(cmd, kMAXPATHLEN+50, ".x %s", (const char*)file->String());
00391 }
00392 Getlinem(kCleanUp, 0);
00393 Gl_histadd(cmd);
00394 fNcmd++;
00395
00396
00397
00398
00399 needGetlinemInit = kFALSE;
00400 retval = ProcessLine(cmd, kFALSE, &error);
00401 gCint->EndOfLineAction();
00402
00403
00404
00405 needGetlinemInit = kTRUE;
00406
00407 if (error != 0) break;
00408 }
00409 } ENDTRY;
00410
00411
00412
00413 fInputHandler->Activate();
00414
00415 if (QuitOpt()) {
00416 if (retrn) return;
00417 Terminate(error == 0 ? retval : error);
00418 }
00419
00420 ClearInputFiles();
00421
00422 if (needGetlinemInit) Getlinem(kInit, GetPrompt());
00423 }
00424
00425 if (QuitOpt()) {
00426 printf("\n");
00427 if (retrn) return;
00428 Terminate(0);
00429 }
00430
00431 TApplication::Run(retrn);
00432
00433 Getlinem(kCleanUp, 0);
00434 }
00435
00436
00437 void TRint::PrintLogo(Bool_t lite)
00438 {
00439
00440
00441 const char *root_version = gROOT->GetVersion();
00442
00443 if (!lite) {
00444 static const char *months[] = {"January","February","March","April","May",
00445 "June","July","August","September","October",
00446 "November","December"};
00447 Int_t idatqq = gROOT->GetVersionDate();
00448 Int_t iday = idatqq%100;
00449 Int_t imonth = (idatqq/100)%100;
00450 Int_t iyear = (idatqq/10000);
00451 char *version_date = Form("%d %s %4d",iday,months[imonth-1],iyear);
00452
00453 Printf(" *******************************************");
00454 Printf(" * *");
00455 Printf(" * W E L C O M E to R O O T *");
00456 Printf(" * *");
00457 Printf(" * Version%10s %17s *", root_version, version_date);
00458 Printf(" * *");
00459 Printf(" * You are welcome to visit our Web site *");
00460 Printf(" * http://root.cern.ch *");
00461 Printf(" * *");
00462 Printf(" *******************************************\n");
00463 }
00464
00465 Printf("ROOT %s (%s@%d, %s on %s)", root_version, gROOT->GetSvnBranch(),
00466 gROOT->GetSvnRevision(), gROOT->GetSvnDate(),
00467 gSystem->GetBuildArch());
00468
00469 if (!lite)
00470 gCint->PrintIntro();
00471
00472 #ifdef R__UNIX
00473
00474 for (int i = 0; i < Argc(); i++)
00475 if (!strcmp(Argv(i), "-splash"))
00476 kill(getppid(), SIGUSR1);
00477 #endif
00478 }
00479
00480
00481 char *TRint::GetPrompt()
00482 {
00483
00484
00485 char *s = gCint->GetPrompt();
00486 if (s[0])
00487 strlcpy(fPrompt, s, sizeof(fPrompt));
00488 else
00489 snprintf(fPrompt, sizeof(fPrompt), fDefaultPrompt.Data(), fNcmd);
00490
00491 return fPrompt;
00492 }
00493
00494
00495 const char *TRint::SetPrompt(const char *newPrompt)
00496 {
00497
00498
00499
00500
00501
00502
00503
00504
00505 static TString op = fDefaultPrompt;
00506
00507 if (newPrompt && strlen(newPrompt) <= 55)
00508 fDefaultPrompt = newPrompt;
00509 else
00510 Error("SetPrompt", "newPrompt too long (> 55 characters)");
00511
00512 return op.Data();
00513 }
00514
00515
00516 Bool_t TRint::HandleTermInput()
00517 {
00518
00519
00520 static TStopwatch timer;
00521 char *line;
00522
00523 if ((line = Getlinem(kOneChar, 0))) {
00524 if (line[0] == 0 && Gl_eof())
00525 Terminate(0);
00526
00527 gVirtualX->SetKeyAutoRepeat(kTRUE);
00528
00529 Gl_histadd(line);
00530
00531 TString sline = line;
00532 line[0] = 0;
00533
00534
00535 sline = sline.Chop();
00536 sline = sline.Strip(TString::kBoth);
00537 ReturnPressed((char*)sline.Data());
00538
00539 fInterrupt = kFALSE;
00540
00541 if (!gCint->GetMore() && !sline.IsNull()) fNcmd++;
00542
00543
00544 fInputHandler->DeActivate();
00545
00546 if (gROOT->Timer()) timer.Start();
00547
00548 Bool_t added = kFALSE;
00549
00550
00551 SetBit(kProcessRemotely);
00552
00553 #ifdef R__EH
00554 try {
00555 #endif
00556 TRY {
00557 if (!sline.IsNull())
00558 LineProcessed(sline);
00559 ProcessLine(sline);
00560 } CATCH(excode) {
00561
00562 fInputHandler->Activate();
00563 added = kTRUE;
00564 Throw(excode);
00565 } ENDTRY;
00566 #ifdef R__EH
00567 }
00568
00569 catch (...) {
00570
00571 if (!added) fInputHandler->Activate();
00572 throw;
00573 }
00574 #endif
00575
00576 if (gROOT->Timer()) timer.Print("u");
00577
00578
00579 fInputHandler->Activate();
00580
00581 if (!sline.BeginsWith(".reset"))
00582 gCint->EndOfLineAction();
00583
00584 gTabCom->ClearAll();
00585 Getlinem(kInit, GetPrompt());
00586 }
00587 return kTRUE;
00588 }
00589
00590
00591 void TRint::HandleException(Int_t sig)
00592 {
00593
00594
00595
00596
00597 if (TROOT::Initialized()) {
00598 if (gException) {
00599 Getlinem(kCleanUp, 0);
00600 Getlinem(kInit, "Root > ");
00601 }
00602 }
00603 TApplication::HandleException(sig);
00604 }
00605
00606
00607 void TRint::Terminate(Int_t status)
00608 {
00609
00610
00611
00612 Getlinem(kCleanUp, 0);
00613
00614 if (ReturnFromRun()) {
00615 gSystem->ExitLoop();
00616 } else {
00617 delete gTabCom;
00618 gTabCom = 0;
00619
00620
00621 const char *logoff;
00622 logoff = gEnv->GetValue("Rint.Logoff", (char*)0);
00623 if (logoff && !NoLogOpt()) {
00624 char *mac = gSystem->Which(TROOT::GetMacroPath(), logoff, kReadPermission);
00625 if (mac)
00626 ProcessFile(logoff);
00627 delete [] mac;
00628 }
00629 TApplication::Terminate(status);
00630
00631 }
00632 }
00633
00634
00635 void TRint::SetEchoMode(Bool_t mode)
00636 {
00637
00638
00639
00640
00641
00642 Gl_config("noecho", mode ? 0 : 1);
00643 }
00644
00645
00646 Long_t TRint::ProcessRemote(const char *line, Int_t *)
00647 {
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 Long_t ret = TApplication::ProcessRemote(line);
00659
00660 if (ret == 1) {
00661 if (fAppRemote) {
00662 TString prompt = Form("%s:root [%%d] ", fAppRemote->ApplicationName());
00663 SetPrompt(prompt);
00664 } else {
00665 SetPrompt("root [%d] ");
00666 }
00667 }
00668
00669 return ret;
00670 }