C++InterfacetoTauola
include/Tauola/Log.h
1 #ifndef __LOG_CLASS_HEADER__
2 #define __LOG_CLASS_HEADER__
3 
4 /**
5  * This file contains class for logging and filtering output.
6  * This header file also includes a debug macro which
7  * tracks any possible memory leaks within the program.
8  *
9  * @author Tomasz Przedzinski
10  * @date 14 November 2009
11  */
12 
13 #include <iostream>
14 #include <string>
15 #include <sstream>
16 #include <stdlib.h>
17 #include <cstring>
18 #include <list>
19 
20 using std::stringstream;
21 using std::string;
22 using std::streambuf;
23 using std::ostream;
24 using std::list;
25 using std::cout;
26 using std::endl;
27 
28 namespace Tauolapp
29 {
30 
31 class Log
32 {
33 public:
34  /** Shows the summary of all messages. */
35  static void Summary();
36 
37  /** Shows the summary at the end of the program. */
38  static void SummaryAtExit() { atexit(Summary); }
39 
40  /** Adds the decay to the counter. The type is:
41  0 - gun, 1 - no mothers & grandmothers, 2 - no mothers, 3 - ok. */
42  static void AddDecay(int type);
43 
44  /** Four logging entries. Usage:
45  Log::Info()<<"Logging some info: "<<8<<" > "<<7.9<<endl;
46  Use Log::Info(false) if you don't want the message to be counted.*/
47  static ostream& Debug(unsigned short int code=0, bool count=true);
48  static ostream& Info(bool count=true);
49  static ostream& Warning(bool count=true);
50  static ostream& Error(bool count=true);
51 
52  /** Turns off or on particular types of messages
53  By default, only debugging messages are turned off. */
54  static void LogInfo (bool flag=true) { iAction=flag; }
55  static void LogWarning(bool flag=true) { wAction=flag; }
56  static void LogError (bool flag=true) { eAction=flag; }
57 
58  static void LogAll (bool flag=true) { iAction=wAction=eAction=flag; dRangeS=0; dRangeE=65535; }
59 
60  /** Sets the range of debug codes that will be printed.
61  By default, the debug messages are turned off. */
62  static void LogDebug(unsigned short s=0,unsigned short e=65535) { dRangeS=s; dRangeE=e; }
63 
64  /** Asserts logical value. If the assertion fails, the default message or 'text'
65  will be printed and the program will terminate.
66  Program termination can be suppressed by Log::IgnoreFailedAsserts(); */
67  static void Assert(bool check, char *text=NULL);
68 
69  /** Terminates the program with added default message or 'text'.
70  It can be suppressed by Log::IgnoreFatal(); */
71  static void Fatal(string text, unsigned short int code=0);
72  static void Fatal(unsigned short int code=0) { Fatal("",code); }
73 
74  /** Redirects output to log. Redirection can be done for a block of code
75  or for one function only. Redirection can be turned off by using
76  Log::IgnoreRedirection(); If the target is one of the log streams
77  (for example): Log::RedirectOutput( someFunction, Log::Info() );
78  You can turn the function's messages off by turning the apropriate
79  log entries off. The redirected code will still be executed,
80  only messages are redirected. */
81  static void RedirectOutput(void (*func)(), ostream& where=*out);
82  static void RedirectOutput(ostream& where=*out);
83  /** WARNING! If you're redirecting more than one function, do not forget
84  to use RevertOutput() afterwards. */
85  static void RevertOutput() { std::cout.rdbuf(bCout); std::cerr.rdbuf(bCerr); }
86 
87  /** Do not exit when Log::Assert() check is false.
88  The number of failed asserts will be listed in the summary. */
89  static void IgnoreFailedAssert(bool flag=true) { asAction=!flag; }
90 
91  /** Ignores redirections of functions' output.
92  The function will still be called in a normal way. */
93  static void IgnoreRedirection(bool flag=true) { rAction=!flag; }
94 
95  /** Do not exit when Log::Fatal() with the code within the provided range is called.
96  The number of ignored fatal errors will be listed in the summary. */
97  static void IgnoreFatal(unsigned short s=0,unsigned short e=65535) { faRangeS=s; faRangeE=e; }
98 
99  /** Change the output of the logged messages.
100  Log::SetOutput(cerr); //changes the output to cerr
101  Log::SetOutput(new ofstream("log.txt")); //changes the output to a file "log.txt" */
102  static void SetOutput(ostream *newOut) { out=newOut; }
103  static void SetOutput(ostream &newOut) { out=&newOut; }
104 
105  /** Change the limit of warnings that will be displayed. Set to 0 for no limit. */
106  static void SetWarningLimit(int x) { warnLimit=x; }
107 
108 protected:
109  static streambuf *bCout,*bCerr;
110  static ostream *out;
111  static stringstream buf;
112  static int warnLimit;
113  static int decays[4];
114  static int dCount,dRangeS,dRangeE,faCount,faRangeS,faRangeE;
115  static int iCount, wCount, eCount, asCount, asFailedCount;
116  static bool iAction,wAction,eAction,asAction,rAction;
117 /**
118  Memory leak tracking section. Compile with #define _LOG_DEBUG_MODE_ to turn it on.
119  WARNING! Increases execution time significantly. Useful only for debug purposes.
120 */
121 protected:
122  typedef struct
123  {
124  unsigned long address;
125  unsigned long size;
126  char file[64];
127  unsigned long line;
128  } Pointer;
129  static list<Pointer*> *PointerList;
130 public:
131 #ifdef _LOG_DEBUG_MODE_
132  static void NewPointer(unsigned long address, unsigned long size, const char *file, unsigned long line)
133  {
134  if(!PointerList)
135  {
136  PointerList = new list<Pointer *>();
137  atexit(PrintAllocatedPointers);
138  }
139  Pointer *info = new Pointer();
140  info->address = address;
141  info->size = size;
142  info->line = line;
143  strncpy(info->file, file, 63);
144  PointerList->push_front(info);
145  }
146  static void DeletePointer(unsigned long address)
147  {
148  if(!PointerList) return;
149  for(list<Pointer*>::iterator i = PointerList->begin(); i!=PointerList->end(); i++)
150  {
151  if((*i)->address == address)
152  {
153  PointerList->remove((*i));
154  break;
155  }
156  }
157  }
158  static bool PointerCompare(Pointer *one, Pointer *two)
159  {
160  int eq = strcmp(one->file,two->file);
161  if(eq<0) return true;
162  else if(eq>0) return false;
163  return (one->line <= two->line);
164  }
165  static void PrintAllocatedPointers()
166  {
167  if(!PointerList) return;
168  int pointers=0,buf=0;
169  unsigned long total=0;
170  char *lastS=" ";
171  int lastL=0;
172  if(PointerList->size()==0)
173  {
174  cout<<"----------------------------UNFREED MEMORY POINTERS----------------------------\n";
175  cout<<" ... NONE ...\n";
176  cout<<"-------------------------------------------------------------------------------\n";
177  return;
178  }
179  PointerList->sort(PointerCompare);
180  cout<<"---------------------------UNFREED MEMORY POINTERS---------------------------\n";
181  for(list<Pointer*>::iterator i = PointerList->begin(); i!=PointerList->end(); i++)
182  {
183  total+=(*i)->size;
184  ++pointers;
185  if(strcmp(lastS,(*i)->file)==0)
186  {
187  if(lastL==(*i)->line)
188  {
189  printf("%56s%10lub (%lu)\n"," ",(*i)->size,(*i)->address);
190  continue;
191  }
192  }
193  lastS=(*i)->file;
194  lastL=(*i)->line;
195  printf("%s%n:",(*i)->file,&buf);
196  printf("%-*lu%10lub (%lu)\n",55-buf,(*i)->line,(*i)->size,(*i)->address);
197  }
198  cout<<endl<<total<<"\tbytes"<<endl;
199  cout<<pointers<<"\tpointers"<<endl;
200  cout<<"-------------------------------------------------------------------------------\n";
201  };
202 #endif //_LOG_DEBUG_MODE_
203 };
204 
205 #ifdef _LOG_DEBUG_MODE_
206 
207 /**
208  Redeclare new and delete to use the tracking feature.
209  To use __FILE__ and __LINE__ macro efficiently this header file
210  should be included in all separately compiled libraries.
211 */
212 
213 inline void* operator new(size_t size, const char *filename, int line)
214 {
215  void *ptr = (void *)malloc(size);
216  Log::NewPointer((unsigned long)ptr, size, filename, line);
217  return(ptr);
218 }
219 
220 inline void operator delete(void *p)
221 {
222  Log::DeletePointer((unsigned long)p);
223  free(p);
224 }
225 
226 #define new new(__FILE__, __LINE__)
227 
228 #endif //_LOG_DEBUG_MODE_
229 
230 } // namespace Tauolapp
231 #endif
static void Summary()
Definition: Log.cxx:113
static void LogDebug(unsigned short s=0, unsigned short e=65535)
static void SummaryAtExit()
static void RedirectOutput(void(*func)(), ostream &where=*out)
Definition: Log.cxx:93
static void IgnoreFatal(unsigned short s=0, unsigned short e=65535)
static void Assert(bool check, char *text=NULL)
Definition: Log.cxx:73
static void AddDecay(int type)
Definition: Log.cxx:25
static void SetWarningLimit(int x)
static void SetOutput(ostream *newOut)
static ostream & Debug(unsigned short int code=0, bool count=true)
Definition: Log.cxx:30
static void RevertOutput()
static void IgnoreRedirection(bool flag=true)
static void LogInfo(bool flag=true)
static void Fatal(string text, unsigned short int code=0)
static void IgnoreFailedAssert(bool flag=true)