summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-06-22 15:06:51 -0400
committerTavian Barnes <tavianator@tavianator.com>2023-06-22 15:31:12 -0400
commit273b64322afa46c560dd74ea32f6c8ad26d93210 (patch)
treecc5e857990d0249e2f5b18c595a0bb39d5344f03
parenta1490d98a1aebb3bfbd3873613977d0341ec7f98 (diff)
downloadbfs-273b64322afa46c560dd74ea32f6c8ad26d93210.tar.xz
diag: New bfs_loc type for source locations
-rw-r--r--src/diag.c18
-rw-r--r--src/diag.h44
2 files changed, 48 insertions, 14 deletions
diff --git a/src/diag.c b/src/diag.c
index 9e6b7ae..99b487a 100644
--- a/src/diag.c
+++ b/src/diag.c
@@ -5,6 +5,7 @@
#include "bfstd.h"
#include "ctx.h"
#include "color.h"
+#include "config.h"
#include "dstring.h"
#include "expr.h"
#include <errno.h>
@@ -12,11 +13,26 @@
#include <stdlib.h>
#include <string.h>
-noreturn void bfs_abortf(const char *format, ...) {
+noreturn void bfs_abortf(const struct bfs_loc *loc, const char *format, ...) {
+ const char *cmd = NULL;
+#if __GLIBC__
+ cmd = program_invocation_short_name;
+#elif BSD
+ cmd = getprogname();
+#endif
+ if (!cmd) {
+ cmd = BFS_COMMAND;
+ }
+
+ fprintf(stderr, "%s: %s@%s:%d: ", cmd, loc->func, loc->file, loc->line);
+
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
+
+ fprintf(stderr, "\n");
+
abort();
}
diff --git a/src/diag.h b/src/diag.h
index 71abb1a..8d02da6 100644
--- a/src/diag.h
+++ b/src/diag.h
@@ -23,19 +23,35 @@
#endif
/**
+ * A source code location.
+ */
+struct bfs_loc {
+ const char *file;
+ int line;
+ const char *func;
+};
+
+#define BFS_LOC_INIT { .file = __FILE__, .line = __LINE__, .func = __func__ }
+
+/**
+ * Get the current source code location.
+ */
+#if __STDC_VERSION__ >= 202311L
+# define bfs_location() (&(static const struct bfs_loc)BFS_LOC_INIT)
+#else
+# define bfs_location() (&(const struct bfs_loc)BFS_LOC_INIT)
+#endif
+
+/**
* Print a message to standard error and abort.
*/
-BFS_FORMATTER(1, 2)
-noreturn void bfs_abortf(const char *format, ...);
+BFS_FORMATTER(2, 3)
+noreturn void bfs_abortf(const struct bfs_loc *loc, const char *format, ...);
/**
* Unconditional abort with a message.
*/
-#define bfs_abort(...) \
- BFS_ABORT(__VA_ARGS__, "\n")
-
-#define BFS_ABORT(format, ...) \
- bfs_abortf((format) ? "%s: %s:%d:%s(): " format "%s" : "", BFS_COMMAND, __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define bfs_abort(...) bfs_abortf(bfs_location(), __VA_ARGS__)
/**
* Abort in debug builds; no-op in release builds.
@@ -46,18 +62,20 @@ noreturn void bfs_abortf(const char *format, ...);
# define bfs_bug bfs_abort
#endif
+
+
/**
* Unconditional assert.
*/
#define bfs_verify(...) \
- BFS_VERIFY(#__VA_ARGS__, __VA_ARGS__, "", "\n")
+ bfs_verify_(#__VA_ARGS__, __VA_ARGS__, "", "")
-#define BFS_VERIFY(str, cond, format, ...) \
- ((cond) ? (void)0 : bfs_abortf( \
+#define bfs_verify_(str, cond, format, ...) \
+ ((cond) ? (void)0 : bfs_abort( \
sizeof(format) > 1 \
- ? "%s: %s:%d: %s(): %.0s" format "%s%s" \
- : "%s: %s:%d: %s(): Assertion failed: `%s`%s", \
- BFS_COMMAND, __FILE__, __LINE__, __func__, str, __VA_ARGS__))
+ ? "%.0s" format "%s%s" \
+ : "Assertion failed: `%s`%s", \
+ str, __VA_ARGS__))
/**
* Assert in debug builds; no-op in release builds.