1
0
forked from 0ad/0ad

add debug_warn_err analogous to debug_assert_failed that reports an error code for use with CHECK_ERR et al. (as discussed in bug#70)

This was SVN commit r3037.
This commit is contained in:
janwas 2005-10-28 02:56:35 +00:00
parent bbda296289
commit 813738c295
3 changed files with 72 additions and 30 deletions

View File

@ -528,7 +528,7 @@ ErrorReaction display_error(const wchar_t* description, int flags,
// notify the user that an assertion failed; displays a stack trace with
// local variables.
ErrorReaction debug_assert_failed(const char* file, int line,
ErrorReaction debug_assert_failed(const char* file, int line,
const char* func, const char* expr)
{
// for edge cases in some functions, warnings (=asserts) are raised in
@ -546,8 +546,32 @@ ErrorReaction debug_assert_failed(const char* file, int line,
const char* base_name = slash? slash+1 : file;
uint skip = 1; void* context = 0;
wchar_t buf[200];
swprintf(buf, ARRAY_SIZE(buf), L"Assertion failed in %hs, %hs(%d): \"%hs\"", func, base_name, line, expr);
wchar_t buf[400];
swprintf(buf, ARRAY_SIZE(buf), L"Assertion failed at %hs:%d (%hs): \"%hs\"", base_name, line, func, expr);
return display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip, context, base_name, line);
}
ErrorReaction debug_warn_err(int err, const char* file, int line,
const char* func)
{
// for edge cases in some functions, warnings (=asserts) are raised in
// addition to returning an error code. self-tests deliberately trigger
// these cases and check for the latter but shouldn't cause the former.
// we therefore squelch them here.
// (note: don't do so in lib.h's CHECK_ERR or debug_assert to reduce
// compile-time dependency on self_test.h)
if(self_test_active)
return ER_CONTINUE;
// __FILE__ evaluates to the full path (albeit without drive letter)
// which is rather long. we only display the base name for clarity.
const char* slash = strrchr(file, DIR_SEP);
const char* base_name = slash? slash+1 : file;
uint skip = 1; void* context = 0;
wchar_t buf[400];
swprintf(buf, ARRAY_SIZE(buf), L"Function call failed at %hs:%d (%hs): return value was %d", base_name, line, func, err);
return display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip, context, base_name, line);
}
@ -588,8 +612,6 @@ static void tls_init()
}
// set the current thread's name; it will be returned by subsequent calls to
// debug_get_thread_name.
//

View File

@ -98,6 +98,14 @@ extern void debug_heap_enable(DebugHeapChecks what);
// debug_assert
//-----------------------------------------------------------------------------
// rationale: we call this "debug_assert" instead of "assert" for the
// following reasons:
// - consistency (everything here is prefixed with debug_) and
// - to avoid inadvertent use of the much less helpful built-in CRT assert.
// if we were to override assert, it would be difficult to tell whether
// user source has included <assert.h> (possibly indirectly via other
// headers) and thereby stomped on our definition.
// make sure the expression <expr> evaluates to non-zero. used to validate
// invariants in the program during development and thus gives a
// very helpful warning if something isn't going as expected.
@ -112,8 +120,8 @@ extern void debug_heap_enable(DebugHeapChecks what);
#define debug_assert(expr) \
STMT(\
static unsigned char suppress__ = 0x55;\
if(suppress__ == 0x55 && !(expr)) \
{ \
if(suppress__ == 0x55 && !(expr))\
{\
switch(debug_assert_failed(__FILE__, __LINE__, __func__, #expr))\
{\
case ER_SUPPRESS:\
@ -126,25 +134,13 @@ STMT(\
debug_break();\
break;\
}\
} \
}\
)
// rationale: we call our assert "debug_assert" for the following reasons:
// - consistency (everything here is prefixed with debug_) and
// - to avoid inadvertent use of the much less helpful built-in CRT assert.
// if we were to override assert, it would be difficult to tell whether
// user source has included <assert.h> (possibly indirectly via other
// headers) and thereby stomped on our definition.
// called when an assertion has failed; notifies the user via display_error.
extern enum ErrorReaction debug_assert_failed(const char* file, int line,
const char* func, const char* assert_expr);
//-----------------------------------------------------------------------------
// output
//-----------------------------------------------------------------------------
// show a dialog to make sure unexpected states in the program are noticed.
// this is less error-prone than "debug_assert(0 && "text");" and avoids
// "conditional expression is constant" warnings. we'd really like to
@ -153,6 +149,35 @@ extern enum ErrorReaction debug_assert_failed(const char* file, int line,
// we therefore just squelch the warning (unfortunately non-portable).
#define debug_warn(str) debug_assert((str) && 0)
#define DEBUG_WARN_ERR(err) \
STMT(\
static unsigned char suppress__ = 0x55;\
if(suppress__ == 0x55)\
{\
switch(debug_warn_err(err, __FILE__, __LINE__, __func__))\
{\
case ER_SUPPRESS:\
suppress__ = 0xAA;\
break;\
case ER_CONTINUE:\
break;\
default:\
case ER_BREAK:\
debug_break();\
break;\
}\
}\
)
extern enum ErrorReaction debug_warn_err(int err, const char* file, int line,
const char* func);
//-----------------------------------------------------------------------------
// logging
//-----------------------------------------------------------------------------
// write a formatted string to the debug channel, subject to filtering
// (see below). implemented via debug_puts - see performance note there.
extern void debug_printf(const char* fmt, ...);

View File

@ -124,8 +124,7 @@ STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
{\
debug_warn("FYI: CHECK_ERR reports that a function failed."\
"feel free to ignore or suppress this warning.");\
DEBUG_WARN_ERR(err__);\
return (int)(err__ & UINT_MAX);\
}\
)
@ -135,8 +134,7 @@ STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
{\
debug_printf("%s:%d: FYI: CHECK_ERR reports that a function failed."\
"feel free to ignore or suppress this warning.\n", __FILE__, __LINE__);\
DEBUG_WARN_ERR(err__);\
return (int)(err__ & UINT_MAX);\
}\
)
@ -157,8 +155,7 @@ STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
{\
debug_warn("FYI: THROW_ERR reports that a function failed."\
"feel free to ignore or suppress this warning.");\
DEBUG_WARN_ERR(err__);\
throw (int)(err__ & UINT_MAX);\
}\
)
@ -170,8 +167,7 @@ STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
{\
debug_warn("FYI: WARN_ERR_RETURN reports that a function failed."\
"feel free to ignore or suppress this warning.");\
DEBUG_WARN_ERR(err__);\
return;\
}\
)
@ -182,8 +178,7 @@ STMT(\
STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
debug_warn("FYI: WARN_ERR reports that a function failed."\
"feel free to ignore or suppress this warning.");\
DEBUG_WARN_ERR(err__);\
)