1 // Copyright © Tavian Barnes <tavianator@tavianator.com>
2 // SPDX-License-Identifier: 0BSD
16 * static_assert() with an optional second argument.
18 #if __STDC_VERSION__ >= 202311L
19 # define bfs_static_assert static_assert
21 # define bfs_static_assert(...) bfs_static_assert_(__VA_ARGS__, #__VA_ARGS__, )
22 # define bfs_static_assert_(expr, msg, ...) _Static_assert(expr, msg)
26 * A source code location.
34 #define BFS_LOC_INIT { .file = __FILE__, .line = __LINE__, .func = __func__ }
37 * Get the current source code location.
39 #if __STDC_VERSION__ >= 202311L
40 # define bfs_location() (&(static const struct bfs_loc)BFS_LOC_INIT)
42 # define bfs_location() (&(const struct bfs_loc)BFS_LOC_INIT)
46 * Print a message to standard error and abort.
49 noreturn void bfs_abortf(const struct bfs_loc *loc, const char *format, ...);
52 * Unconditional abort with a message.
54 #define bfs_abort(...) bfs_abortf(bfs_location(), __VA_ARGS__)
57 * Abort in debug builds; no-op in release builds.
60 # define bfs_bug(...) ((void)0)
62 # define bfs_bug bfs_abort
66 * Unconditional assert.
68 #define bfs_verify(...) \
69 bfs_verify_(#__VA_ARGS__, __VA_ARGS__, "", "")
71 #define bfs_verify_(str, cond, format, ...) \
72 ((cond) ? (void)0 : bfs_abort( \
74 ? "%.0s" format "%s%s" \
75 : "Assertion failed: `%s`%s", \
79 * Assert in debug builds; no-op in release builds.
82 # define bfs_assert(...) ((void)0)
84 # define bfs_assert bfs_verify
90 * Like perror(), but decorated like bfs_error().
92 void bfs_perror(const struct bfs_ctx *ctx, const char *str);
95 * Shorthand for printing error messages.
98 void bfs_error(const struct bfs_ctx *ctx, const char *format, ...);
101 * Shorthand for printing warning messages.
103 * @return Whether a warning was printed.
106 bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...);
109 * Shorthand for printing debug messages.
111 * @return Whether a debug message was printed.
114 bool bfs_debug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *format, ...);
117 * bfs_error() variant that takes a va_list.
120 void bfs_verror(const struct bfs_ctx *ctx, const char *format, va_list args);
123 * bfs_warning() variant that takes a va_list.
126 bool bfs_vwarning(const struct bfs_ctx *ctx, const char *format, va_list args);
129 * bfs_debug() variant that takes a va_list.
132 bool bfs_vdebug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *format, va_list args);
135 * Print the error message prefix.
137 void bfs_error_prefix(const struct bfs_ctx *ctx);
140 * Print the warning message prefix.
142 bool bfs_warning_prefix(const struct bfs_ctx *ctx);
145 * Print the debug message prefix.
147 bool bfs_debug_prefix(const struct bfs_ctx *ctx, enum debug_flags flag);
150 * Highlight parts of the command line in an error message.
152 void bfs_argv_error(const struct bfs_ctx *ctx, const bool args[]);
155 * Highlight parts of an expression in an error message.
157 void bfs_expr_error(const struct bfs_ctx *ctx, const struct bfs_expr *expr);
160 * Highlight parts of the command line in a warning message.
162 bool bfs_argv_warning(const struct bfs_ctx *ctx, const bool args[]);
165 * Highlight parts of an expression in a warning message.
167 bool bfs_expr_warning(const struct bfs_ctx *ctx, const struct bfs_expr *expr);