cartobase
5.0.5
ZDebug.h
Go to the documentation of this file.
1
/* This software and supporting documentation are distributed by
2
* Institut Federatif de Recherche 49
3
* CEA/NeuroSpin, Batiment 145,
4
* 91191 Gif-sur-Yvette cedex
5
* France
6
*
7
* This software is governed by the CeCILL-B license under
8
* French law and abiding by the rules of distribution of free software.
9
* You can use, modify and/or redistribute the software under the
10
* terms of the CeCILL-B license as circulated by CEA, CNRS
11
* and INRIA at the following URL "http://www.cecill.info".
12
*
13
* As a counterpart to the access to the source code and rights to copy,
14
* modify and redistribute granted by the license, users are provided only
15
* with a limited warranty and the software's author, the holder of the
16
* economic rights, and the successive licensors have only limited
17
* liability.
18
*
19
* In this respect, the user's attention is drawn to the risks associated
20
* with loading, using, modifying and/or developing or reproducing the
21
* software by the user in light of its specific status of free software,
22
* that may mean that it is complicated to manipulate, and that also
23
* therefore means that it is reserved for developers and experienced
24
* professionals having in-depth computer knowledge. Users are therefore
25
* encouraged to load and test the software's suitability as regards their
26
* requirements in conditions enabling the security of their systems and/or
27
* data to be ensured and, more generally, to use and operate it in the
28
* same conditions as regards security.
29
*
30
* The fact that you are presently reading this means that you have had
31
* knowledge of the CeCILL-B license and that you accept its terms.
32
*/
33
34
#ifndef __ZDebug__
35
#define __ZDebug__ 1
36
#include <cstdlib>
37
#include "
zconfig.h
"
38
39
/* ====================================================================================================
40
AG 2000-08-11.
41
Another rework, this time breaking out the implementation of ZDebug_DisplayMessage into separate
42
ZDebug_XXX implementation files, and putting more capabilities in place, like detecting the presence
43
of a debugger on Windows, and dumping stack crawls to log files on MacOS and Windows.
44
45
46
AG 1998-11-10.
47
ZDebug has been radically revised to provide more control over when debugging messages are output, and
48
whether we're dropped into the debugger/exit()ed from the app.
49
50
All these macros/routines take a debug level as the first parameter and will only have an effect if the level is
51
less than or equal to the value of ZCONFIG_Debug. So an assertion with a level parameter of 0 will show up in
52
all versions of the app, a level 1 will not show up in non-debug apps.
53
54
Pseudo-prototypes (not quite real C++ because of the parenthesized printf-style stuff)
55
-----------------
56
void ZDebugStop(int debugLevel);
57
void ZDebugStopf(int debugLevel, (const char* message, ...));
58
void ZDebugLog(int debugLevel);
59
void ZDebugLogf(int debugLevel, (const char* message, ...));
60
61
bool ZAssertStop(int debugLevel, bool assertCondition);
62
bool ZAssertStopf(int debugLevel, bool assertCondition, (const char* message, ...));
63
bool ZAssertLog(int debugLevel, bool assertCondition);
64
bool ZAssertLogf(int debugLevel, bool assertCondition, (const char* message, ...));
65
66
Usage
67
-----
68
ZDebugStop takes a debug level parameter, and unconditionally stops/exits the app if ZCONFIG_Debug is >= the parameter.
69
Example:
70
ZDebugStop(2); // Will unconditionally stop/exit the app when ZCONFIG_Debug is 2, become a no-op when ZCONFIG_Debug is 0 or 1
71
72
ZDebugStopf takes a debug level, and additionally (in parentheses [coz of macro weirdness]) a printf-style
73
parameter list (called printf-params in these docs). Otherwise its behavior is the same as ZDebugStop
74
Example: (assuming an accesible int called theValue)
75
ZDebugStop(1, ("Our integer's value is %d", theValue));
76
77
ZDebugLog takes a debug level, and if the level is active will cause a statement of the form:
78
"filename: line#" to be logged. Its functionality is basically that of a TRACE macro.
79
80
ZDebugLogf takes a debug level and printf-params. It will output the parameters if the debug level is active,using an appropriate
81
mechanism for the platform (MacsBug, source debugger, output to stderr).
82
ZDebugLogf does *not* stop or exit the application -- it just logs the message and continues operation.
83
84
The ZAssert macros are similar to the ZDebug macros, with the addition of a parameter inserted between the debug level
85
and the printf-params. The second parameter should be a boolean condition expression. If the debug level is
86
active, and the condition evaluates *false*, the printf-params will be output, along with the text of the
87
failed condition, ZAssertStopf will stop/exit the app. ZAssertLogf will just output the text and resume execution.
88
89
ZAssertLog (note the lack of an 'f' on the end) does not take printf-params, it just outputs the text of the
90
failed condition (along with the line number and file, like all the other macros) and lets the app continue.
91
ZAssertStop does the same but stops/exits the application.
92
93
ZAssert and ZDebugString are provided for backward compatibility. They are equivalent to ZAssertStop and
94
ZDebugStopf respectively, each with a debug level of 0. ZUnimplemented is also provided for backward compatibility.
95
96
Note that ZAssertLog/ZAssertLogf/ZAssertStop/ZAssertStopf return a boolean (the value of the condition expression). So
97
you can write code like this:
98
if (!ZAssertLogf(2, theObject.IsValid(), ("Whoaa, our object: %08x was not valid\n", &theObject)))
99
{
100
// Some recovery code
101
}
102
103
[Note the '!' before the ZAssertLogf -- the value returned by ZAssertXXX is the value of the condition
104
expression, which will be true when the condition is satisfied, and false when not.]
105
106
IMPORTANT. The "recovery code" will only be executed if the assertion fails, *and* the debug level parameter is <=
107
the value of ZCONFIG_Debug. So if ZCONFIG_Debug were set to 1, the entire chunk of code above would drop out
108
of the application.
109
110
111
TO DO
112
-----
113
Allow an application to install a function to be called to output a debug message (so a unix daemon can output to stdlog, for example).
114
==================================================================================================== */
115
116
// Note. I'm sorry, but (I think) all this stuff needs to be visible in ZDebug.h, so that inlines can be
117
// optimized away and generated code size minimized.
118
119
enum
ZDebug_Action
{
eDebugAction_Continue
,
eDebugAction_Stop
};
120
121
// ZDebug_FormatMessage and ZDebug_DisplayMessage are defined either in ZDebug.cpp or in ZDebug_XXX.cpp. ZDebug_FormatMessage
122
// takes the printf string and invokes sprintf on a static buffer, it may also acquire a critical section to ensure thread
123
// safety. ZDebug_DisplayMessage does the actual work of dumping the text to the console, invoking the debugger, or whatever is appropriate.
124
125
// Note that we use overloading on ZDebug_FormatMessage to simplify the macros, and allow inlining to occur.
126
const
char
*
ZDebug_FormatMessage
(
const
char
* inMessage, ...);
127
inline
const
char
*
ZDebug_FormatMessage
() {
return
0; }
128
129
void
ZDebug_DisplayMessage
(
int
inLevel,
ZDebug_Action
inAction,
const
char
* inFilename,
int
inLine,
const
char
* inAssertionMessage,
const
char
* inUserMessage);
130
131
// The actual macros that get used in source code. The funkiness of these macros (should) generate minimal inline code, so that
132
// an assertion that's active at level 2 will generate *no code* at level 1 or 0. This does rely on the compiler optimizing
133
// away statements/expressions with no effect.
134
#define ZDebugLogf(a, b) ((a)<=ZCONFIG_Debug ? ZDebug_DisplayMessage(a, eDebugAction_Continue, __FILE__, __LINE__, 0, ZDebug_FormatMessage b): (void)0)
135
#define ZDebugStopf(a, b) ((a)<=ZCONFIG_Debug ? ZDebug_DisplayMessage(a, eDebugAction_Stop, __FILE__, __LINE__, 0, ZDebug_FormatMessage b): (void)0)
136
#define ZDebugLog(a) ((a)<=ZCONFIG_Debug ? ZDebug_DisplayMessage(a, eDebugAction_Continue, __FILE__, __LINE__, 0, 0): (void)0)
137
#define ZDebugStop(a) ((a)<=ZCONFIG_Debug ? ZDebug_DisplayMessage(a, eDebugAction_Stop, __FILE__, __LINE__, 0, 0): (void)0)
138
139
#define ZAssertLogf(a, b, c) ((a)<=ZCONFIG_Debug && !(b) ? ZDebug_DisplayMessage(a, eDebugAction_Continue, __FILE__, __LINE__, #b, ZDebug_FormatMessage c), false: true)
140
#define ZAssertStopf(a, b, c) ((a)<=ZCONFIG_Debug && !(b) ? ZDebug_DisplayMessage(a, eDebugAction_Stop, __FILE__, __LINE__, #b, ZDebug_FormatMessage c), false: true)
141
#define ZAssertLog(a, b) ((a)<=ZCONFIG_Debug && !(b) ? ZDebug_DisplayMessage(a, eDebugAction_Continue, __FILE__, __LINE__, #b, 0), false: true)
142
#define ZAssertStop(a, b) ((a)<=ZCONFIG_Debug && !(b) ? ZDebug_DisplayMessage(a, eDebugAction_Stop, __FILE__, __LINE__, #b, 0), false: true)
143
144
145
// ZAssertCompile can be used to enforce a constraint at compile time, (for example that
146
// a struct obeys necessary alignment rules). It either drops out completely or generates an error,
147
// depending on whether the expression evaulates true or false.
148
#define ZAssertCompile(a) extern int sCompileTimeAssertionViolated[(a) ? 1 : 0]
149
150
// I'd like to formalize ZUnimplemented a little more sometime. Perhaps it should throw an exception in production code.
151
#define ZUnimplemented() ZDebugStopf(0, ("Unimplemented routine"))
152
153
154
// There are still quite a lot of places where plain old ZAssert is used.
155
#define ZAssert(a) ZAssertStop(1, a);
156
157
// ====================================================================================================
158
// These defines could go into a private header, but I'd rather not add yet
159
// another file. Perhaps later.
160
161
#define ZDebug_Message_AssertionAndUser "Assertion failed: %s. %s, %s:%d"
162
#define ZDebug_Message_AssertionOnly "Assertion failed: %s, %s:%d"
163
#define ZDebug_Message_UserOnly "%s, %s:%d"
164
#define ZDebug_Message_None "%s:%d"
165
166
#endif // __ZDebug__
eDebugAction_Stop
Definition:
ZDebug.h:119
eDebugAction_Continue
Definition:
ZDebug.h:119
ZDebug_Action
ZDebug_Action
Definition:
ZDebug.h:119
ZDebug_FormatMessage
const char * ZDebug_FormatMessage(const char *inMessage,...)
zconfig.h
ZDebug_DisplayMessage
void ZDebug_DisplayMessage(int inLevel, ZDebug_Action inAction, const char *inFilename, int inLine, const char *inAssertionMessage, const char *inUserMessage)
cartobase
zoolib
ZDebug.h
Generated by
1.8.13