// @(#)root/gui:$Id$
// Author: G. Ganis   10/10/2005

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGRedirectOutputGuard                                                //
//                                                                      //
// This class provides output redirection to a TGTextView in guaranteed //
// exception safe way. Use like this:                                   //
// {                                                                    //
//    TGRedirectOutputGuard guard(textview);                            //
//    ... // do something                                               //
//    guard.Update();                                                   //
//    ... // do something else                                          //
// }                                                                    //
// when guard goes out of scope, Update() is called to flush what left  //
// on the screed and the output is automatically redirected again to    //
// the standard units.                                                  //
// The exception mechanism takes care of calling the dtors              //
// of local objects so it is exception safe.                            //
// Optionally the output can also be saved into a file:                 //
// {                                                                    //
//    TGRedirectOutputGuard guard(textview, file, mode);                //
//    ... // do something                                               //
// }                                                                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include <errno.h>
#include <sys/types.h>
#ifdef WIN32
#   include <io.h>
#else
#   include <unistd.h>
#endif

#include "TError.h"
#include "TGRedirectOutputGuard.h"
#include "TGTextView.h"
#include "TSystem.h"

//_____________________________________________________________________________
TGRedirectOutputGuard::TGRedirectOutputGuard(TGTextView *tv,
                                             const char *flog,
                                             const char *mode)
{
   // Create output redirection guard.
   // The TGTextView instance should be initialized outside.
   // Text is added to the existing text in the frame.
   // If defined, 'flog' is interpreted as the path of a file
   // where to save the output; in such a case 'mode' if the
   // opening mode of the file (either "w" or "a").
   // By default a temporary file is used.

   fTextView = tv;
   fLogFile = flog;
   fTmpFile = kFALSE;
   fLogFileRead = 0;
   if (!flog) {
      // Create temporary file
      fLogFile = "RedirOutputGuard_";
      fLogFileRead = gSystem->TempFileName(fLogFile);
      if (!fLogFileRead) {
         Error("TGRedirectOutputGuard", "could create temp file");
         return;
      }
      fTmpFile = kTRUE;

      // We need it in read mode
      fclose(fLogFileRead);
   } else {
      // Check permissions, if existing
      if (!gSystem->AccessPathName(flog, kFileExists)) {
         if (gSystem->AccessPathName(flog,
               (EAccessMode)(kWritePermission | kReadPermission))) {
            Error("TGRedirectOutputGuard",
                  "no write or read permission on file: %s", flog);
            return;
         }
      }
   }

   // Redirect
   const char *m = (mode[0] != 'a' && mode[0] != 'w') ? "a" : mode;
   if (gSystem->RedirectOutput(fLogFile.Data(), m) == -1) {
      Error("TGRedirectOutputGuard","could not redirect output");
      return;
   }

   // Open file in read mode
   if ((fLogFileRead = fopen(fLogFile.Data(),"r"))) {
      // Start reading from the present end
      lseek(fileno(fLogFileRead),(off_t)0, SEEK_END);
   } else {
      Error("TGRedirectOutputGuard","could not open file in read mode");
      return;
   }

   return;
}

//_____________________________________________________________________________
TGRedirectOutputGuard::~TGRedirectOutputGuard()
{
   // Destructor.

   // Display last info
   Update();

   // Close the file
   if (fLogFileRead)
      fclose(fLogFileRead);

   // Unlink the file if we are the owners
   if (fTmpFile && fLogFile.Length() > 0)
      gSystem->Unlink(fLogFile);

   // Restore standard output
   gSystem->RedirectOutput(0);
}

//_____________________________________________________________________________
void TGRedirectOutputGuard::Update()
{
   // Send to text frame the undisplayed content of the file.

   if (!fTextView) {
      Warning("Update","no TGTextView defined");
      return;
   }

   if (!fLogFileRead) {
      Warning("Update","no file open for reading");
      return;
   }

   // Make sure you get anything
   fflush(stdout);

   char line[4096];
   while (fgets(line,sizeof(line),fLogFileRead)) {

      // Get read of carriage return
      if (line[strlen(line)-1] == '\n')
         line[strlen(line)-1] = 0;

      // Send line to the TGTextView
      fTextView->AddLine(line);
   }
}
 TGRedirectOutputGuard.cxx:1
 TGRedirectOutputGuard.cxx:2
 TGRedirectOutputGuard.cxx:3
 TGRedirectOutputGuard.cxx:4
 TGRedirectOutputGuard.cxx:5
 TGRedirectOutputGuard.cxx:6
 TGRedirectOutputGuard.cxx:7
 TGRedirectOutputGuard.cxx:8
 TGRedirectOutputGuard.cxx:9
 TGRedirectOutputGuard.cxx:10
 TGRedirectOutputGuard.cxx:11
 TGRedirectOutputGuard.cxx:12
 TGRedirectOutputGuard.cxx:13
 TGRedirectOutputGuard.cxx:14
 TGRedirectOutputGuard.cxx:15
 TGRedirectOutputGuard.cxx:16
 TGRedirectOutputGuard.cxx:17
 TGRedirectOutputGuard.cxx:18
 TGRedirectOutputGuard.cxx:19
 TGRedirectOutputGuard.cxx:20
 TGRedirectOutputGuard.cxx:21
 TGRedirectOutputGuard.cxx:22
 TGRedirectOutputGuard.cxx:23
 TGRedirectOutputGuard.cxx:24
 TGRedirectOutputGuard.cxx:25
 TGRedirectOutputGuard.cxx:26
 TGRedirectOutputGuard.cxx:27
 TGRedirectOutputGuard.cxx:28
 TGRedirectOutputGuard.cxx:29
 TGRedirectOutputGuard.cxx:30
 TGRedirectOutputGuard.cxx:31
 TGRedirectOutputGuard.cxx:32
 TGRedirectOutputGuard.cxx:33
 TGRedirectOutputGuard.cxx:34
 TGRedirectOutputGuard.cxx:35
 TGRedirectOutputGuard.cxx:36
 TGRedirectOutputGuard.cxx:37
 TGRedirectOutputGuard.cxx:38
 TGRedirectOutputGuard.cxx:39
 TGRedirectOutputGuard.cxx:40
 TGRedirectOutputGuard.cxx:41
 TGRedirectOutputGuard.cxx:42
 TGRedirectOutputGuard.cxx:43
 TGRedirectOutputGuard.cxx:44
 TGRedirectOutputGuard.cxx:45
 TGRedirectOutputGuard.cxx:46
 TGRedirectOutputGuard.cxx:47
 TGRedirectOutputGuard.cxx:48
 TGRedirectOutputGuard.cxx:49
 TGRedirectOutputGuard.cxx:50
 TGRedirectOutputGuard.cxx:51
 TGRedirectOutputGuard.cxx:52
 TGRedirectOutputGuard.cxx:53
 TGRedirectOutputGuard.cxx:54
 TGRedirectOutputGuard.cxx:55
 TGRedirectOutputGuard.cxx:56
 TGRedirectOutputGuard.cxx:57
 TGRedirectOutputGuard.cxx:58
 TGRedirectOutputGuard.cxx:59
 TGRedirectOutputGuard.cxx:60
 TGRedirectOutputGuard.cxx:61
 TGRedirectOutputGuard.cxx:62
 TGRedirectOutputGuard.cxx:63
 TGRedirectOutputGuard.cxx:64
 TGRedirectOutputGuard.cxx:65
 TGRedirectOutputGuard.cxx:66
 TGRedirectOutputGuard.cxx:67
 TGRedirectOutputGuard.cxx:68
 TGRedirectOutputGuard.cxx:69
 TGRedirectOutputGuard.cxx:70
 TGRedirectOutputGuard.cxx:71
 TGRedirectOutputGuard.cxx:72
 TGRedirectOutputGuard.cxx:73
 TGRedirectOutputGuard.cxx:74
 TGRedirectOutputGuard.cxx:75
 TGRedirectOutputGuard.cxx:76
 TGRedirectOutputGuard.cxx:77
 TGRedirectOutputGuard.cxx:78
 TGRedirectOutputGuard.cxx:79
 TGRedirectOutputGuard.cxx:80
 TGRedirectOutputGuard.cxx:81
 TGRedirectOutputGuard.cxx:82
 TGRedirectOutputGuard.cxx:83
 TGRedirectOutputGuard.cxx:84
 TGRedirectOutputGuard.cxx:85
 TGRedirectOutputGuard.cxx:86
 TGRedirectOutputGuard.cxx:87
 TGRedirectOutputGuard.cxx:88
 TGRedirectOutputGuard.cxx:89
 TGRedirectOutputGuard.cxx:90
 TGRedirectOutputGuard.cxx:91
 TGRedirectOutputGuard.cxx:92
 TGRedirectOutputGuard.cxx:93
 TGRedirectOutputGuard.cxx:94
 TGRedirectOutputGuard.cxx:95
 TGRedirectOutputGuard.cxx:96
 TGRedirectOutputGuard.cxx:97
 TGRedirectOutputGuard.cxx:98
 TGRedirectOutputGuard.cxx:99
 TGRedirectOutputGuard.cxx:100
 TGRedirectOutputGuard.cxx:101
 TGRedirectOutputGuard.cxx:102
 TGRedirectOutputGuard.cxx:103
 TGRedirectOutputGuard.cxx:104
 TGRedirectOutputGuard.cxx:105
 TGRedirectOutputGuard.cxx:106
 TGRedirectOutputGuard.cxx:107
 TGRedirectOutputGuard.cxx:108
 TGRedirectOutputGuard.cxx:109
 TGRedirectOutputGuard.cxx:110
 TGRedirectOutputGuard.cxx:111
 TGRedirectOutputGuard.cxx:112
 TGRedirectOutputGuard.cxx:113
 TGRedirectOutputGuard.cxx:114
 TGRedirectOutputGuard.cxx:115
 TGRedirectOutputGuard.cxx:116
 TGRedirectOutputGuard.cxx:117
 TGRedirectOutputGuard.cxx:118
 TGRedirectOutputGuard.cxx:119
 TGRedirectOutputGuard.cxx:120
 TGRedirectOutputGuard.cxx:121
 TGRedirectOutputGuard.cxx:122
 TGRedirectOutputGuard.cxx:123
 TGRedirectOutputGuard.cxx:124
 TGRedirectOutputGuard.cxx:125
 TGRedirectOutputGuard.cxx:126
 TGRedirectOutputGuard.cxx:127
 TGRedirectOutputGuard.cxx:128
 TGRedirectOutputGuard.cxx:129
 TGRedirectOutputGuard.cxx:130
 TGRedirectOutputGuard.cxx:131
 TGRedirectOutputGuard.cxx:132
 TGRedirectOutputGuard.cxx:133
 TGRedirectOutputGuard.cxx:134
 TGRedirectOutputGuard.cxx:135
 TGRedirectOutputGuard.cxx:136
 TGRedirectOutputGuard.cxx:137
 TGRedirectOutputGuard.cxx:138
 TGRedirectOutputGuard.cxx:139
 TGRedirectOutputGuard.cxx:140
 TGRedirectOutputGuard.cxx:141
 TGRedirectOutputGuard.cxx:142
 TGRedirectOutputGuard.cxx:143
 TGRedirectOutputGuard.cxx:144
 TGRedirectOutputGuard.cxx:145
 TGRedirectOutputGuard.cxx:146
 TGRedirectOutputGuard.cxx:147
 TGRedirectOutputGuard.cxx:148
 TGRedirectOutputGuard.cxx:149
 TGRedirectOutputGuard.cxx:150
 TGRedirectOutputGuard.cxx:151
 TGRedirectOutputGuard.cxx:152
 TGRedirectOutputGuard.cxx:153
 TGRedirectOutputGuard.cxx:154
 TGRedirectOutputGuard.cxx:155
 TGRedirectOutputGuard.cxx:156
 TGRedirectOutputGuard.cxx:157
 TGRedirectOutputGuard.cxx:158