Optional detail info at assertion failure
This commit is contained in:
parent
0292d1b7c3
commit
d31a12a210
15
error.c
15
error.c
@ -1122,11 +1122,26 @@ rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args)
|
||||
|
||||
void
|
||||
rb_assert_failure(const char *file, int line, const char *name, const char *expr)
|
||||
{
|
||||
rb_assert_failure_detail(file, line, name, expr, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
rb_assert_failure_detail(const char *file, int line, const char *name, const char *expr,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
FILE *out = stderr;
|
||||
fprintf(out, "Assertion Failed: %s:%d:", file, line);
|
||||
if (name) fprintf(out, "%s:", name);
|
||||
fprintf(out, "%s\n%s\n\n", expr, rb_dynamic_description);
|
||||
|
||||
if (fmt && *fmt) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(out, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
preface_dump(out);
|
||||
rb_vm_bugreport(NULL, out);
|
||||
bug_report_end(out, -1);
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
#include "ruby/internal/assume.h"
|
||||
#include "ruby/internal/attr/cold.h"
|
||||
#include "ruby/internal/attr/format.h"
|
||||
#include "ruby/internal/attr/noreturn.h"
|
||||
#include "ruby/internal/cast.h"
|
||||
#include "ruby/internal/dllexport.h"
|
||||
@ -132,6 +133,11 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
|
||||
RBIMPL_ATTR_NORETURN()
|
||||
RBIMPL_ATTR_COLD()
|
||||
void rb_assert_failure(const char *file, int line, const char *name, const char *expr);
|
||||
|
||||
RBIMPL_ATTR_NORETURN()
|
||||
RBIMPL_ATTR_COLD()
|
||||
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 5, 6)
|
||||
void rb_assert_failure_detail(const char *file, int line, const char *name, const char *expr, const char *fmt, ...);
|
||||
RBIMPL_SYMBOL_EXPORT_END()
|
||||
|
||||
#ifdef RUBY_FUNCTION_NAME_STRING
|
||||
@ -147,8 +153,22 @@ RBIMPL_SYMBOL_EXPORT_END()
|
||||
*
|
||||
* @param mesg The message to display.
|
||||
*/
|
||||
#define RUBY_ASSERT_FAIL(mesg) \
|
||||
#if defined(HAVE___VA_OPT__)
|
||||
# if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
|
||||
/* __VA_OPT__ is to be used for the zero variadic macro arguments
|
||||
* cases. */
|
||||
RBIMPL_WARNING_IGNORED(-Wgnu-zero-variadic-macro-arguments)
|
||||
# endif
|
||||
# define RUBY_ASSERT_FAIL(mesg, ...) \
|
||||
rb_assert_failure##__VA_OPT__(_detail)( \
|
||||
__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg __VA_OPT__(,) __VA_ARGS__)
|
||||
#elif !defined(__cplusplus)
|
||||
# define RUBY_ASSERT_FAIL(mesg, ...) \
|
||||
rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
|
||||
#else
|
||||
# define RUBY_ASSERT_FAIL(mesg) \
|
||||
rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Asserts that the expression is truthy. If not aborts with the message.
|
||||
@ -156,15 +176,27 @@ RBIMPL_SYMBOL_EXPORT_END()
|
||||
* @param expr What supposedly evaluates to true.
|
||||
* @param mesg The message to display on failure.
|
||||
*/
|
||||
#define RUBY_ASSERT_MESG(expr, mesg) \
|
||||
#if defined(HAVE___VA_OPT__) || !defined(__cplusplus)
|
||||
# define RUBY_ASSERT_MESG(expr, ...) \
|
||||
(RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(__VA_ARGS__))
|
||||
#else
|
||||
# define RUBY_ASSERT_MESG(expr, mesg) \
|
||||
(RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(mesg))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A variant of #RUBY_ASSERT that does not interface with #RUBY_DEBUG.
|
||||
*
|
||||
* @copydetails #RUBY_ASSERT
|
||||
*/
|
||||
#define RUBY_ASSERT_ALWAYS(expr) RUBY_ASSERT_MESG((expr), #expr)
|
||||
#if defined(HAVE___VA_OPT__)
|
||||
# define RUBY_ASSERT_ALWAYS(expr, ...) \
|
||||
RUBY_ASSERT_MESG(expr, #expr __VA_OPT__(,) __VA_ARGS__)
|
||||
#elif !defined(__cplusplus)
|
||||
# define RUBY_ASSERT_ALWAYS(expr, ...) RUBY_ASSERT_MESG(expr, #expr)
|
||||
#else
|
||||
# define RUBY_ASSERT_ALWAYS(expr) RUBY_ASSERT_MESG((expr), #expr)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Asserts that the given expression is truthy if and only if #RUBY_DEBUG is truthy.
|
||||
@ -172,9 +204,20 @@ RBIMPL_SYMBOL_EXPORT_END()
|
||||
* @param expr What supposedly evaluates to true.
|
||||
*/
|
||||
#if RUBY_DEBUG
|
||||
# define RUBY_ASSERT(expr) RUBY_ASSERT_MESG((expr), #expr)
|
||||
# if defined(HAVE___VA_OPT__)
|
||||
# define RUBY_ASSERT(expr, ...) \
|
||||
RUBY_ASSERT_MESG((expr), #expr __VA_OPT__(,) __VA_ARGS__)
|
||||
# elif !defined(__cplusplus)
|
||||
# define RUBY_ASSERT(expr, ...) RUBY_ASSERT_MESG((expr), #expr)
|
||||
# else
|
||||
# define RUBY_ASSERT(expr) RUBY_ASSERT_MESG((expr), #expr)
|
||||
# endif
|
||||
#else
|
||||
# define RUBY_ASSERT(expr) RBIMPL_ASSERT_NOTHING
|
||||
# if defined(HAVE___VA_OPT__) || !defined(__cplusplus)
|
||||
# define RUBY_ASSERT(/* expr, */...) RBIMPL_ASSERT_NOTHING
|
||||
# else
|
||||
# define RUBY_ASSERT(expr) RBIMPL_ASSERT_NOTHING
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -187,9 +230,20 @@ RBIMPL_SYMBOL_EXPORT_END()
|
||||
/* Currently `RUBY_DEBUG == ! defined(NDEBUG)` is always true. There is no
|
||||
* difference any longer between this one and `RUBY_ASSERT`. */
|
||||
#if defined(NDEBUG)
|
||||
# define RUBY_ASSERT_NDEBUG(expr) RBIMPL_ASSERT_NOTHING
|
||||
# if defined(HAVE___VA_OPT__) || !defined(__cplusplus)
|
||||
# define RUBY_ASSERT_NDEBUG(/* expr, */...) RBIMPL_ASSERT_NOTHING
|
||||
# else
|
||||
# define RUBY_ASSERT_NDEBUG(expr) RBIMPL_ASSERT_NOTHING
|
||||
# endif
|
||||
#else
|
||||
# define RUBY_ASSERT_NDEBUG(expr) RUBY_ASSERT_MESG((expr), #expr)
|
||||
# if defined(HAVE___VA_OPT__)
|
||||
# define RUBY_ASSERT_NDEBUG(expr, ...) \
|
||||
RUBY_ASSERT_MESG((expr), #expr __VA_OPT__(,) __VA_ARGS__)
|
||||
# elif !defined(__cplusplus)
|
||||
# define RUBY_ASSERT_NDEBUG(expr, ...) RUBY_ASSERT_MESG((expr), #expr)
|
||||
# else
|
||||
# define RUBY_ASSERT_NDEBUG(expr) RUBY_ASSERT_MESG((expr), #expr)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -197,10 +251,20 @@ RBIMPL_SYMBOL_EXPORT_END()
|
||||
* @param mesg The message to display on failure.
|
||||
*/
|
||||
#if RUBY_DEBUG
|
||||
# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) RUBY_ASSERT_MESG((expr), (mesg))
|
||||
# if defined(HAVE___VA_OPT__) || !defined(__cplusplus)
|
||||
# define RUBY_ASSERT_MESG_WHEN(cond, /* expr, */...) \
|
||||
RUBY_ASSERT_MESG(__VA_ARGS__)
|
||||
# else
|
||||
# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) RUBY_ASSERT_MESG((expr), (mesg))
|
||||
# endif
|
||||
#else
|
||||
# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
|
||||
# if defined(HAVE___VA_OPT__) || !defined(__cplusplus)
|
||||
# define RUBY_ASSERT_MESG_WHEN(cond, expr, ...) \
|
||||
((cond) ? RUBY_ASSERT_MESG((expr), __VA_ARGS__) : RBIMPL_ASSERT_NOTHING)
|
||||
# else
|
||||
# define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
|
||||
((cond) ? RUBY_ASSERT_MESG((expr), (mesg)) : RBIMPL_ASSERT_NOTHING)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -210,7 +274,14 @@ RBIMPL_SYMBOL_EXPORT_END()
|
||||
* @param cond Extra condition that shall hold for assertion to take effect.
|
||||
* @param expr What supposedly evaluates to true.
|
||||
*/
|
||||
#define RUBY_ASSERT_WHEN(cond, expr) RUBY_ASSERT_MESG_WHEN((cond), (expr), #expr)
|
||||
#if defined(HAVE___VA_OPT__)
|
||||
# define RUBY_ASSERT_WHEN(cond, expr, ...) \
|
||||
RUBY_ASSERT_MESG_WHEN(cond, expr, #expr __VA_OPT__(,) __VA_ARGS__)
|
||||
#elif !defined(__cplusplus)
|
||||
# define RUBY_ASSERT_WHEN(cond, expr, ...) RUBY_ASSERT_MESG_WHEN(cond, expr, #expr)
|
||||
#else
|
||||
# define RUBY_ASSERT_WHEN(cond, expr) RUBY_ASSERT_MESG_WHEN((cond), (expr), #expr)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This is either #RUBY_ASSERT or #RBIMPL_ASSUME, depending on #RUBY_DEBUG.
|
||||
|
Loading…
x
Reference in New Issue
Block a user