source: trunk/MagicSoft/Mars/mbase/MLog.cc@ 1849

Last change on this file since 1849 was 1794, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 8.9 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 12/2000 <mailto:tbretz@uni-sw.gwdg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25
26//////////////////////////////////////////////////////////////////////////////
27// //
28// MLog //
29// //
30// This is what we call the logging-system. //
31// //
32// It is derived from the C++ streaming classes and can handle our //
33// logging. The log output can be redirected to stdout, stderr, any other //
34// stream or a root window. //
35// //
36// There is a global log-instance which you can use like cout, id is gLog. //
37// A log-instance of your choice (gLog by default) is destributed to all //
38// Task which are used in an eventloop, so that you can redirect the output //
39// of one eventloop to where you want.. //
40// //
41//////////////////////////////////////////////////////////////////////////////
42
43#include "MLog.h"
44
45#include <stdlib.h> // mkstempe
46#include <fstream.h>
47#include <pthread.h>
48#include <TGListBox.h>
49
50#include "MLogManip.h"
51
52ClassImp(MLog);
53
54// root 3.02:
55// check for TObjectWarning, TObject::Info, gErrorIgnoreLevel
56
57//
58// This is the definition of the global log facility
59//
60MLog gLog;
61
62// --------------------------------------------------------------------------
63//
64// this strange usage of an unbufferd buffer is a workaround
65// to make it work on Alpha and Linux!
66//
67void MLog::Init()
68{
69 setp(&fBuffer, &fBuffer+1);
70 *this << '\0';
71
72 //
73 // Creat drawing semaphore
74 //
75 fMuxGui = new pthread_mutex_t;
76 pthread_mutex_init((pthread_mutex_t*)fMuxGui, NULL);
77}
78
79// --------------------------------------------------------------------------
80//
81// default constructor which initializes the streamer and sets the device
82// which is used for the output (i)
83//
84MLog::MLog(int i) : ostream(this), fPPtr(fBase), fEPtr(fBase+bsz), fOutputLevel(0), fDebugLevel((unsigned)-1), fDevice(i), fIsNull(kFALSE), fGuiLineId(0), fout(NULL), fOutAllocated(kFALSE), fgui(NULL), fNumLines(0)
85{
86 Init();
87}
88
89// --------------------------------------------------------------------------
90//
91// default constructor which initializes the streamer and sets the given
92// ofstream as the default output device
93//
94MLog::MLog(ofstream &out) : ostream(this), fPPtr(fBase), fEPtr(fBase+bsz), fOutputLevel(0), fDebugLevel((unsigned)-1), fDevice(eFile), fIsNull(kFALSE), fGuiLineId(0), fout(&out), fOutAllocated(kFALSE), fgui(NULL), fNumLines(0)
95{
96 Init();
97}
98
99// --------------------------------------------------------------------------
100//
101// default constructor which initializes the streamer and sets the given
102// TGListBox as the default output device
103//
104MLog::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), fNumLines(0)
105{
106 Init();
107}
108
109// --------------------------------------------------------------------------
110//
111// default constructor which initializes the streamer and opens a file with
112// the given name. Dependend on the flag the file is set as output device
113// or not.
114//
115MLog::MLog(const char *fname, int flag) : ostream(this), fPPtr(fBase), fEPtr(fBase+bsz), fOutputLevel(0), fDebugLevel((unsigned)-1), fDevice(eFile), fIsNull(kFALSE), fGuiLineId(0), fgui(NULL), fNumLines(0)
116{
117 Init();
118
119 AllocateFile(fname);
120 CheckFlag(eFile, flag);
121}
122
123// --------------------------------------------------------------------------
124//
125// Destructor, destroying the gui mutex.
126//
127MLog::~MLog()
128{
129 DeallocateFile();
130 pthread_mutex_destroy((pthread_mutex_t*)fMuxGui);
131}
132
133// --------------------------------------------------------------------------
134//
135// copyt constructor
136//
137MLog::MLog(MLog &log)
138{
139 fOutputLevel = log.fOutputLevel;
140 fDebugLevel = log.fDebugLevel;
141 fDevice = log.fDevice;
142}
143
144// --------------------------------------------------------------------------
145//
146// This is the function which writes the stream physically to a device.
147// If you want to add a new device this must be done here.
148//
149void MLog::WriteBuffer()
150{
151 //
152 // restart writing to the buffer at its first char
153 //
154 const int len = fPPtr - fBase;
155
156 fPPtr = fBase;
157
158 if (fIsNull)
159 return;
160
161 if (fDevice&eStdout)
162 cout.write(fBase, len);
163
164 if (fDevice&eStderr)
165 cerr.write(fBase, len);
166
167 if (fDevice&eFile && fout)
168 fout->write(fBase, len);
169
170 if (fDevice&eGui && fgui)
171 {
172 char **newstr = new char*[fNumLines+1];
173
174 for (int i=0; i<fNumLines; i++)
175 newstr[i] = fGuiLines[i];
176
177 if (fNumLines>0)
178 delete fGuiLines;
179
180 char *dummy = new char[len];
181 memcpy(dummy, fBase, len-1);
182 dummy[len-1]='\0';
183
184 newstr[fNumLines++] = dummy;
185
186 fGuiLines = newstr;
187 }
188}
189
190void MLog::UpdateGui()
191{
192 if (fNumLines==0)
193 return;
194
195 Lock();
196
197// cout << "/---------------------------------------" << endl;
198
199 for (int i=0; i<fNumLines; i++)
200 {
201 fgui->AddEntry(fGuiLines[i], fGuiLineId++);
202// cout << fGuiLines[i] << endl;
203 delete fGuiLines[i];
204 }
205
206 delete fGuiLines;
207
208// cout << "\\---------------------------------------" << endl;
209
210 fNumLines=0;
211
212 fgui->RemoveEntries(0, fGuiLineId-1000);
213 fgui->SetTopEntry(fGuiLineId-1);
214 fgui->SetBit(kHasChanged);
215
216 UnLock();
217}
218
219void MLog::Lock()
220{
221 pthread_mutex_lock((pthread_mutex_t*)fMuxGui);
222}
223
224void MLog::UnLock()
225{
226 pthread_mutex_unlock((pthread_mutex_t*)fMuxGui);
227}
228
229// --------------------------------------------------------------------------
230//
231// This is called to flush the buffer of the streaming devices
232//
233int MLog::sync()
234{
235 Lock();
236 WriteBuffer();
237 UnLock();
238
239 if (fDevice&eStdout)
240 cout.flush();
241
242 if (fDevice&eStderr)
243 cerr.flush();
244
245 if (fDevice&eFile && fout)
246 fout->flush();
247
248 return 0;
249}
250
251// --------------------------------------------------------------------------
252//
253// This function comes from streambuf and should
254// output the buffer to the device (flush, endl)
255// or handle a buffer overflow (too many chars)
256// If a real overflow happens i contains the next
257// chars which doesn't fit into the buffer anymore.
258// If the buffer is not really filled i is EOF(-1).
259//
260int MLog::overflow(int i) // i=EOF means not a real overflow
261{
262 //
263 // no output if
264 //
265 if (fOutputLevel <= fDebugLevel)
266 {
267 Lock();
268
269 *fPPtr++ = (char)i;
270
271 if (fPPtr == fEPtr)
272 WriteBuffer();
273
274 UnLock();
275 }
276
277 return 0;
278}
279
280// --------------------------------------------------------------------------
281//
282// Create a new instance of an file output stream
283// an set the corresponding flag
284//
285void MLog::AllocateFile(const char *fname)
286{
287 char *txt = (char*)"logXXXXXX";
288 fout = fname ? new ofstream(fname) : new ofstream(mkstemp(txt));
289 fOutAllocated = kTRUE;
290}
291
292// --------------------------------------------------------------------------
293//
294// if fout was allocated by this instance of MLooging
295// delete it.
296//
297void MLog::DeallocateFile()
298{
299 if (fOutAllocated)
300 delete fout;
301}
302
303// --------------------------------------------------------------------------
304//
305// if necessary delete the old in stance of the file
306// output stream and create a new one
307//
308void MLog::ReallocateFile(const char *fname)
309{
310 DeallocateFile();
311 AllocateFile(fname);
312}
313
314// --------------------------------------------------------------------------
315//
316// This function checks if a device should get enabled or disabled.
317//
318void MLog::CheckFlag(Flags_t chk, int flag)
319{
320 if (flag==-1)
321 return;
322
323 flag ? EnableOutputDevice(chk) : DisableOutputDevice(chk);
324}
Note: See TracBrowser for help on using the repository browser.