cube/src/debug.h (6636B)
/**
* @file debug.h
* @author Michael Neuper (michael@michaelneuper.com)
*
* Debug utilities: assertion macros that print the failing
* expression with operand values and abort. All macros are no-ops
* unless compiled with -DDEBUG.
*/
#ifndef DEBUG_H_
#define DEBUG_H_
#include <stdio.h>
#include <stdlib.h>
#define FORMAT_SPECIFIER(x) \
_Generic((x), \
char: "%c", \
signed char: "%hhd", \
unsigned char: "%hhu", \
short: "%hd", \
unsigned short: "%hu", \
int: "%d", \
unsigned int: "%u", \
long: "%ld", \
unsigned long: "%lu", \
long long: "%lld", \
unsigned long long: "%llu", \
float: "%f", \
double: "%f", \
long double: "%Lf", \
char *: "%s", \
const char *: "%s", \
void *: "%p", \
default: "unknown type (0x%p)")
#ifdef DEBUG
# define ASSERT(cond, fmt, ...) \
do { \
if (!(cond)) { \
fprintf(stderr, \
"\e[1m%s:%d: \e[31massertion failed:\e[m\n '%s'.", \
__FILE__, __LINE__, #cond); \
fprintf(stderr, fmt, ##__VA_ARGS__); \
abort(); \
} \
} while (0)
#else
# define ASSERT(cond, fmt, ...) ((void)0)
#endif
#define ASSERT_EQ(a, b) \
do { \
const char *fa__ = FORMAT_SPECIFIER(a); \
const char *fb__ = FORMAT_SPECIFIER(b); \
char fmt__[64]; \
snprintf(fmt__, sizeof fmt__, "%%s = %s, %%s = %s\n", fa__, fb__); \
ASSERT((a) == (b), fmt__, #a, (a), #b, (b)); \
} while (0)
#define ASSERT_NE(a, b) \
do { \
const char *fa__ = FORMAT_SPECIFIER(a); \
const char *fb__ = FORMAT_SPECIFIER(b); \
char fmt__[64]; \
snprintf(fmt__, sizeof fmt__, "%%s = %s, %%s = %s\n", fa__, fb__); \
ASSERT((a) != (b), fmt__, #a, (a), #b, (b)); \
} while (0)
#define ASSERT_LT(a, b) \
do { \
const char *fa__ = FORMAT_SPECIFIER(a); \
const char *fb__ = FORMAT_SPECIFIER(b); \
char fmt__[64]; \
snprintf(fmt__, sizeof fmt__, "%%s = %s, %%s = %s\n", fa__, fb__); \
ASSERT((a) < (b), fmt__, #a, (a), #b, (b)); \
} while (0)
#define ASSERT_LE(a, b) \
do { \
const char *fa__ = FORMAT_SPECIFIER(a); \
const char *fb__ = FORMAT_SPECIFIER(b); \
char fmt__[64]; \
snprintf(fmt__, sizeof fmt__, "%%s = %s, %%s = %s\n", fa__, fb__); \
ASSERT((a) <= (b), fmt__, #a, (a), #b, (b)); \
} while (0)
#define ASSERT_NZ(a) \
do { \
const char *fa__ = FORMAT_SPECIFIER(a); \
char fmt__[64]; \
snprintf(fmt__, sizeof fmt__, "%%s = %s\n", fa__); \
ASSERT((a) != 0, fmt__, #a, (a)); \
} while (0)
#define ASSERT_GZ(a) \
do { \
const char *fa__ = FORMAT_SPECIFIER(a); \
char fmt__[64]; \
snprintf(fmt__, sizeof fmt__, "%%s = %s\n", fa__); \
ASSERT((a) > 0, fmt__, #a, (a)); \
} while (0)
#define ASSERT_GEZ(a) \
do { \
const char *fa__ = FORMAT_SPECIFIER(a); \
char fmt__[64]; \
snprintf(fmt__, sizeof fmt__, "%%s = %s\n", fa__); \
ASSERT((a) >= 0, fmt__, #a, (a)); \
} while (0)
#define ASSERT_NOT_NULL(a) ASSERT_NE((a), NULL)
#endif // DEBUG_H_