00001 /* 00002 SagaEngine library 00003 Copyright (c) 2002-2006 Skalden Studio AS 00004 00005 This software is provided 'as-is', without any express or implied 00006 warranty. In no event will the authors be held liable for any 00007 damages arising from the use of this software. 00008 00009 Permission is granted to distribute the library under the terms of the 00010 Q Public License version 1.0. Be sure to read and understand the license 00011 before using the library. It should be included here, or you may read it 00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl 00013 00014 The original version of this library can be located at: 00015 http://www.sagaengine.com/ 00016 00017 Rune Myrland 00018 rune@skalden.com 00019 */ 00020 00021 00022 #include "Log.hpp" 00023 #include "../system/util_system.hpp" 00024 #include "../math/BrayT.hpp" 00025 #include <malloc.h> 00026 #ifdef _WINDOWS 00027 #include <Windows.h> 00028 #endif 00029 #include <cstdio> 00030 #include <cstdlib> 00031 00032 namespace se_err { 00033 void dump(const char *s) { 00034 # ifdef _WINDOWS 00035 OutputDebugString(s); 00036 OutputDebugString("\n"); 00037 # endif 00038 00039 fputs(s, stderr); 00040 fputs("\n", stderr); 00041 fflush(stderr); 00042 } 00043 00044 00045 void scream3(const char* file, int line, const char* msg) { 00046 char buffer[512]; 00047 sprintf(buffer, "Fat: \"%s\" (%s-%d)", msg, file, line); 00048 dump(buffer); 00049 00050 # ifdef _WINDOWS 00051 sprintf(buffer, "(%s-%d)", file, line); 00052 ::MessageBox (0, msg, buffer, MB_ICONEXCLAMATION | MB_OK); 00053 # endif 00054 // Unhandled exception throws to debugger in Visual C++. 00055 throw 0.0f; 00056 } 00057 void say3(const char* file, int line, const char* msg) { 00058 char buffer[512]; 00059 sprintf(buffer, "Wrn: \"%s\" (%s-%d)", msg, file, line); 00060 dump(buffer); 00061 } 00062 void whisper3(const char* file, int line, const char* msg) { 00063 char buffer[512]; 00064 sprintf(buffer, "Msg: \"%s\" (%s-%d)", msg, file, line); 00065 dump(buffer); 00066 } 00067 void silent3(const char* file, int line, const char* msg) { 00068 char buffer[512]; 00069 sprintf(buffer, "Det: \"%s\" (%s-%d)", msg, file, line); 00070 dump(buffer); 00071 } 00072 00073 void debugStop() { 00074 static int count = 0; 00075 //say3(__FILE__, __LINE__, s); 00076 ++count; 00077 } 00078 } 00079 00080 char* log_msg() { 00081 static char message[512] VAR_IN_EWRAM; 00082 return message; 00083 } 00084 00085 00086 namespace se_err { 00087 /* 00088 Log& Log 00089 ::singleton() { 00090 static Log lg; 00091 return lg; 00092 } 00093 */ 00094 00095 00096 Log& Log 00097 ::file(const char* file, int line) { 00098 msgPos_ = 0; 00099 msg_[0] = 0; 00100 line_ = line; 00101 file_ = file; 00102 return *this; 00103 } 00104 00105 00106 Log& Log 00107 ::scream() { 00108 scream3(file_, line_, msg_); 00109 return *this; 00110 } 00111 00112 00113 Log& Log 00114 ::say() { 00115 say3(file_, line_, msg_); 00116 return *this; 00117 } 00118 00119 00120 Log& Log 00121 ::whisper() { 00122 whisper3(file_, line_, msg_); 00123 return *this; 00124 } 00125 00126 00127 Log& Log 00128 ::silent() { 00129 silent3(file_, line_, msg_); 00130 return *this; 00131 } 00132 00133 00134 Log& Log 00135 ::operator << (const char* msg) { 00136 copy(msg); 00137 return *this; 00138 } 00139 00140 00141 Log& Log 00142 ::operator << (char c) { 00143 sprintf(tmp_, "%c", c); 00144 copy(tmp_); 00145 return *this; 00146 } 00147 00148 00149 Log& Log 00150 ::operator << (float n) { 00151 sprintf(tmp_, "%f", n); 00152 copy(tmp_); 00153 return *this; 00154 } 00155 00156 00157 Log& Log 00158 ::operator << (double n) { 00159 sprintf(tmp_, "%f", n); 00160 copy(tmp_); 00161 return *this; 00162 } 00163 00164 00165 Log& Log 00166 ::operator << (int n) { 00167 sprintf(tmp_, "%d", n); 00168 copy(tmp_); 00169 return *this; 00170 } 00171 00172 00173 Log& Log 00174 ::operator << (unsigned int n) { 00175 sprintf(tmp_, "%d", n); 00176 copy(tmp_); 00177 return *this; 00178 } 00179 00180 00181 Log& Log 00182 ::operator << (bray_t n) { 00183 sprintf(tmp_, "%f", se_core::BrayT::toDeg(n)); 00184 copy(tmp_); 00185 return *this; 00186 } 00187 00188 00189 Log& Log 00190 ::operator << (unsigned long n) { 00191 sprintf(tmp_, "%d", n); 00192 copy(tmp_); 00193 return *this; 00194 } 00195 00196 00197 Log& Log 00198 ::operator << (long n) { 00199 sprintf(tmp_, "%d", n); 00200 copy(tmp_); 00201 return *this; 00202 } 00203 00204 00205 Log& Log 00206 ::operator << (const se_core::String& s) { 00207 copy(s.get()); 00208 return *this; 00209 } 00210 00211 00212 Log& Log 00213 ::operator << (const se_core::String* s) { 00214 copy(s->get()); 00215 return *this; 00216 } 00217 00218 00219 00220 Log& Log 00221 ::mem(int n) { 00222 sprintf(tmp_, "%x", n); 00223 copy(tmp_); 00224 return *this; 00225 } 00226 00227 short debug_state = 0; 00228 int usedMem = 0; 00229 int maxUsedMem = 0; 00230 int objects = 0; 00231 int arrays = 0; 00232 int allocCount = 0; 00233 struct Alloc { 00234 const char* file; 00235 int line; 00236 short count; 00237 short prevCount; 00238 int totalSize; 00239 } allocs[200]; 00240 00241 struct Mem2Alloc { 00242 void* p; 00243 Alloc* a; 00244 unsigned short size; 00245 } *m2a = 0; 00246 int m2aCount = 0; 00247 int maxM2aCount = 0; 00248 00249 00250 00251 } 00252 00253 #ifdef new 00254 #undef new 00255 00256 #ifdef delete 00257 #undef delete 00258 #endif 00259 00260 namespace se_err { 00261 00262 Alloc& findAlloc(const char* file, int line) { 00263 for(int i = 0; i < allocCount; ++i) { 00264 if(allocs[i].file == file && allocs[i].line == line) { 00265 return allocs[i]; 00266 } 00267 } 00268 allocs[allocCount].file = file; 00269 allocs[allocCount].line = line; 00270 allocs[allocCount].count = 0; 00271 allocs[allocCount].prevCount = 0; 00272 allocs[allocCount].totalSize = 0; 00273 return allocs[allocCount++]; 00274 } 00275 00276 void dumpAlloc() { 00277 dump(";;--------------------------\n"); 00278 for(int i = 0; i < allocCount; ++i) { 00279 if(allocs[i].count == 0) continue; 00280 Alloc& a = allocs[i]; 00281 00282 00283 if(a.count != a.prevCount) 00284 dump((sprintf(log_msg(), ";; %5d, %d - %s(%d)\n", a.totalSize, a.count, a.file, a.line), log_msg())); 00285 a.prevCount = a.count; 00286 } 00287 int m2aSize = 0; 00288 for(int j = 0; j < m2aCount; ++j) { 00289 m2aSize += m2a[j].size; 00290 } 00291 00292 dump(";;+++++++++++++++++++++++++++++++\n"); 00293 dump((sprintf(log_msg(), ";;Objects: %d, Arrays: %d\n", se_err::objects, se_err::arrays), log_msg())); 00294 dump((sprintf(log_msg(), ";;Allocs: %d, MaxAllocs: %d\n", se_err::m2aCount, se_err::maxM2aCount), log_msg())); 00295 dump((sprintf(log_msg(), ";;Alloc places: %d\n", allocCount), log_msg())); 00296 dump((sprintf(log_msg(), ";;Allocated bytes (now, max): %d, %d - check: %d\n", se_err::usedMem, se_err::maxUsedMem, m2aSize), log_msg())); 00297 dump(";;+++++++++++++++++++++++++++++++\n"); 00298 } 00299 00300 void addP(const char* file, int line, void* p, unsigned short size) { 00301 static Mem2Alloc pool[ 2000 ]; 00302 if(!m2a) m2a = pool; //(Mem2Alloc*)malloc(sizeof(Mem2Alloc) * 2000); 00303 Alloc& a = findAlloc(file, line); 00304 ++a.count; 00305 a.totalSize += size; 00306 m2a[m2aCount].p = p; 00307 m2a[m2aCount].a = &a; 00308 m2a[m2aCount].size = size; 00309 if(usedMem > maxUsedMem) maxUsedMem = usedMem; 00310 usedMem += size; 00311 ++m2aCount; 00312 if(m2aCount > maxM2aCount) 00313 maxM2aCount = m2aCount; 00314 //Assert(m2aCount < 4000); 00315 } 00316 00317 int findM2A(void* p) { 00318 //Assert(m2a); 00319 if(!m2a) return -1; 00320 for(int i = 0; i < m2aCount; ++i) { 00321 if(m2a[i].p == p) { 00322 return i; 00323 } 00324 } 00325 // Bug! 00326 //Assert(false); 00327 return -1; 00328 } 00329 00330 void delP(void* p) { 00331 int index = findM2A(p); 00332 if(index < 0) return; 00333 unsigned short size = m2a[index].size; 00334 usedMem -= size; 00335 m2a[index].a->count--; 00336 m2a[index].a->totalSize -= size; 00337 --m2aCount; 00338 m2a[index].a = m2a[m2aCount].a; 00339 m2a[index].size = m2a[m2aCount].size; 00340 m2a[index].p = m2a[m2aCount].p; 00341 } 00342 } 00343 00344 using namespace se_err; 00345 00346 void * operator new (size_t size, char const * file, int line) { 00347 Alloc* p = (Alloc*)malloc (size); 00348 ++objects; 00349 addP(file, line, p, size); 00350 return (p + 0); 00351 } 00352 00353 00354 void * operator new (size_t size) { 00355 Alloc* p = (Alloc*)malloc (size); 00356 ++objects; 00357 addP(__FILE__, __LINE__, p, size); 00358 return (p + 0); 00359 } 00360 00361 00362 void operator delete (void * p, char const * file, int line) { 00363 --objects; 00364 delP(p); 00365 free (((Alloc*)p) - 0); 00366 } 00367 00368 00369 void operator delete (void * p) { 00370 --objects; 00371 delP(p); 00372 free (((Alloc*)p) - 0); 00373 } 00374 00375 00376 void * operator new[] (size_t size, char const * file, int line) { 00377 Alloc* p = (Alloc*)malloc (size); 00378 ++arrays; 00379 addP(file, line, p, size); 00380 return p + 0; 00381 } 00382 00383 00384 void * operator new[] (size_t size) { 00385 Alloc* p = (Alloc*)malloc (size); 00386 ++arrays; 00387 addP(__FILE__, __LINE__, p, size); 00388 return p + 0; 00389 } 00390 00391 00392 void operator delete[] (void * p, char const * file, int line) { 00393 --arrays; 00394 delP(p); 00395 free (((Alloc*)p) - 0); 00396 } 00397 00398 00399 void operator delete[] (void * p) { 00400 --arrays; 00401 delP(p); 00402 free (((Alloc*)p) - 0); 00403 } 00404 00405 #endif 00406
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:12 2007 by Doxygen version 1.3.9.1.