|
#ifndef __COMMON_ASSERT_H__
|
|
#define __COMMON_ASSERT_H__
|
|
|
|
#include <stddef.h> // for size_t
|
|
#include <stdint.h> // for uint64_t
|
|
#include "simplest-defs.h" // for STRINGIFY
|
|
|
|
// Use CHECK for checking something that you really want checked.
|
|
//
|
|
// Use ASSERT for checking something that you want checked, but the
|
|
// functionality of the program won't be compromised if the predicate isn't
|
|
// checked, or even run. It should be correct to define ASSERT as "#define
|
|
// ASSERT(x) ((void)0)". This means that you should not put side effects into
|
|
// ASSERT predicates.
|
|
//
|
|
// Use ASSERT_WITH_SIDE_EFFECTS for checking something you want checked, but
|
|
// there may be side effects in the predicate, so we need need to evaluate the
|
|
// predicate even if NOASSERT is set.
|
|
//
|
|
// See wisdom.tex for more discussion.
|
|
|
|
#ifndef CHECK_ASSERT_SIDE_EFFECTS
|
|
#define CHECK_ASSERT_SIDE_EFFECTS 0
|
|
#endif
|
|
|
|
#ifdef NOASSERT
|
|
#define ASSERT(x) ((0) ? ((void)(x), (void)(0)) : (void)(0))
|
|
#define ASSERT0 ASSERT
|
|
#define ASSERTv(x, typeof_val, val) ((0) ? ((void)(x), (void)(val), (void)(0)) : (void)(0))
|
|
#define ASSERT_EQ_u(a, b) ((0) ? ((void)(a), (void)(b), (void)(0)) \
|
|
: (void)(0))
|
|
#define ASSERT_EQ_i(a, b) ((0) ? ((void)(a), (void)(b), (void)(0)) \
|
|
: (void)(0))
|
|
#define ASSERT_WITH_SIDE_EFFECTS(expr) ((void)expr)
|
|
#elif !CHECK_ASSERT_SIDE_EFFECTS // && !NOASSERT
|
|
#define ASSERT CHECK
|
|
#define ASSERT0 CHECK0
|
|
#define ASSERTv CHECKv
|
|
#define ASSERT_EQ_u CHECK_EQ_u
|
|
#define ASSERT_EQ_i CHECK_EQ_i
|
|
#define ASSERT_WITH_SIDE_EFFECTS ASSERT
|
|
#else // CHECK_ASSERT_SIDE_EFFECTS && !NOASSERT
|
|
// See https://stackoverflow.com/questions/10593492/catching-assert-with-side-effects
|
|
// for this trick for noticing that you have an ASSERT with side effects.
|
|
extern int not_needed_if_expr_has_no_side_effects;
|
|
#define ASSERT(expr) ((void)(not_needed_if_expr_has_no_side_effects || (expr)))
|
|
#define ASSERT0(expr) ASSERT((expr) == 0)
|
|
#define ASSERTv(x, typeof_val, val) ASSERT(x)
|
|
#define ASSERT_EQ_u(a, b) ASSERT((a) == (b))
|
|
#define ASSERT_EQ_i(a, b) ASSERT((a) == (b))
|
|
#define ASSERT_WITH_SIDE_EFFECTS(expr) ((void)(expr))
|
|
#endif // CHECK_ASSERT_SIDE_EFFECTS && !NOASSERT
|
|
|
|
#define CHECK(x) ((x) ? (void) (0) : assert_fail (STRINGIFY(x), __FILE__, __LINE__, __PRETTY_FUNCTION__))
|
|
#define CHECK0(x) CHECK((x) == 0)
|
|
/* Check and print variable of specified type. */
|
|
#define CHECKv(x, typeof_val, val) ((x) ? (void) (0) : assert_fail_ ## typeof_val \
|
|
(STRINGIFY(x), #val, val, __FILE__, __LINE__, __PRETTY_FUNCTION__))
|
|
#define CHECKvv(x, fmt_args...) ((x) ? (void)(0) : assert_fail_v(STRINGIFY(x), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt_args) )
|
|
#define UNREACHABLE() CHECK("UNREACHABLE" && 0)
|
|
|
|
void assert_fail(const char *assertion,
|
|
const char *file, size_t line, const char *function)
|
|
__attribute__ ((__noreturn__));
|
|
void assert_fail_int(const char *assertion, const char *str_var, int var,
|
|
const char *file, size_t line, const char *function)
|
|
__attribute__ ((__noreturn__));
|
|
void assert_fail_v(const char *assertion,
|
|
const char *file,
|
|
size_t line,
|
|
const char *function,
|
|
const char *fmt_string,
|
|
...)
|
|
__attribute__ ((__noreturn__))
|
|
__attribute__ ((format (printf, 5, 6)));
|
|
void
|
|
check_eq_u(uintmax_t a, uintmax_t b,
|
|
const char *file, size_t line, const char *function,
|
|
const char *assertion);
|
|
|
|
#define CHECK_EQ_u(a, b) ( \
|
|
check_eq_u((uintmax_t)(a), (uintmax_t)(b), \
|
|
__FILE__, __LINE__, __PRETTY_FUNCTION__, \
|
|
STRINGIFY(a) " == " STRINGIFY(b)))
|
|
|
|
|
|
void
|
|
check_eq_i(intmax_t a, intmax_t b,
|
|
const char *file, size_t line, const char *function,
|
|
const char *assertion);
|
|
|
|
#define CHECK_EQ_i(a, b) ( \
|
|
check_eq_i((intmax_t)(a), (intmax_t)(b), \
|
|
__FILE__, __LINE__, __PRETTY_FUNCTION__, \
|
|
STRINGIFY(a) " == " STRINGIFY(b)))
|
|
|
|
|
|
#endif
|