<commit_before>#ifndef ERRORS_HPP_
#define ERRORS_HPP_

#include <errno.h>
#include <stdlib.h>

#ifdef __linux__
#if defined __i386 || defined __x86_64
#define BREAKPOINT __asm__ volatile ("int3")
#else   /* not x86/amd64 */
#define BREAKPOINT raise(SIGTRAP)
#endif  /* x86/amd64 */
#endif /* __linux__ */

#define CT_ASSERT(e) {enum { compile_time_assert_error = 1/(!!(e)) };}

#ifndef NDEBUG
#define DEBUG_ONLY(...) __VA_ARGS__
#define DEBUG_ONLY_CODE(expr) do { expr; } while (0)
#else
#define DEBUG_ONLY(...)
#define DEBUG_ONLY_CODE(expr) ((void)(0))
#endif

/* This macro needs to exist because gcc and icc disagree on how to number the
 * attributes to methods. ICC does different number for methods and functions
 * and it's too unwieldy to make programs use these macros so we're just going
 * to disable them in icc.
 * With this macro attribute number starts at 1. If it is a nonstatic method
 * then "1" refers to the class pointer ("this").
 * */
#ifdef __ICC
#define NON_NULL_ATTR(arg)
#else
#define NON_NULL_ATTR(arg) __attribute__((nonnull(arg)))
#endif

/* Error handling
 *
 * There are several ways to report errors in RethinkDB:
 *  fail_due_to_user_error(msg, ...)    fail and report line number/stack trace. Should only be used when the user
 *                                      is at fault (e.g. provided wrong database file name) and it is reasonable to
 *                                      fail instead of handling the problem more gracefully.
 *
 *  The following macros are used only for the cases of programmer error checking. For the time being they are also used
 *  for system error checking (especially the *_err variants).
 *
 *  crash(msg, ...)                 always fails and reports line number and such. Never returns.
 *  crash_or_trap(msg, ...)         same as above, but traps into debugger if it is present instead of terminating.
 *                                  That means that it possibly can return, and one can continue stepping through the code in the debugger.
 *                                  All off the rassert/guarantee functions use crash_or_trap.
 *  rassert(cond)                   makes sure cond is true and is a no-op in release mode
 *  rassert(cond, msg, ...)         ditto, with additional message and possibly some arguments used for formatting
 *  rassert_err(cond)               same as rassert(cond), but also print errno error description
 *  rassert_err(cond, msg, ...)     same as rassert(cond, msg, ...), but also print errno error description
 *  guarantee(cond)                 same as rassert(cond), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee(cond, msg, ...)       same as rassert(cond, msg, ...), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee_err(cond)             same as guarantee(cond), but also print errno error description
 *  guarantee_err(cond, msg, ...)   same as guarantee(cond, msg, ...), but also print errno error description
 *  guarantee_xerr(cond, err, msg, ...) same as guarantee_err(cond, msg, ...), but also allows to specify errno as err argument
 *                                  (useful for async io functions, which return negated errno)
 *
 * The names rassert* are used instead of assert* because /usr/include/assert.h undefines assert macro and redefines it with its own version
 * every single time it gets included.
 */

#ifndef NDEBUG
#define DEBUG_ONLY_VAR
#else
#define DEBUG_ONLY_VAR __attribute__((unused))
#endif

#define UNUSED __attribute__((unused))
#define MUST_USE __attribute__((warn_unused_result))

// TODO: Abort probably is not the right thing to do here.
#define fail_due_to_user_error(msg, ...) do {                           \
        report_user_error(msg, ##__VA_ARGS__);                          \
        exit(-1);                                                       \
    } while (0)

#define crash(msg, ...) do {                                        \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT; /* this used to be abort(), but it didn't cause VALGRIND to print a backtrace */ \
        abort();                                                    \
    } while (0)

#define nice_crash(msg, ...) do {            \
        fprintf(stderr, msg, ##__VA_ARGS__); \
        exit(EXIT_FAILURE);                             \
    } while (0)

#define crash_or_trap(msg, ...) do {                                \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT;                                                 \
    } while (0)

void report_fatal_error(const char*, int, const char*, ...) __attribute__((format (printf, 3, 4)));
void report_user_error(const char*, ...) __attribute__((format (printf, 1, 2)));

#define stringify(x) #x

#define format_assert_message(assert_type, cond) assert_type " failed: [" stringify(cond) "] "
#define guarantee(cond, msg...) do {    \
        if (!(cond)) {                  \
            crash_or_trap(format_assert_message("Guarantee", cond) msg); \
        }                               \
    } while (0)

#define nice_guarantee(cond, msg, ...) do { \
        if (!(cond)) {                      \
            nice_crash(msg, ##__VA_ARGS__); \
        }                                   \
    } while (0)

#define guarantee_xerr(cond, err, msg, args...) do {                            \<commit_msg>addresses last comments in pull request<commit_after>#ifndef ERRORS_HPP_
#define ERRORS_HPP_

#include <errno.h>
#include <stdlib.h>

#ifdef __linux__
#if defined __i386 || defined __x86_64
#define BREAKPOINT __asm__ volatile ("int3")
#else   /* not x86/amd64 */
#define BREAKPOINT raise(SIGTRAP)
#endif  /* x86/amd64 */
#endif /* __linux__ */

#define CT_ASSERT(e) {enum { compile_time_assert_error = 1/(!!(e)) };}

#ifndef NDEBUG
#define DEBUG_ONLY(...) __VA_ARGS__
#define DEBUG_ONLY_CODE(expr) do { expr; } while (0)
#else
#define DEBUG_ONLY(...)
#define DEBUG_ONLY_CODE(expr) ((void)(0))
#endif

/* This macro needs to exist because gcc and icc disagree on how to number the
 * attributes to methods. ICC does different number for methods and functions
 * and it's too unwieldy to make programs use these macros so we're just going
 * to disable them in icc.
 * With this macro attribute number starts at 1. If it is a nonstatic method
 * then "1" refers to the class pointer ("this").
 * */
#ifdef __ICC
#define NON_NULL_ATTR(arg)
#else
#define NON_NULL_ATTR(arg) __attribute__((nonnull(arg)))
#endif

/* Error handling
 *
 * There are several ways to report errors in RethinkDB:
 *  fail_due_to_user_error(msg, ...)    fail and report line number/stack trace. Should only be used when the user
 *                                      is at fault (e.g. provided wrong database file name) and it is reasonable to
 *                                      fail instead of handling the problem more gracefully.
 *
 *  The following macros are used only for the cases of programmer error checking. For the time being they are also used
 *  for system error checking (especially the *_err variants).
 *
 *  crash(msg, ...)                 always fails and reports line number and such. Never returns.
 *  crash_or_trap(msg, ...)         same as above, but traps into debugger if it is present instead of terminating.
 *                                  That means that it possibly can return, and one can continue stepping through the code in the debugger.
 *                                  All off the rassert/guarantee functions use crash_or_trap.
 *  rassert(cond)                   makes sure cond is true and is a no-op in release mode
 *  rassert(cond, msg, ...)         ditto, with additional message and possibly some arguments used for formatting
 *  rassert_err(cond)               same as rassert(cond), but also print errno error description
 *  rassert_err(cond, msg, ...)     same as rassert(cond, msg, ...), but also print errno error description
 *  guarantee(cond)                 same as rassert(cond), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee(cond, msg, ...)       same as rassert(cond, msg, ...), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee_err(cond)             same as guarantee(cond), but also print errno error description
 *  guarantee_err(cond, msg, ...)   same as guarantee(cond, msg, ...), but also print errno error description
 *  guarantee_xerr(cond, err, msg, ...) same as guarantee_err(cond, msg, ...), but also allows to specify errno as err argument
 *                                  (useful for async io functions, which return negated errno)
 *
 * The names rassert* are used instead of assert* because /usr/include/assert.h undefines assert macro and redefines it with its own version
 * every single time it gets included.
 */

#ifndef NDEBUG
#define DEBUG_ONLY_VAR
#else
#define DEBUG_ONLY_VAR __attribute__((unused))
#endif

#define UNUSED __attribute__((unused))
#define MUST_USE __attribute__((warn_unused_result))

// TODO: Abort probably is not the right thing to do here.
#define fail_due_to_user_error(msg, ...) do {                           \
        report_user_error(msg, ##__VA_ARGS__);                          \
        exit(-1);                                                       \
    } while (0)

#define crash(msg, ...) do {                                        \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT; /* this used to be abort(), but it didn't cause VALGRIND to print a backtrace */ \
        abort();                                                    \
    } while (0)

#define nice_crash(...) do {          \
        fprintf(stderr, __VA_ARGS__); \
        exit(EXIT_FAILURE);           \
    } while (0)

#define crash_or_trap(msg, ...) do {                                \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT;                                                 \
    } while (0)

void report_fatal_error(const char*, int, const char*, ...) __attribute__((format (printf, 3, 4)));
void report_user_error(const char*, ...) __attribute__((format (printf, 1, 2)));

#define stringify(x) #x

#define format_assert_message(assert_type, cond) assert_type " failed: [" stringify(cond) "] "
#define guarantee(cond, msg...) do {    \
        if (!(cond)) {                  \
            crash_or_trap(format_assert_message("Guarantee", cond) msg); \
        }                               \
    } while (0)

#define nice_guarantee(cond, msg, ...) do { \
        if (!(cond)) {                      \
            nice_crash(msg, ##__VA_ARGS__); \
        }                                   \
    } while (0)

#define guarantee_xerr(cond, err, msg, args...) do {                            \
{'fraction_non_alphanumeric': 0.10003664345914254, 'fraction_numerical': 0.005862953462806889, 'mean_word_length': 2.149740334679746, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 38, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '712312', 'n_tokens_mistral': 3068, 'n_tokens_neox': 2969, 'n_words': 1100}