// @(#)root/proof:$Id$
// Author: G. Ganis   31/08/06

/*************************************************************************
 * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TProofLog                                                            //
//                                                                      //
// Implementation of the PROOF session log handler                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TFile.h"
#include "TMacro.h"
#include "TProofLog.h"
#include "TProofMgr.h"
#include "TObjString.h"
#include "TUrl.h"

ClassImp(TProofLog)

//________________________________________________________________________
TProofLog::TProofLog(const char *stag, const char *url, TProofMgr *mgr)
          : TNamed(stag, url)
{
   // Constructor.

   SetLogToBox();
   fFILE = 0;
   fElem = new TList;
   fElem->SetOwner();
   fMgr = mgr;
   // Set a fake starting time
   fStartTime.Set((UInt_t)0);
   // Extract real starting time
   TString st(stag);
   Int_t idx = st.Index('-');
   if (idx != kNPOS) {
      st.Remove(0, idx+1);
      idx = st.Index('-');
      if (idx != kNPOS) {
         st.Remove(idx);
         if (st.IsDigit()) {
            fStartTime.Set(st.Atoi());
         }
      }
   }
}

//________________________________________________________________________
TProofLog::~TProofLog()
{
   // Destructor.

   SafeDelete(fElem);
}

//________________________________________________________________________
TProofLogElem *TProofLog::Add(const char *ord, const char *url)
{
   // Add new entry to the list of elements.

   TProofLogElem *ple = new TProofLogElem(ord, url, this);
   fElem->Add(ple);
   // Done
   return ple;
}

//________________________________________________________________________
Int_t TProofLog::Retrieve(const char *ord, TProofLog::ERetrieveOpt opt,
                          const char *fname, const char *pattern)
{
   // Retrieve the content of the log file associated with worker 'ord'.
   // If 'ord' is "*" (default), all the workers are retrieved. If 'all'
   // is true, the whole files are retrieved; else a max of
   // fgMaxTransferSize (about 1000 lines) per file is read, starting from
   // the end (i.e. the last ~1000 lines).
   // The received buffer is added to the file fname, if the latter is defined.
   // If opt == TProofLog::kGrep only the lines containing 'pattern' are
   // retrieved (remote grep functionality); to filter out a pattern 'pat' use
   // pattern = "-v pat".
   // Return 0 on success, -1 in case of any error.

   // Validate inputs
   if (opt == TProofLog::kGrep && (!pattern || strlen(pattern) <= 0)) {
      Error("Retrieve", "option 'Grep' requires a pattern");
      return -1;
   }

   Int_t nel = (ord[0] == '*') ? fElem->GetSize() : 1;
   // Iterate over the elements
   TIter nxe(fElem);
   TProofLogElem *ple = 0;
   Int_t nd = 0, nb = 0;
   TString msg;
   while ((ple = (TProofLogElem *) nxe())) {
      if (ord[0] == '*' || !strcmp(ord, ple->GetName())) {
         if (ple->Retrieve(opt, pattern) != 0) {
            nb++;
         } else {
            nd++;
         }
         Float_t frac = ((Float_t)nd + (Float_t)nb) * 100. / (Float_t)nel;
         msg.Form("Retrieving logs: %d ok, %d not ok (%.0f%% processed)\r", nd, nb, frac);
         Prt(msg.Data(), kFALSE);
      }
   }
   Prt("\n");

   // Save to file, if required
   if (fname)
      Save(ord, fname);

   // Done
   return 0;
}

//________________________________________________________________________
void TProofLog::Display(const char *ord, Int_t from, Int_t to)
{
   // Display the content associated with worker 'ord' from line 'from'
   // to line 'to' inclusive. A negative value
   // for 'from' indicates lines counted from the end (tail action); 'to'
   // is ignored in such a case.
   // If 'ord' is "*" (default), all the workers are displayed.

   TString msg;
   if (ord[0] == '*') {
      Int_t nel = (fElem) ? fElem->GetSize() : 0;
      // Write global header
      msg.Form("\n// --------- Displaying PROOF Session logs --------\n"
               "// Server: %s \n// Session: %s \n// # of elements: %d \n"
               "// ------------------------------------------------\n\n",
               GetTitle(), GetName(), nel);
      Prt(msg.Data());
   }
   // Iterate over the elements
   TIter nxe(fElem);
   TProofLogElem *ple = 0;
   while ((ple = (TProofLogElem *) nxe())) {
      if (ord[0] == '*' || !strcmp(ord, ple->GetName()))
         ple->Display(from, to);
   }
   if (ord[0] == '*')
      // Write global tail
      Prt("// --------- End of PROOF Session logs ---------\n");
}

//________________________________________________________________________
void TProofLog::Print(Option_t *opt) const
{
   // Print head info about the content

   Int_t nel = (fElem) ? fElem->GetSize() : 0;
   // Write global header
   fprintf(stderr, "// --------- PROOF Session logs object --------\n");
   fprintf(stderr, "// Server: %s \n", GetTitle());
   fprintf(stderr, "// Session: %s \n", GetName());
   fprintf(stderr, "// # of elements: %d \n", nel);
   fprintf(stderr, "// --------------------------------------------\n");

   // Iterate over the elements
   TIter nxe(fElem);
   TProofLogElem *ple = 0;
   while ((ple = (TProofLogElem *) nxe()))
      ple->Print(opt);

   // Write global tail
   fprintf(stderr, "// --------------------------------------------\n");
}

//________________________________________________________________________
void TProofLog::Prt(const char *what, Bool_t newline)
{
   // Special printing procedure

   if (what) {
      if (LogToBox()) {
         // Send to log box:
         EmitVA("Prt(const char*)", 2, what, kFALSE);
      } else {
         FILE *where = (fFILE) ? (FILE *)fFILE : stderr;
         fputs(what, where);
         if (newline) fputc('\n', where);
      }
   }
}

//________________________________________________________________________
Int_t TProofLog::Save(const char *ord, const char *fname, Option_t *opt)
{
   // Save the content associated with worker 'ord' to finel 'fname'.
   // If 'ord' is "*" (default), the log from all the workers is saved.
   // If 'opt' is "a" the file is open in append mode; otherwise the file
   // is truncated.

   // Make sure we got a file name
   if (!fname) {
      Warning("Save", "filename undefined - do nothing");
      return -1;
   }

   // Open file to write header
   // Check, if the option is to append
   TString option = opt;
   option.ToLower();
   FILE *fout=0;
   if (option.Contains("a")){
      fout = fopen(fname, "a");
   } else {
      fout = fopen(fname, "w");
   }
   if (!fout) {
      Warning("Save", "file could not be opened - do nothing");
      return -1;
   }
   fFILE = (void *) fout;

   TString msg;
   if (ord[0] == '*') {
      Int_t nel = (fElem) ? fElem->GetSize() : 0;
      // Write global header
      msg.Form("\n// --------- Displaying PROOF Session logs --------\n"
               "// Server: %s \n// Session: %s \n// # of elements: %d \n"
               "// ------------------------------------------------\n\n",
               GetTitle(), GetName(), nel);
      Prt(msg.Data());
   }

   // Iterate over the elements
   TIter nxe(fElem);
   TProofLogElem *ple = 0;
   while ((ple = (TProofLogElem *) nxe())) {
      if (ord[0] == '*' || !strcmp(ord, ple->GetName()))
         ple->Display(0);
   }

   if (ord[0] == '*') {
      // Write global tail
      Prt("// --------- End of PROOF Session logs ---------\n");
   }

   // Close file
   fclose(fout);
   fFILE = 0;

   // Done
   return 0;
}

//________________________________________________________________________
Int_t TProofLog::Grep(const char *txt, Int_t from)
{
   // Search lines containing 'txt', starting from line 'from'.
   // Print the lines where this happens.

   if (!txt || strlen(txt) <= 0) {
      Warning("Grep", "text to be searched for is undefined - do nothing");
      return -1;
   }

   Int_t nel = (fElem) ? fElem->GetSize() : 0;
   // Write global header
   TString msg;
   msg.Form("\n// --------- Search in PROOF Session logs --------\n"
            "// Server: %s \n// Session: %s \n// # of elements: %d \n"
            "// Text searched for: \"%s\"", GetTitle(), GetName(), nel, txt);
   Prt(msg.Data());
   if (from > 1) {
      msg.Form("// starting from line %d \n", from);
   } else {
      msg = "\n";
   }
   Prt(msg.Data());
   Prt("// ------------------------------------------------\n");

   // Iterate over the elements
   TIter nxe(fElem);
   TProofLogElem *ple = 0;
   while ((ple = (TProofLogElem *) nxe())) {
      TString res;
      Int_t nf = ple->Grep(txt, res, from);
      if (nf > 0) {
         msg.Form("// Ord: %s - line(s): %s\n", ple->GetName(), res.Data());
         Prt(msg.Data());
      }
   }

   Prt("// ------------------------------------------------\n");

   // Done
   return 0;
}

//________________________________________________________________________
void TProofLog::SetMaxTransferSize(Long64_t maxsz)
{
   // Set max transfer size.

   TProofLogElem::SetMaxTransferSize(maxsz);
}

//
// TProofLogElem
//

Long64_t TProofLogElem::fgMaxTransferSize = 100000; // about 1000 lines

//________________________________________________________________________
TProofLogElem::TProofLogElem(const char *ord, const char *url,
                             TProofLog *logger)
              : TNamed(ord, url)
{
   // Constructor.

   fLogger = logger;
   fMacro = new TMacro;
   fSize = -1;
   fFrom = -1;
   fTo = -1;

   //Note the role here, don't redo at each call of Display()
   if (strstr(GetTitle(), "worker-")) {
      fRole = "worker";
   } else {
      if (strchr(GetName(), '.')) {
         fRole = "submaster";
      } else {
         fRole = "master";
      }
   }
}

//________________________________________________________________________
TProofLogElem::~TProofLogElem()
{
   // Destructor.

   SafeDelete(fMacro);
}

//________________________________________________________________________
Long64_t TProofLogElem::GetMaxTransferSize()
{
   // Get max transfer size.

   return fgMaxTransferSize;
}

//________________________________________________________________________
void TProofLogElem::SetMaxTransferSize(Long64_t maxsz)
{
   // Set max transfer size.

   fgMaxTransferSize = maxsz;
}

//________________________________________________________________________
Int_t TProofLogElem::Retrieve(TProofLog::ERetrieveOpt opt, const char *pattern)
{
   // Retrieve the content of the associated file. The approximate number
   // of lines to be retrieved is given by 'lines', with the convention that
   // 0 means 'all', a positive number means the first 'lines' and a negative
   // number means the last '-lines'. Default is -1000.
   // If opt == TProofLog::kGrep only the lines containing 'pattern' are
   // retrieved (remote grep functionality); to filter out a pattern 'pat' use
   // pattern = "-v pat".
   // Return 0 on success, -1 in case of any error.

   // Make sure we have a reference manager
   if (!fLogger->fMgr || !fLogger->fMgr->IsValid()) {
      Warning("Retrieve", "No reference manager: corruption?");
      return -1;
   }

   // Print some info on the file
   if (gDebug >= 2) {
      Info("Retrieve", "Retrieving from ordinal %s file %s with pattern %s",
         GetName(), GetTitle(), (pattern ? pattern : "(no pattern)"));
   }

   // Determine offsets
   if (opt == TProofLog::kAll) {
      // Re-read everything
      fFrom = 0;
      fTo = -1;
      if (gDebug >= 1)
         Info("Retrieve", "Retrieving the whole file");
   } else if (opt == TProofLog::kLeading) {
      // Read leading part
      fFrom = 0;
      fTo = fgMaxTransferSize;
      if (gDebug >= 1)
         Info("Retrieve", "Retrieving the leading %lld lines of file", fTo);
   } else if (opt == TProofLog::kGrep) {
      // Retrieve lines containing 'pattern', which must be defined
      if (!pattern || strlen(pattern) <= 0) {
         Error("Retrieve", "option 'Grep' requires a pattern");
         return -1;
      }
      if (gDebug >= 1)
         Info("Retrieve", "Retrieving only lines filtered with %s", pattern);
   } else {
      // Read trailing part
      fFrom = -fgMaxTransferSize;
      fTo = -1;
      if (gDebug >= 1)
         Info("Retrieve", "Retrieving the last %lld lines of file", -fFrom);
   }

   // Reset the macro
   SafeDelete(fMacro);
   fMacro = new TMacro;

   // Size to be read
   Long64_t len = (fTo > fFrom) ? fTo - fFrom : -1;

   // Readout the buffer
   TObjString *os = 0;
   if (fLogger->fMgr) {
      TString fileName = GetTitle();
      if (fileName.Contains("__igprof.pp__")) {
         // File is an IgProf log. Override all patterns and preprocess it
         if (gDebug >= 1)
            Info("Retrieve", "Retrieving analyzed IgProf performance profile");
         TString analyzeAndFilter = \
           "|( T=`mktemp` && cat > \"$T\" ; igprof-analyse -d -g \"$T\" ; rm -f \"$T\" )";
         if (pattern && (*pattern == '|'))
            analyzeAndFilter.Append(pattern);
         os = fLogger->fMgr->ReadBuffer(fileName.Data(), analyzeAndFilter.Data());
      }
      else if (opt == TProofLog::kGrep)
         os = fLogger->fMgr->ReadBuffer(fileName.Data(), pattern);
      else
         os = fLogger->fMgr->ReadBuffer(fileName.Data(), fFrom, len);
   }
   if (os) {
      // Loop over lines
      TString ln;
      Ssiz_t from = 0;
      while (os->String().Tokenize(ln, from, "\n"))
         fMacro->AddLine(ln.Data());

      // Cleanup
      delete os;
   }

   // Done
   return 0;
}

//_____________________________________________________________________________
void TProofLogElem::Display(Int_t from, Int_t to)
{
   // Display the current content starting from line 'from' to line 'to'
   // inclusive.
   // A negative value for 'from' indicates lines counted from the end
   // (tail action); 'to' is ignored in such a case.
   // TProofLog::Prt is called to display: the location (screen, file, box)
   // is defined there.
   // Return 0 on success, -1 in case of any error.

   Int_t nls = (fMacro->GetListOfLines()) ?
                fMacro->GetListOfLines()->GetSize() : 0;

   // Starting line
   Int_t i = 0;
   Int_t ie = (to > -1 && to < nls) ? to : nls;
   if (from > 1) {
      if (from <= nls)
         i = from - 1;
   } else if (from < 0) {
      // Tail action
      if (-from <= nls)
         i = nls + from;
      ie = nls;
   }
   // Write header
   TString msg;
   Prt("// --------- Start of element log -----------------\n");
   msg.Form("// Ordinal: %s (role: %s)\n", GetName(), fRole.Data());
   Prt(msg.Data());
   // Separate out the submaster path, if any
   TString path(GetTitle());
   Int_t ic = path.Index(",");
   if (ic != kNPOS) {
      TString subm(path);
      path.Remove(0, ic+1);
      subm.Remove(ic);
      msg.Form("// Submaster: %s \n", subm.Data());
      Prt(msg.Data());
   }
   msg.Form("// Path: %s \n// # of retrieved lines: %d ", path.Data(), nls);
   Prt(msg.Data());
   if (i > 0 || ie < nls) {
      msg.Form("(displaying lines: %d -> %d)\n", i+1, ie);
   } else {
      msg = "\n";
   }
   Prt(msg.Data());
   Prt("// ------------------------------------------------\n");
   // Write lines
   msg = "";
   if (fMacro->GetListOfLines()) {
      TIter nxl(fMacro->GetListOfLines());
      TObjString *os = 0;
      Int_t kk = 0;
      while ((os = (TObjString *) nxl())) {
         kk++;
         if (kk > i) {
            if (msg.Length() < 100000) {
               if (msg.Length() > 0) msg += "\n";
               msg += os->GetName();
            } else {
               Prt(msg.Data());
               msg = "";
            }
         }
         if (kk > ie) break;
      }
   }
   if (msg.Length() > 0) Prt(msg.Data());
   // Write tail
   Prt("// --------- End of element log -------------------\n\n");
}

//________________________________________________________________________
void TProofLogElem::Print(Option_t *) const
{
   // Print a line with the relevant info.

   Int_t nls = (fMacro->GetListOfLines()) ?
                fMacro->GetListOfLines()->GetSize() : 0;
   const char *role = (strstr(GetTitle(), "worker-")) ? "worker" : "master";

   fprintf(stderr, "Ord: %s Host: Role: %s lines: %d\n", GetName(), role, nls);
}

//________________________________________________________________________
void TProofLogElem::Prt(const char *what)
{
   // Special printing procedure.

   if (fLogger)
      fLogger->Prt(what);
}

//________________________________________________________________________
Int_t TProofLogElem::Grep(const char *txt, TString &res, Int_t from)
{
   // Search lines containing 'txt', starting from line 'from'. Return
   // their blanck-separated list into 'res'.
   // Return the number of lines found, or -1 in case of error.

   Int_t nls = (fMacro->GetListOfLines()) ?
                fMacro->GetListOfLines()->GetSize() : 0;

   Int_t nf = 0;
   Int_t i = (from > 0) ? (from - 1) : 0;
   for( ; i < nls; i++) {
      TObjString *os = (TObjString *) fMacro->GetListOfLines()->At(i);
      if (os) {
         if (strstr(os->GetName(), txt)) {
            if (res.Length() > 0)
               res += " ";
            res += (i + 1);
            nf++;
         }
      }
   }

   // Done
   return nf;
}
 TProofLog.cxx:1
 TProofLog.cxx:2
 TProofLog.cxx:3
 TProofLog.cxx:4
 TProofLog.cxx:5
 TProofLog.cxx:6
 TProofLog.cxx:7
 TProofLog.cxx:8
 TProofLog.cxx:9
 TProofLog.cxx:10
 TProofLog.cxx:11
 TProofLog.cxx:12
 TProofLog.cxx:13
 TProofLog.cxx:14
 TProofLog.cxx:15
 TProofLog.cxx:16
 TProofLog.cxx:17
 TProofLog.cxx:18
 TProofLog.cxx:19
 TProofLog.cxx:20
 TProofLog.cxx:21
 TProofLog.cxx:22
 TProofLog.cxx:23
 TProofLog.cxx:24
 TProofLog.cxx:25
 TProofLog.cxx:26
 TProofLog.cxx:27
 TProofLog.cxx:28
 TProofLog.cxx:29
 TProofLog.cxx:30
 TProofLog.cxx:31
 TProofLog.cxx:32
 TProofLog.cxx:33
 TProofLog.cxx:34
 TProofLog.cxx:35
 TProofLog.cxx:36
 TProofLog.cxx:37
 TProofLog.cxx:38
 TProofLog.cxx:39
 TProofLog.cxx:40
 TProofLog.cxx:41
 TProofLog.cxx:42
 TProofLog.cxx:43
 TProofLog.cxx:44
 TProofLog.cxx:45
 TProofLog.cxx:46
 TProofLog.cxx:47
 TProofLog.cxx:48
 TProofLog.cxx:49
 TProofLog.cxx:50
 TProofLog.cxx:51
 TProofLog.cxx:52
 TProofLog.cxx:53
 TProofLog.cxx:54
 TProofLog.cxx:55
 TProofLog.cxx:56
 TProofLog.cxx:57
 TProofLog.cxx:58
 TProofLog.cxx:59
 TProofLog.cxx:60
 TProofLog.cxx:61
 TProofLog.cxx:62
 TProofLog.cxx:63
 TProofLog.cxx:64
 TProofLog.cxx:65
 TProofLog.cxx:66
 TProofLog.cxx:67
 TProofLog.cxx:68
 TProofLog.cxx:69
 TProofLog.cxx:70
 TProofLog.cxx:71
 TProofLog.cxx:72
 TProofLog.cxx:73
 TProofLog.cxx:74
 TProofLog.cxx:75
 TProofLog.cxx:76
 TProofLog.cxx:77
 TProofLog.cxx:78
 TProofLog.cxx:79
 TProofLog.cxx:80
 TProofLog.cxx:81
 TProofLog.cxx:82
 TProofLog.cxx:83
 TProofLog.cxx:84
 TProofLog.cxx:85
 TProofLog.cxx:86
 TProofLog.cxx:87
 TProofLog.cxx:88
 TProofLog.cxx:89
 TProofLog.cxx:90
 TProofLog.cxx:91
 TProofLog.cxx:92
 TProofLog.cxx:93
 TProofLog.cxx:94
 TProofLog.cxx:95
 TProofLog.cxx:96
 TProofLog.cxx:97
 TProofLog.cxx:98
 TProofLog.cxx:99
 TProofLog.cxx:100
 TProofLog.cxx:101
 TProofLog.cxx:102
 TProofLog.cxx:103
 TProofLog.cxx:104
 TProofLog.cxx:105
 TProofLog.cxx:106
 TProofLog.cxx:107
 TProofLog.cxx:108
 TProofLog.cxx:109
 TProofLog.cxx:110
 TProofLog.cxx:111
 TProofLog.cxx:112
 TProofLog.cxx:113
 TProofLog.cxx:114
 TProofLog.cxx:115
 TProofLog.cxx:116
 TProofLog.cxx:117
 TProofLog.cxx:118
 TProofLog.cxx:119
 TProofLog.cxx:120
 TProofLog.cxx:121
 TProofLog.cxx:122
 TProofLog.cxx:123
 TProofLog.cxx:124
 TProofLog.cxx:125
 TProofLog.cxx:126
 TProofLog.cxx:127
 TProofLog.cxx:128
 TProofLog.cxx:129
 TProofLog.cxx:130
 TProofLog.cxx:131
 TProofLog.cxx:132
 TProofLog.cxx:133
 TProofLog.cxx:134
 TProofLog.cxx:135
 TProofLog.cxx:136
 TProofLog.cxx:137
 TProofLog.cxx:138
 TProofLog.cxx:139
 TProofLog.cxx:140
 TProofLog.cxx:141
 TProofLog.cxx:142
 TProofLog.cxx:143
 TProofLog.cxx:144
 TProofLog.cxx:145
 TProofLog.cxx:146
 TProofLog.cxx:147
 TProofLog.cxx:148
 TProofLog.cxx:149
 TProofLog.cxx:150
 TProofLog.cxx:151
 TProofLog.cxx:152
 TProofLog.cxx:153
 TProofLog.cxx:154
 TProofLog.cxx:155
 TProofLog.cxx:156
 TProofLog.cxx:157
 TProofLog.cxx:158
 TProofLog.cxx:159
 TProofLog.cxx:160
 TProofLog.cxx:161
 TProofLog.cxx:162
 TProofLog.cxx:163
 TProofLog.cxx:164
 TProofLog.cxx:165
 TProofLog.cxx:166
 TProofLog.cxx:167
 TProofLog.cxx:168
 TProofLog.cxx:169
 TProofLog.cxx:170
 TProofLog.cxx:171
 TProofLog.cxx:172
 TProofLog.cxx:173
 TProofLog.cxx:174
 TProofLog.cxx:175
 TProofLog.cxx:176
 TProofLog.cxx:177
 TProofLog.cxx:178
 TProofLog.cxx:179
 TProofLog.cxx:180
 TProofLog.cxx:181
 TProofLog.cxx:182
 TProofLog.cxx:183
 TProofLog.cxx:184
 TProofLog.cxx:185
 TProofLog.cxx:186
 TProofLog.cxx:187
 TProofLog.cxx:188
 TProofLog.cxx:189
 TProofLog.cxx:190
 TProofLog.cxx:191
 TProofLog.cxx:192
 TProofLog.cxx:193
 TProofLog.cxx:194
 TProofLog.cxx:195
 TProofLog.cxx:196
 TProofLog.cxx:197
 TProofLog.cxx:198
 TProofLog.cxx:199
 TProofLog.cxx:200
 TProofLog.cxx:201
 TProofLog.cxx:202
 TProofLog.cxx:203
 TProofLog.cxx:204
 TProofLog.cxx:205
 TProofLog.cxx:206
 TProofLog.cxx:207
 TProofLog.cxx:208
 TProofLog.cxx:209
 TProofLog.cxx:210
 TProofLog.cxx:211
 TProofLog.cxx:212
 TProofLog.cxx:213
 TProofLog.cxx:214
 TProofLog.cxx:215
 TProofLog.cxx:216
 TProofLog.cxx:217
 TProofLog.cxx:218
 TProofLog.cxx:219
 TProofLog.cxx:220
 TProofLog.cxx:221
 TProofLog.cxx:222
 TProofLog.cxx:223
 TProofLog.cxx:224
 TProofLog.cxx:225
 TProofLog.cxx:226
 TProofLog.cxx:227
 TProofLog.cxx:228
 TProofLog.cxx:229
 TProofLog.cxx:230
 TProofLog.cxx:231
 TProofLog.cxx:232
 TProofLog.cxx:233
 TProofLog.cxx:234
 TProofLog.cxx:235
 TProofLog.cxx:236
 TProofLog.cxx:237
 TProofLog.cxx:238
 TProofLog.cxx:239
 TProofLog.cxx:240
 TProofLog.cxx:241
 TProofLog.cxx:242
 TProofLog.cxx:243
 TProofLog.cxx:244
 TProofLog.cxx:245
 TProofLog.cxx:246
 TProofLog.cxx:247
 TProofLog.cxx:248
 TProofLog.cxx:249
 TProofLog.cxx:250
 TProofLog.cxx:251
 TProofLog.cxx:252
 TProofLog.cxx:253
 TProofLog.cxx:254
 TProofLog.cxx:255
 TProofLog.cxx:256
 TProofLog.cxx:257
 TProofLog.cxx:258
 TProofLog.cxx:259
 TProofLog.cxx:260
 TProofLog.cxx:261
 TProofLog.cxx:262
 TProofLog.cxx:263
 TProofLog.cxx:264
 TProofLog.cxx:265
 TProofLog.cxx:266
 TProofLog.cxx:267
 TProofLog.cxx:268
 TProofLog.cxx:269
 TProofLog.cxx:270
 TProofLog.cxx:271
 TProofLog.cxx:272
 TProofLog.cxx:273
 TProofLog.cxx:274
 TProofLog.cxx:275
 TProofLog.cxx:276
 TProofLog.cxx:277
 TProofLog.cxx:278
 TProofLog.cxx:279
 TProofLog.cxx:280
 TProofLog.cxx:281
 TProofLog.cxx:282
 TProofLog.cxx:283
 TProofLog.cxx:284
 TProofLog.cxx:285
 TProofLog.cxx:286
 TProofLog.cxx:287
 TProofLog.cxx:288
 TProofLog.cxx:289
 TProofLog.cxx:290
 TProofLog.cxx:291
 TProofLog.cxx:292
 TProofLog.cxx:293
 TProofLog.cxx:294
 TProofLog.cxx:295
 TProofLog.cxx:296
 TProofLog.cxx:297
 TProofLog.cxx:298
 TProofLog.cxx:299
 TProofLog.cxx:300
 TProofLog.cxx:301
 TProofLog.cxx:302
 TProofLog.cxx:303
 TProofLog.cxx:304
 TProofLog.cxx:305
 TProofLog.cxx:306
 TProofLog.cxx:307
 TProofLog.cxx:308
 TProofLog.cxx:309
 TProofLog.cxx:310
 TProofLog.cxx:311
 TProofLog.cxx:312
 TProofLog.cxx:313
 TProofLog.cxx:314
 TProofLog.cxx:315
 TProofLog.cxx:316
 TProofLog.cxx:317
 TProofLog.cxx:318
 TProofLog.cxx:319
 TProofLog.cxx:320
 TProofLog.cxx:321
 TProofLog.cxx:322
 TProofLog.cxx:323
 TProofLog.cxx:324
 TProofLog.cxx:325
 TProofLog.cxx:326
 TProofLog.cxx:327
 TProofLog.cxx:328
 TProofLog.cxx:329
 TProofLog.cxx:330
 TProofLog.cxx:331
 TProofLog.cxx:332
 TProofLog.cxx:333
 TProofLog.cxx:334
 TProofLog.cxx:335
 TProofLog.cxx:336
 TProofLog.cxx:337
 TProofLog.cxx:338
 TProofLog.cxx:339
 TProofLog.cxx:340
 TProofLog.cxx:341
 TProofLog.cxx:342
 TProofLog.cxx:343
 TProofLog.cxx:344
 TProofLog.cxx:345
 TProofLog.cxx:346
 TProofLog.cxx:347
 TProofLog.cxx:348
 TProofLog.cxx:349
 TProofLog.cxx:350
 TProofLog.cxx:351
 TProofLog.cxx:352
 TProofLog.cxx:353
 TProofLog.cxx:354
 TProofLog.cxx:355
 TProofLog.cxx:356
 TProofLog.cxx:357
 TProofLog.cxx:358
 TProofLog.cxx:359
 TProofLog.cxx:360
 TProofLog.cxx:361
 TProofLog.cxx:362
 TProofLog.cxx:363
 TProofLog.cxx:364
 TProofLog.cxx:365
 TProofLog.cxx:366
 TProofLog.cxx:367
 TProofLog.cxx:368
 TProofLog.cxx:369
 TProofLog.cxx:370
 TProofLog.cxx:371
 TProofLog.cxx:372
 TProofLog.cxx:373
 TProofLog.cxx:374
 TProofLog.cxx:375
 TProofLog.cxx:376
 TProofLog.cxx:377
 TProofLog.cxx:378
 TProofLog.cxx:379
 TProofLog.cxx:380
 TProofLog.cxx:381
 TProofLog.cxx:382
 TProofLog.cxx:383
 TProofLog.cxx:384
 TProofLog.cxx:385
 TProofLog.cxx:386
 TProofLog.cxx:387
 TProofLog.cxx:388
 TProofLog.cxx:389
 TProofLog.cxx:390
 TProofLog.cxx:391
 TProofLog.cxx:392
 TProofLog.cxx:393
 TProofLog.cxx:394
 TProofLog.cxx:395
 TProofLog.cxx:396
 TProofLog.cxx:397
 TProofLog.cxx:398
 TProofLog.cxx:399
 TProofLog.cxx:400
 TProofLog.cxx:401
 TProofLog.cxx:402
 TProofLog.cxx:403
 TProofLog.cxx:404
 TProofLog.cxx:405
 TProofLog.cxx:406
 TProofLog.cxx:407
 TProofLog.cxx:408
 TProofLog.cxx:409
 TProofLog.cxx:410
 TProofLog.cxx:411
 TProofLog.cxx:412
 TProofLog.cxx:413
 TProofLog.cxx:414
 TProofLog.cxx:415
 TProofLog.cxx:416
 TProofLog.cxx:417
 TProofLog.cxx:418
 TProofLog.cxx:419
 TProofLog.cxx:420
 TProofLog.cxx:421
 TProofLog.cxx:422
 TProofLog.cxx:423
 TProofLog.cxx:424
 TProofLog.cxx:425
 TProofLog.cxx:426
 TProofLog.cxx:427
 TProofLog.cxx:428
 TProofLog.cxx:429
 TProofLog.cxx:430
 TProofLog.cxx:431
 TProofLog.cxx:432
 TProofLog.cxx:433
 TProofLog.cxx:434
 TProofLog.cxx:435
 TProofLog.cxx:436
 TProofLog.cxx:437
 TProofLog.cxx:438
 TProofLog.cxx:439
 TProofLog.cxx:440
 TProofLog.cxx:441
 TProofLog.cxx:442
 TProofLog.cxx:443
 TProofLog.cxx:444
 TProofLog.cxx:445
 TProofLog.cxx:446
 TProofLog.cxx:447
 TProofLog.cxx:448
 TProofLog.cxx:449
 TProofLog.cxx:450
 TProofLog.cxx:451
 TProofLog.cxx:452
 TProofLog.cxx:453
 TProofLog.cxx:454
 TProofLog.cxx:455
 TProofLog.cxx:456
 TProofLog.cxx:457
 TProofLog.cxx:458
 TProofLog.cxx:459
 TProofLog.cxx:460
 TProofLog.cxx:461
 TProofLog.cxx:462
 TProofLog.cxx:463
 TProofLog.cxx:464
 TProofLog.cxx:465
 TProofLog.cxx:466
 TProofLog.cxx:467
 TProofLog.cxx:468
 TProofLog.cxx:469
 TProofLog.cxx:470
 TProofLog.cxx:471
 TProofLog.cxx:472
 TProofLog.cxx:473
 TProofLog.cxx:474
 TProofLog.cxx:475
 TProofLog.cxx:476
 TProofLog.cxx:477
 TProofLog.cxx:478
 TProofLog.cxx:479
 TProofLog.cxx:480
 TProofLog.cxx:481
 TProofLog.cxx:482
 TProofLog.cxx:483
 TProofLog.cxx:484
 TProofLog.cxx:485
 TProofLog.cxx:486
 TProofLog.cxx:487
 TProofLog.cxx:488
 TProofLog.cxx:489
 TProofLog.cxx:490
 TProofLog.cxx:491
 TProofLog.cxx:492
 TProofLog.cxx:493
 TProofLog.cxx:494
 TProofLog.cxx:495
 TProofLog.cxx:496
 TProofLog.cxx:497
 TProofLog.cxx:498
 TProofLog.cxx:499
 TProofLog.cxx:500
 TProofLog.cxx:501
 TProofLog.cxx:502
 TProofLog.cxx:503
 TProofLog.cxx:504
 TProofLog.cxx:505
 TProofLog.cxx:506
 TProofLog.cxx:507
 TProofLog.cxx:508
 TProofLog.cxx:509
 TProofLog.cxx:510
 TProofLog.cxx:511
 TProofLog.cxx:512
 TProofLog.cxx:513
 TProofLog.cxx:514
 TProofLog.cxx:515
 TProofLog.cxx:516
 TProofLog.cxx:517
 TProofLog.cxx:518
 TProofLog.cxx:519
 TProofLog.cxx:520
 TProofLog.cxx:521
 TProofLog.cxx:522
 TProofLog.cxx:523
 TProofLog.cxx:524
 TProofLog.cxx:525
 TProofLog.cxx:526
 TProofLog.cxx:527
 TProofLog.cxx:528
 TProofLog.cxx:529
 TProofLog.cxx:530
 TProofLog.cxx:531
 TProofLog.cxx:532
 TProofLog.cxx:533
 TProofLog.cxx:534
 TProofLog.cxx:535
 TProofLog.cxx:536
 TProofLog.cxx:537
 TProofLog.cxx:538
 TProofLog.cxx:539
 TProofLog.cxx:540
 TProofLog.cxx:541
 TProofLog.cxx:542
 TProofLog.cxx:543
 TProofLog.cxx:544
 TProofLog.cxx:545
 TProofLog.cxx:546
 TProofLog.cxx:547
 TProofLog.cxx:548
 TProofLog.cxx:549
 TProofLog.cxx:550
 TProofLog.cxx:551
 TProofLog.cxx:552
 TProofLog.cxx:553
 TProofLog.cxx:554
 TProofLog.cxx:555
 TProofLog.cxx:556
 TProofLog.cxx:557
 TProofLog.cxx:558
 TProofLog.cxx:559
 TProofLog.cxx:560
 TProofLog.cxx:561
 TProofLog.cxx:562
 TProofLog.cxx:563
 TProofLog.cxx:564
 TProofLog.cxx:565
 TProofLog.cxx:566
 TProofLog.cxx:567
 TProofLog.cxx:568
 TProofLog.cxx:569
 TProofLog.cxx:570
 TProofLog.cxx:571
 TProofLog.cxx:572
 TProofLog.cxx:573
 TProofLog.cxx:574
 TProofLog.cxx:575
 TProofLog.cxx:576
 TProofLog.cxx:577
 TProofLog.cxx:578
 TProofLog.cxx:579
 TProofLog.cxx:580
 TProofLog.cxx:581