/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz 12/2000 ! ! Copyright: MAGIC Software Development, 2000-2001 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // // MLog // // // // This is what we call the logging-system. // // // // It is derived from the C++ streaming classes and can handle our // // logging. The log output can be redirected to stdout, stderr, any other // // stream or a root window. // // // // There is a global log-instance which you can use like cout, id is gLog. // // A log-instance of your choice (gLog by default) is destributed to all // // Task which are used in an eventloop, so that you can redirect the output // // of one eventloop to where you want.. // // // ////////////////////////////////////////////////////////////////////////////// #include "MLog.h" #include // mkstempe #include #include #include "MLogManip.h" ClassImp(MLog); // // This is the definition of the global log facility // MLog gLog; // -------------------------------------------------------------------------- // // this strange usage of an unbufferd buffer is a workaround // to make it work on Alpha and Linux! // void MLog::Init() { setp(&fBuffer, &fBuffer+1); *this << '\0'; } // -------------------------------------------------------------------------- // // default constructor which initializes the streamer and sets the device // which is used for the output (i) // MLog::MLog(int i) : ostream(this), fPPtr(fBase), fEPtr(fBase+bsz), fOutputLevel(0), fDebugLevel((unsigned)-1), fDevice(i), fGuiLineId(0), fout(NULL), fOutAllocated(kFALSE), fgui(NULL) { Init(); } // -------------------------------------------------------------------------- // // default constructor which initializes the streamer and sets the given // ofstream as the default output device // MLog::MLog(ofstream &out) : ostream(this), fPPtr(fBase), fEPtr(fBase+bsz), fOutputLevel(0), fDebugLevel((unsigned)-1), fDevice(eFile), fGuiLineId(0), fout(&out), fOutAllocated(kFALSE), fgui(NULL) { Init(); } // -------------------------------------------------------------------------- // // default constructor which initializes the streamer and sets the given // TGListBox as the default output device // MLog::MLog(TGListBox &out) : ostream(this), fPPtr(fBase), fEPtr(fBase+bsz), fOutputLevel(0), fDebugLevel((unsigned)-1), fDevice(eGui), fGuiLineId(0), fout(NULL), fOutAllocated(kFALSE), fgui(&out) { Init(); } // -------------------------------------------------------------------------- // // default constructor which initializes the streamer and opens a file with // the given name. Dependend on the flag the file is set as output device // or not. // MLog::MLog(const char *fname, int flag) : ostream(this), fPPtr(fBase), fEPtr(fBase+bsz), fOutputLevel(0), fDebugLevel((unsigned)-1), fDevice(eFile), fGuiLineId(0), fgui(NULL) { Init(); AllocateFile(fname); CheckFlag(eFile, flag); } // -------------------------------------------------------------------------- // // copyt constructor // MLog::MLog(MLog &log) { fOutputLevel = log.fOutputLevel; fDebugLevel = log.fDebugLevel; fDevice = log.fDevice; } // -------------------------------------------------------------------------- // // This is the function which writes the stream physically to a device. // If you want to add a new device this must be done here. // void MLog::WriteBuffer() { const int len = fPPtr - fBase; if (fDevice&eStdout) cout.write(fBase, len); if (fDevice&eStderr) cerr.write(fBase, len); if (fDevice&eFile && fout) fout->write(fBase, len); if (fDevice&eGui && fgui) { char *dummy = new char[len+1]; memcpy(dummy, fBase, len); *(dummy+len)='\0'; fgui->AddEntry(dummy, fGuiLineId); fgui->SetTopEntry(fGuiLineId++); fgui->SetBit(kHasChanged); delete dummy; } // // restart writing to the buffer at its first char // fPPtr = fBase; } // -------------------------------------------------------------------------- // // This is called to flush the buffer of the streaming devices // int MLog::sync() { WriteBuffer(); if (fDevice&eStdout) cout.flush(); if (fDevice&eStderr) cerr.flush(); if (fDevice&eFile && fout) fout->flush(); return 0; } // -------------------------------------------------------------------------- // // This function comes from streambuf and should // output the buffer to the device (flush, endl) // or handle a buffer overflow (too many chars) // If a real overflow happens i contains the next // chars which doesn't fit into the buffer anymore. // If the buffer is not really filled i is EOF(-1). // int MLog::overflow(int i) // i=EOF means not a real overflow { // // no output if // if (fOutputLevel > fDebugLevel) return 0; *fPPtr++ = (char)i; if (fPPtr == fEPtr) WriteBuffer(); return 0; } // -------------------------------------------------------------------------- // // Create a new instance of an file output stream // an set the corresponding flag // void MLog::AllocateFile(const char *fname) { fout = fname ? new ofstream(fname) : new ofstream(mkstemp("logXXXXXX")); fOutAllocated = kTRUE; } // -------------------------------------------------------------------------- // // if fout was allocated by this instance of MLooging // delete it. // void MLog::DeallocateFile() { if (fOutAllocated) delete fout; } // -------------------------------------------------------------------------- // // if necessary delete the old in stance of the file // output stream and create a new one // void MLog::ReallocateFile(const char *fname) { DeallocateFile(); AllocateFile(fname); } // -------------------------------------------------------------------------- // // This function checks if a device should get enabled or disabled. // void MLog::CheckFlag(Flags_t chk, int flag) { if (flag==-1) return; flag ? EnableOutputDevice(chk) : DisableOutputDevice(chk); }