1 #ifndef __LOG_CLASS_HEADER__
2 #define __LOG_CLASS_HEADER__
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.
9 * @author Tomasz Przedzinski
10 * @date 14 November 2009
20 using std::stringstream;
34 /** Shows the summary of all messages. */
35 static void Summary();
37 /** Shows the summary at the end of the program. */
38 static void SummaryAtExit() { atexit(Summary); }
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);
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);
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; }
58 static void LogAll (bool flag=true) { iAction=wAction=eAction=flag; dRangeS=0; dRangeE=65535; }
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; }
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);
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); }
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); }
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; }
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; }
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; }
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; }
105 /** Change the limit of warnings that will be displayed. Set to 0 for no limit. */
106 static void SetWarningLimit(int x) { warnLimit=x; }
109 static streambuf *bCout,*bCerr;
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;
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.
124 unsigned long address;
129 static list<Pointer*> *PointerList;
131 #ifdef _LOG_DEBUG_MODE_
132 static void NewPointer(unsigned long address, unsigned long size, const char *file, unsigned long line)
136 PointerList = new list<Pointer *>();
137 atexit(PrintAllocatedPointers);
139 Pointer *info = new Pointer();
140 info->address = address;
143 strncpy(info->file, file, 63);
144 PointerList->push_front(info);
146 static void DeletePointer(unsigned long address)
148 if(!PointerList) return;
149 for(list<Pointer*>::iterator i = PointerList->begin(); i!=PointerList->end(); i++)
151 if((*i)->address == address)
153 PointerList->remove((*i));
158 static bool PointerCompare(Pointer *one, Pointer *two)
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);
165 static void PrintAllocatedPointers()
167 if(!PointerList) return;
168 int pointers=0,buf=0;
169 unsigned long total=0;
172 if(PointerList->size()==0)
174 cout<<"----------------------------UNFREED MEMORY POINTERS----------------------------\n";
175 cout<<" ... NONE ...\n";
176 cout<<"-------------------------------------------------------------------------------\n";
179 PointerList->sort(PointerCompare);
180 cout<<"---------------------------UNFREED MEMORY POINTERS---------------------------\n";
181 for(list<Pointer*>::iterator i = PointerList->begin(); i!=PointerList->end(); i++)
185 if(strcmp(lastS,(*i)->file)==0)
187 if(lastL==(*i)->line)
189 printf("%56s%10lub (%lu)\n"," ",(*i)->size,(*i)->address);
195 printf("%s%n:",(*i)->file,&buf);
196 printf("%-*lu%10lub (%lu)\n",55-buf,(*i)->line,(*i)->size,(*i)->address);
198 cout<<endl<<total<<"\tbytes"<<endl;
199 cout<<pointers<<"\tpointers"<<endl;
200 cout<<"-------------------------------------------------------------------------------\n";
202 #endif //_LOG_DEBUG_MODE_
205 #ifdef _LOG_DEBUG_MODE_
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.
213 inline void* operator new(size_t size, const char *filename, int line)
215 void *ptr = (void *)malloc(size);
216 Log::NewPointer((unsigned long)ptr, size, filename, line);
220 inline void operator delete(void *p)
222 Log::DeletePointer((unsigned long)p);
226 #define new new(__FILE__, __LINE__)
228 #endif //_LOG_DEBUG_MODE_
230 } // namespace Tauolapp