include/Photos/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
20using std::stringstream;
21using std::string;
22using std::streambuf;
23using std::ostream;
24using std::list;
25using std::cout;
26using std::endl;
27
28namespace Photospp
29{
30
31extern void (*PHOERR)(int,const char*,double);
32extern void (*PHOREP)();
33
34class Log
35{
36public:
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
120protected:
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*/
133protected:
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;
142public:
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
225inline 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
232inline 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 ostream & Debug(unsigned short int code=0, bool count=true)
Definition Log.cxx:33
static void AddDecay(int type)
Definition Log.cxx:28
static void Assert(bool check, char *text=NULL)
Definition Log.cxx:75
static void SetWarningLimit(int x)
static void IgnoreFatal(unsigned short s=0, unsigned short e=65535)
static void SetOutput(ostream *newOut)
static void LogInfo(bool flag=true)
static void Fatal(string text, unsigned short int code=0)
static void PHOREP()
Definition Log.cxx:285
static void RevertOutput()
static void RedirectOutput(void(*func)(), ostream &where=*out)
Definition Log.cxx:93
static void IgnoreRedirection(bool flag=true)
static void SummaryAtExit()
static void IgnoreFailedAssert(bool flag=true)
static void LogDebug(unsigned short s=0, unsigned short e=65535)
static void Summary()
Definition Log.cxx:113
STL iterator class.