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

Last change on this file since 1788 was 1743, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 8.8 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->SetTopEntry(fGuiLineId-1);
213 fgui->SetBit(kHasChanged);
214
215 UnLock();
216}
217
218void MLog::Lock()
219{
220 pthread_mutex_lock((pthread_mutex_t*)fMuxGui);
221}
222
223void MLog::UnLock()
224{
225 pthread_mutex_unlock((pthread_mutex_t*)fMuxGui);
226}
227
228// --------------------------------------------------------------------------
229//
230// This is called to flush the buffer of the streaming devices
231//
232int MLog::sync()
233{
234 Lock();
235 WriteBuffer();
236 UnLock();
237
238 if (fDevice&eStdout)
239 cout.flush();
240
241 if (fDevice&eStderr)
242 cerr.flush();
243
244 if (fDevice&eFile && fout)
245 fout->flush();
246
247 return 0;
248}
249
250// --------------------------------------------------------------------------
251//
252// This function comes from streambuf and should
253// output the buffer to the device (flush, endl)
254// or handle a buffer overflow (too many chars)
255// If a real overflow happens i contains the next
256// chars which doesn't fit into the buffer anymore.
257// If the buffer is not really filled i is EOF(-1).
258//
259int MLog::overflow(int i) // i=EOF means not a real overflow
260{
261 //
262 // no output if
263 //
264 if (fOutputLevel <= fDebugLevel)
265 {
266 Lock();
267
268 *fPPtr++ = (char)i;
269
270 if (fPPtr == fEPtr)
271 WriteBuffer();
272
273 UnLock();
274 }
275
276 return 0;
277}
278
279// --------------------------------------------------------------------------
280//
281// Create a new instance of an file output stream
282// an set the corresponding flag
283//
284void MLog::AllocateFile(const char *fname)
285{
286 char *txt = (char*)"logXXXXXX";
287 fout = fname ? new ofstream(fname) : new ofstream(mkstemp(txt));
288 fOutAllocated = kTRUE;
289}
290
291// --------------------------------------------------------------------------
292//
293// if fout was allocated by this instance of MLooging
294// delete it.
295//
296void MLog::DeallocateFile()
297{
298 if (fOutAllocated)
299 delete fout;
300}
301
302// --------------------------------------------------------------------------
303//
304// if necessary delete the old in stance of the file
305// output stream and create a new one
306//
307void MLog::ReallocateFile(const char *fname)
308{
309 DeallocateFile();
310 AllocateFile(fname);
311}
312
313// --------------------------------------------------------------------------
314//
315// This function checks if a device should get enabled or disabled.
316//
317void MLog::CheckFlag(Flags_t chk, int flag)
318{
319 if (flag==-1)
320 return;
321
322 flag ? EnableOutputDevice(chk) : DisableOutputDevice(chk);
323}
Note: See TracBrowser for help on using the repository browser.