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