source: GTP/trunk/Lib/Vis/Preprocessing/src/Timer/merror.h @ 2539

Revision 2539, 11.9 KB checked in by mattausch, 17 years ago (diff)

fixed obj loading error

  • Property svn:executable set to *
Line 
1 /* ========================================================================
2  * (C) 2000 Vienna University of Technology
3  * ========================================================================
4  * PROJECT: Urban Viz
5  * ========================================================================*/
6/** several error checking/log facilities.
7  *
8  * for char-strings, 'String' is typedef'd for convenience
9  * This library can be used standalone, with old style iostreams
10  * (define \c OLDSTREAM for that) or new style iostreams
11  *
12  * $Header: /usr/local/cvsyare/cvsyamp/include/merror.h,v 1.3 2003/01/06 19:01:32 wimmer Exp $
13  * @author      Michael Wimmer
14  * @file                                                                   */
15 /* ========================================================================*/
16
17#ifndef NO_PRAGMA_ONCE
18#pragma once
19#endif
20
21#ifndef MERROR_H
22#define MERROR_H
23
24
25// this library can be used with new and old style iostreams
26#ifndef OLDSTREAM
27# include <iostream>
28# define ERRSTD std
29#else
30# include <iostream.h>
31# define ERRSTD
32#endif
33
34
35// ---------------------------------------------------------------------------
36//  General macros
37// ---------------------------------------------------------------------------
38
39/// always use this to delete an object
40#define DELPTR(ptr) do { if (ptr) { delete (ptr); (ptr) = NULL; } } while (0)
41/// always use this to delete an array of objects
42#define DELAPTR(ptr) do { if (ptr) { delete [] (ptr); (ptr) = NULL; } } while (0)
43
44
45// ---------------------------------------------------------------------------
46//  Log file initialization
47// ---------------------------------------------------------------------------
48
49// gets global logfile, used by OUT/ASSERT/etc macros, to allow
50// logstream to be used in global constructors
51ERRSTD::ostream &_GetLogStream();
52// enables use of curses or other things
53ERRSTD::ostream &_LogStreamDone(ERRSTD::ostream &os,
54                                                                bool overrideconsole = false);
55
56/** an application can declare a function of this type to redirect
57        console output. */
58typedef void (*LogStreamToConsoleFunc)(const char *consoleoutput);
59
60/// Set a handler to redirect console output
61void SetConsoleStreamHandler(LogStreamToConsoleFunc handler);
62
63/// enables/disables logging to logfile (for performance reasons)
64void SetLogToFile(bool yesno);
65
66
67/** initializes the logfile for \c OUT/ASSERT  etc macros - call once at
68        beginning if you desire file output
69    (for logtofile=false output goes to \c cerr initially) */
70void InitLogStream(const char *filename = "error.log", bool logtofileonly = true);     
71
72/// if true, logs to logfile, otherwise logs to console (\c cerr)
73bool SetLogStream(bool logtofileonly);
74
75
76// ---------------------------------------------------------------------------
77//  Log file definitions and macros
78// ---------------------------------------------------------------------------
79
80
81/** @name Logfile output macros
82        Any of those will write a string to the console and, if desired,
83        to the logfile.
84        They differ in the amount of tabs they prepend.
85        Note: all macros (except OUT0) PREPEND a carriage return!
86*/
87//@{
88
89
90/// stream a variable; example: \c OUT1(SV(refcount))  gives ' refcount = 5 '
91#define SV(x) " " #x "=" << (x) << " "
92
93/// stream a string; example: \c OUT1(SS(filename)) gives ' filename = "abc" '
94#define SS(x) "\"" << x << "\""
95
96// ------- logfile output macros
97
98/** stream to logfile.
99        (NOTE: don't insert \c endl here! use OUT1 for that - this is if you DON'T
100        want linebreaks!) */
101#define OUT0(__xx) _LogStreamDone(_GetLogStream() << __xx)
102/// stream to logfile (use if you want linebreaks!) - for normal use
103#define OUT1(__xx) OUT0("\n" << __xx)
104/// like \c OUT1, but with a TAB in front
105#define OUT2(__xx) OUT1("\t" << __xx)
106/// prepends 2 TABs
107#define OUT3(__xx) OUT1("\t\t" << __xx)
108/// prepends i TABs
109#define OUTI(__ii,__xx) { _GetLogStream() << "\n"; \
110                                        for (int __jj = 0; __jj < __ii; __jj ++)        \
111                                        _GetLogStream() << "\t";                                        \
112                                        _LogStreamDone(_GetLogStream() << __xx); }
113
114#define HERE " ("__FILE__", " << __LINE__ << ") ("__DATE__")"
115
116// internal macro to allow forced console output
117#define _CONOUT(__xx) _LogStreamDone(_GetLogStream() << "\n" << __xx,true)
118
119/// error message with file, line and date information
120#define EOUT(__xx) _CONOUT("ERROR: " << __xx << HERE)
121/// warning message with file, line and date information
122#define WOUT(__xx) _CONOUT("\tWARNING: " << __xx << HERE)
123
124//@}
125
126/* ---------------------------------------------------------------------------
127    Assertion macros: test the parameter result (if (!result) and take
128                approprate action if failed:
129 
130    ASM_xxx 2nd parameter specifies an error message for the logfile
131    ASS_xxx no error message
132    xxx if failed, just print error message
133        xxx_RETVAL if failed, the 3rd macro parameter is returned
134    xxx_RET return is called (for void functions)
135        xxx_ELSE if failed, output the error message, else execute following
136                statement
137    _ASM_TEMPLATE is used for creating the other macros.
138   -------------------------------------------------------------------------*/
139
140// used by ASM_*
141#define _BLOCK do
142#define _BLBEGIN _BLOCK {
143#define _BLEND } while (0)
144#define _NOP 4==4
145
146#ifndef RELEASE_BUILD
147        #define _ASM_TEMPLATE(result, errstr, stmt) \
148                _BLBEGIN if(!(result)) { EOUT(errstr); stmt; } _BLEND
149       
150        #define _ASS_TEMPLATE(result, stmt) \
151                _BLBEGIN if(!(result)) { stmt; } _BLEND
152
153        #define _CHKM_TEMPLATE(result, errstr, stmt) \
154                _BLBEGIN if(!(result)) { EOUT(errstr); stmt; } _BLEND
155
156        #define _CHKMS_TEMPLATE(result, stmt) \
157                _BLBEGIN if((result)==NULL) \
158                { DWORD errorValue = GetLastError(); EOUTMS( SV(errorValue) << \
159                  GetErrorStringMS(errorValue)); stmt; } _BLEND
160
161#else
162        #define _ASM_TEMPLATE(result, errstr, stmt) _BLBEGIN _NOP; _BLEND
163        #define _ASS_TEMPLATE(result, stmt) _BLBEGIN _NOP; _BLEND
164        #define _CHKM_TEMPLATE(result, errstr, stmt) \
165                _BLBEGIN if (!(result)) { stmt }; _BLEND
166        #define _CHKMS_TEMPLATE(result, stmt) _CHKM_TEMPLATE(result, "", stmt)
167#endif
168
169// ---------------------------------------------------------------------------
170//  ASSERT macros - code will NOT be executed in release builds
171// ---------------------------------------------------------------------------
172
173/** @name Assertion and error checking macros
174        Use for ALL error checking in your code.
175        They are useful to check a return code, print a message
176        and take appropriate action.
177        Generally, ASM_* macros are for code consistency checks,
178        whereas CHK_* macros should be used for errors that could
179        occur also in the final program (like file not found etc.).
180*/
181//@{
182
183/** logs error message, returns \c value if \c result==NULL
184        (all ASM_* map to a NOOP in Release builds - use CHKM_*
185        if the code needs to get executed!!!) */
186#define ASM_RETVAL(result, errstr, value) \
187        _ASM_TEMPLATE(result, errstr, return (value))
188
189/// \c ASM_RETVAL for void-functions
190#define ASM_RET(result, errstr) _ASM_TEMPLATE(result, errstr, return)
191
192/// like \c ASM_RETVAL, but does an \c exit(-1)
193// NOTE: this should NOT have a CHKM-version, as this would result
194//               in a bad exit behaviour!
195#define ASM_EXIT(result, errstr) _ASM_TEMPLATE(result, errstr, exit(-1))
196
197// ---------------------------------------------------------------------------
198//  CHECK macros - code WILL be executed in release builds
199// ---------------------------------------------------------------------------
200
201/// \c ASM_RETVAL for code that needs to be executed also in release-builds
202#define CHKM_RETVAL(result, errstr, value) \
203        _CHKM_TEMPLATE(result, errstr, return (value))
204///
205#define CHKM_RET(result, errstr) _CHKM_TEMPLATE(result, errstr, return)
206
207
208// ---------------------------------------------------------------------------
209//  Macros not used much
210// ---------------------------------------------------------------------------
211
212
213/// like \c ASM_RETVAL but without logging anything
214#define ASS_RETVAL(result, value) _ASS_TEMPLATE(result, return (value))
215/// like \c ASM_RET but without logging anything
216#define ASS_RET(result, errstr) _ASS_TEMPLATE(result, return)
217
218#ifndef RELEASE_BUILD
219
220/// log error msg if result==NULL, no further action
221#define ASM(result, errstr) _BLBEGIN if(!(result)) { EOUT(errstr); } _BLEND
222
223/** \c if(!result) and logs error msg. Example:
224        \code ASM_IF(res, "failed!") { do_cleanup; } else { do_good_code; }
225        \endcode */
226#define ASM_IF(result, errstr) if((!(result)) ? (EOUT(errstr),true) : false)
227
228/** only the \c else -path of \c ASM_IF. Example:
229        \code ASM_ELSE(res, "bad input") { do_good_code; } \endcode */
230#define ASM_ELSE(result, errstr) if (!(result)) { EOUT(errstr); } else
231
232/// \c ASM_IF that also evaluates \c result in release-builds
233#define CHKM_IF(result, errstr) ASM_IF(result, errstr)
234
235/// see \c CHKM_IF
236#define CHKM_ELSE(result, errstr) ASM_ELSE(result, errstr)
237
238/** special: if result is false, output the offending statement
239        (saves you the trouble of inventing error strings!) */
240#define ASSERTSELF(result) _BLBEGIN if(!(result)) { EOUT(#result); } _BLEND
241
242/** for some Win32 API calls (those where the result contains errorcode):
243        print error msg if statement fails */
244#define CHKMS_FORMAT(result) \
245        _BLBEGIN int hResult = (result); if((hResult) != NULL) \
246        { EOUT( GetAPIErrorString(hResult) + #result ); } _BLEND
247
248/// outputs any OpenGL error accumulated so far
249#define CHKGL _BLBEGIN GLenum error; \
250        if ( (error = glGetError()) != GL_NO_ERROR) \
251        EOUT("gl error " << gluErrorString(error)); _BLEND;
252
253#ifdef WIN32
254#include <malloc.h>
255/// checks the heap for consistency (useful for errors seemingly in stl!)
256#define CHKHEAP _BLBEGIN int hpres; if ( (hpres = _heapchk()) != _HEAPOK ) \
257        EOUT("Heap error: " << hpres); _BLEND;
258#else
259#define CHKHEAP
260#endif
261
262
263#ifndef DBG_LVL
264/** override this define in C++-settings to change
265        behaviour of \c DBG and \c REL */
266#define DBG_LVL 1
267#endif
268
269#else
270
271#define ASM(result, errstr) _ASM_TEMPLATE(result, errstr, _NOP)
272
273#define ASSERTSELF(result) _BLBEGIN _NOP; _BLEND
274#define CHKMS_FORMAT(result) _BLBEGIN (result);  _BLEND
275
276#define ASM_IF(result, errstr) if(false)
277#define ASM_ELSE(result, errstr) if (false) _NOP; else
278#define CHKM_IF(result, errstr) if(!(result))
279#define CHKM_ELSE(result, errstr) if(result)
280#define CHKGL
281#define CHKHEAP
282
283#ifndef DBG_LVL
284#define DBG_LVL 0
285#endif
286
287#endif
288
289#if DBG_LVL > 0
290        /** the following statement/block is only executed in debug-builds
291                (\c DBG_LVL = 1) */
292        #define DDBG if(true)
293        /** the following statement/block is only executed in release-builds
294                (\c DBG_LVL = 0) */
295        #define RREL if(false)
296#else
297        #define DDBG if(false)
298        #define RREL if(true)
299#endif
300
301//@}
302
303// ---------------------------------------------------------------------------
304//  Microsoft Win32 API errors
305// ---------------------------------------------------------------------------
306
307/** @name Win32 only
308        These macros should be used for Win32 API-calls
309*/
310//@{
311
312/// put a messagebox to screen - WIN32 only
313void Msg(const char *message, const char *title = NULL);
314
315/// gets WIN32 API error message (used by CHKMS-macros)
316extern char *GetErrorStringMS(unsigned long errorValue);
317
318#define EOUTMS(x) _CONOUT("\nERRMS: " << x << HERE)
319#define WOUTMS(x) _CONOUT("\nWARNMS: " << x << HERE)
320
321/// for Win32 API calls: prints error message if statement fails
322#define CHKMS(result) _CHKMS_TEMPLATE(result, _NOP)
323/** for Win32 API calls: prints error message and returns value
324        if statement fails */
325#define CHKMS_RETVAL(result, value) _CHKMS_TEMPLATE(result, return (value))
326/// for Win32 API calls: prints error message and returns if statement fails
327#define CHKMS_RET(result) _CHKMS_TEMPLATE(result, return)
328
329//@}
330
331// C4127: conditional expression is constant (because of merror)
332// C4514 unreferenced inline function has been removed (also in stl.h)
333#ifdef WIN32
334#pragma warning(disable: 4127 4514)
335#endif
336
337#undef ERRSTD
338
339#endif // MERROR_H
Note: See TracBrowser for help on using the repository browser.