Implement ssassert(), a replacement for oops().
parent
1b52c46b81
commit
4415f5bb91
|
@ -49,6 +49,8 @@ if(MSVC)
|
|||
# they have their own __inline; this breaks `static inline` functions.
|
||||
# We do not want to care and so we fix this with a definition.
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline")
|
||||
# Same for the (C99) __func__ special variable; we use it only in C++ code.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D__func__=__FUNCTION__")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// Copyright 2013 Daniel Richard G. <skunk@iSKUNK.ORG>
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <time.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
#include "solvespace.h"
|
||||
|
||||
|
@ -25,6 +26,29 @@ void dbp(const char *str, ...)
|
|||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
void assert_failure(const char *file, unsigned line, const char *function,
|
||||
const char *condition, const char *message) {
|
||||
fprintf(stderr, "File %s, line %u, function %s:\n", file, line, function);
|
||||
fprintf(stderr, "Assertion '%s' failed: ((%s) == false).\n", message, condition);
|
||||
|
||||
static void *ptrs[1024] = {};
|
||||
size_t nptrs = backtrace(ptrs, sizeof(ptrs) / sizeof(ptrs[0]));
|
||||
char **syms = backtrace_symbols(ptrs, nptrs);
|
||||
|
||||
fprintf(stderr, "Backtrace:\n");
|
||||
if(syms != NULL) {
|
||||
for(size_t i = 0; i < nptrs; i++) {
|
||||
fprintf(stderr, "%2zu: %s\n", i, syms[i]);
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; i < nptrs; i++) {
|
||||
fprintf(stderr, "%2zu: %p\n", i, ptrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
FILE *ssfopen(const std::string &filename, const char *mode)
|
||||
{
|
||||
if(filename.length() != strlen(filename.c_str())) oops();
|
||||
|
|
|
@ -24,6 +24,17 @@ void dbp(const char *str, ...)
|
|||
OutputDebugStringA(buf);
|
||||
}
|
||||
|
||||
void assert_failure(const char *file, unsigned line, const char *function,
|
||||
const char *condition, const char *message) {
|
||||
dbp("File %s, line %u, function %s:\n", file, line, function);
|
||||
dbp("Assertion '%s' failed: ((%s) == false).\n", message, condition);
|
||||
#ifdef NDEBUG
|
||||
_exit(1);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string Narrow(const wchar_t *in)
|
||||
{
|
||||
std::string out;
|
||||
|
|
|
@ -56,14 +56,26 @@ struct FT_FaceRec_;
|
|||
#endif
|
||||
|
||||
// Debugging functions
|
||||
#ifdef NDEBUG
|
||||
#define oops() do { dbp("oops at line %d, file %s\n", __LINE__, __FILE__); \
|
||||
exit(-1); } while(0)
|
||||
#if defined(__GNUC__)
|
||||
#define ssassert(condition, message) \
|
||||
do { \
|
||||
if(__builtin_expect((condition), true) == false) { \
|
||||
SolveSpace::assert_failure(__FILE__, __LINE__, __func__, #condition, message); \
|
||||
__builtin_unreachable(); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define oops() do { dbp("oops at line %d, file %s\n", __LINE__, __FILE__); \
|
||||
abort(); } while(0)
|
||||
#define ssassert(condition, message) \
|
||||
do { \
|
||||
if((condition) == false) { \
|
||||
SolveSpace::assert_failure(__FILE__, __LINE__, __func__, #condition, message); \
|
||||
abort(); \
|
||||
} \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#define oops() ssassert(false, "oops() called")
|
||||
|
||||
#ifndef isnan
|
||||
# define isnan(x) (((x) != (x)) || (x > 1e11) || (x < -1e11))
|
||||
#endif
|
||||
|
@ -74,6 +86,12 @@ using std::min;
|
|||
using std::max;
|
||||
using std::swap;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((noreturn))
|
||||
#endif
|
||||
void assert_failure(const char *file, unsigned line, const char *function,
|
||||
const char *condition, const char *message);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__format__ (__printf__, 1, 2)))
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue