diff options
-rw-r--r-- | src/diag.c | 4 | ||||
-rw-r--r-- | src/diag.h | 43 | ||||
-rw-r--r-- | src/sighook.c | 4 | ||||
-rw-r--r-- | src/xspawn.c | 2 | ||||
-rw-r--r-- | src/xtime.c | 4 | ||||
-rw-r--r-- | tests/bfstd.c | 4 | ||||
-rw-r--r-- | tests/ioq.c | 6 | ||||
-rw-r--r-- | tests/main.c | 5 | ||||
-rw-r--r-- | tests/sighook.c | 12 | ||||
-rw-r--r-- | tests/tests.h | 15 | ||||
-rw-r--r-- | tests/xspawn.c | 42 | ||||
-rw-r--r-- | tests/xtime.c | 8 |
12 files changed, 93 insertions, 56 deletions
@@ -38,6 +38,10 @@ noreturn void bfs_abortf(const struct bfs_loc *loc, const char *format, ...) { abort(); } +const char *bfs_errstr(void) { + return xstrerror(errno); +} + const char *debug_flag_name(enum debug_flags flag) { switch (flag) { case DEBUG_COST: @@ -55,6 +55,20 @@ void bfs_diagf(const struct bfs_loc *loc, const char *format, ...); #define bfs_diag(...) bfs_diagf(bfs_location(), __VA_ARGS__) /** + * Get the last error message. + */ +const char *bfs_errstr(void); + +/** + * Print a diagnostic message including the last error. + */ +#define bfs_ediag(...) \ + bfs_ediag_("" __VA_ARGS__, bfs_errstr()) + +#define bfs_ediag_(format, ...) \ + bfs_diag(sizeof(format) > 1 ? format ": %s" : "%s", __VA_ARGS__) + +/** * Print a message to standard error and abort. */ attr(cold, printf(2, 3)) @@ -63,15 +77,27 @@ noreturn void bfs_abortf(const struct bfs_loc *loc, const char *format, ...); /** * Unconditional abort with a message. */ -#define bfs_abort(...) bfs_abortf(bfs_location(), __VA_ARGS__) +#define bfs_abort(...) \ + bfs_abortf(bfs_location(), __VA_ARGS__) + +/** + * Abort with a message including the last error. + */ +#define bfs_eabort(...) \ + bfs_eabort_("" __VA_ARGS__, bfs_errstr()) + +#define bfs_eabort_(format, ...) \ + bfs_abort(sizeof(format) > 1 ? format ": %s" : "%s", __VA_ARGS__) /** * Abort in debug builds; no-op in release builds. */ #ifdef NDEBUG # define bfs_bug(...) ((void)0) +# define bfs_ebug(...) ((void)0) #else # define bfs_bug bfs_abort +# define bfs_ebug bfs_eabort #endif /** @@ -88,12 +114,27 @@ noreturn void bfs_abortf(const struct bfs_loc *loc, const char *format, ...); str, __VA_ARGS__)) /** + * Unconditional assert, including the last error. + */ +#define bfs_everify(...) \ + bfs_everify_(#__VA_ARGS__, __VA_ARGS__, "", bfs_errstr()) + +#define bfs_everify_(str, cond, format, ...) \ + ((cond) ? (void)0 : bfs_abort( \ + sizeof(format) > 1 \ + ? "%.0s" format "%s: %s" \ + : "Assertion failed: `%s`: %s", \ + str, __VA_ARGS__)) + +/** * Assert in debug builds; no-op in release builds. */ #ifdef NDEBUG # define bfs_assert(...) ((void)0) +# define bfs_eassert(...) ((void)0) #else # define bfs_assert bfs_verify +# define bfs_eassert bfs_everify #endif struct bfs_ctx; diff --git a/src/sighook.c b/src/sighook.c index 745ccb9..ff5b96f 100644 --- a/src/sighook.c +++ b/src/sighook.c @@ -104,7 +104,7 @@ static int arc_sem_wait(struct arc *arc) { #if _POSIX_SEMAPHORES > 0 if (arc->sem_status == 0) { while (sem_wait(&arc->sem) != 0) { - bfs_verify(errno == EINTR, "sem_wait(): %s", xstrerror(errno)); + bfs_everify(errno == EINTR, "sem_wait()"); } return 0; } @@ -146,7 +146,7 @@ static void arc_destroy(struct arc *arc) { #if _POSIX_SEMAPHORES > 0 if (arc->sem_status == 0) { - bfs_verify(sem_destroy(&arc->sem) == 0, "sem_destroy(): %s", xstrerror(errno)); + bfs_everify(sem_destroy(&arc->sem) == 0, "sem_destroy()"); } #endif } diff --git a/src/xspawn.c b/src/xspawn.c index 5a8277d..33e5a4a 100644 --- a/src/xspawn.c +++ b/src/xspawn.c @@ -611,7 +611,7 @@ static pid_t bfs_fork_spawn(struct bfs_resolver *res, const struct bfs_spawn *ct // Restore the original signal mask int ret = pthread_sigmask(SIG_SETMASK, &old_mask, NULL); - bfs_verify(ret == 0, "pthread_sigmask(): %s", xstrerror(ret)); + bfs_everify(ret == 0, "pthread_sigmask()"); if (pid < 0) { // fork() failed diff --git a/src/xtime.c b/src/xtime.c index eb11afa..2808455 100644 --- a/src/xtime.c +++ b/src/xtime.c @@ -20,7 +20,7 @@ int xmktime(struct tm *tm, time_t *timep) { struct tm tmp; if (!localtime_r(&time, &tmp)) { - bfs_bug("localtime_r(-1): %s", xstrerror(errno)); + bfs_ebug("localtime_r(-1)"); return -1; } @@ -46,7 +46,7 @@ int xtimegm(struct tm *tm, time_t *timep) { struct tm tmp; if (!gmtime_r(&time, &tmp)) { - bfs_bug("gmtime_r(-1): %s", xstrerror(errno)); + bfs_ebug("gmtime_r(-1)"); return -1; } diff --git a/tests/bfstd.c b/tests/bfstd.c index 07b68b0..f0f61ce 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -15,12 +15,12 @@ static bool check_base_dir(const char *path, const char *dir, const char *base) bool ret = true; char *xdir = xdirname(path); - bfs_verify(xdir, "xdirname(): %s", xstrerror(errno)); + bfs_everify(xdir, "xdirname()"); ret &= bfs_check(strcmp(xdir, dir) == 0, "xdirname('%s') == '%s' (!= '%s')", path, xdir, dir); free(xdir); char *xbase = xbasename(path); - bfs_verify(xbase, "xbasename(): %s", xstrerror(errno)); + bfs_everify(xbase, "xbasename()"); ret &= bfs_check(strcmp(xbase, base) == 0, "xbasename('%s') == '%s' (!= '%s')", path, xbase, base); free(xbase); diff --git a/tests/ioq.c b/tests/ioq.c index ef5ee3b..99c98a2 100644 --- a/tests/ioq.c +++ b/tests/ioq.c @@ -40,15 +40,15 @@ static void check_ioq_push_block(void) { const size_t depth = 2; struct ioq *ioq = ioq_create(depth, 1); - bfs_verify(ioq, "ioq_create(): %s", xstrerror(errno)); + bfs_everify(ioq, "ioq_create()"); // Push enough operations to fill the queue for (size_t i = 0; i < depth; ++i) { struct bfs_dir *dir = bfs_allocdir(); - bfs_verify(dir, "bfs_allocdir(): %s", xstrerror(errno)); + bfs_everify(dir, "bfs_allocdir()"); int ret = ioq_opendir(ioq, dir, AT_FDCWD, ".", 0, NULL); - bfs_verify(ret == 0, "ioq_opendir(): %s", xstrerror(errno)); + bfs_everify(ret == 0, "ioq_opendir()"); } bfs_verify(ioq_capacity(ioq) == 0); diff --git a/tests/main.c b/tests/main.c index 58def32..aef0583 100644 --- a/tests/main.c +++ b/tests/main.c @@ -9,7 +9,6 @@ #include "tests.h" #include "bfstd.h" #include "color.h" -#include <errno.h> #include <locale.h> #include <stdio.h> #include <stdlib.h> @@ -90,10 +89,6 @@ static void run_test(struct test_ctx *ctx, const char *test, test_fn *fn) { } } -const char *bfs_errstr(void) { - return xstrerror(errno); -} - int main(int argc, char *argv[]) { // Try to set a UTF-8 locale if (!setlocale(LC_ALL, "C.UTF-8")) { diff --git a/tests/sighook.c b/tests/sighook.c index e5dd47f..c94526e 100644 --- a/tests/sighook.c +++ b/tests/sighook.c @@ -20,7 +20,7 @@ static void alrm_hook(int sig, siginfo_t *info, void *arg) { /** Swap out an old hook for a new hook. */ static int swap_hooks(struct sighook **hook) { struct sighook *next = sighook(SIGALRM, alrm_hook, NULL, SH_CONTINUE); - if (!bfs_pcheck(next, "sighook(SIGALRM)")) { + if (!bfs_echeck(next, "sighook(SIGALRM)")) { return -1; } @@ -32,7 +32,7 @@ static int swap_hooks(struct sighook **hook) { /** Background thread that rapidly (un)registers signal hooks. */ static void *hook_thread(void *ptr) { struct sighook *hook = sighook(SIGALRM, alrm_hook, NULL, SH_CONTINUE); - if (!bfs_pcheck(hook, "sighook(SIGALRM)")) { + if (!bfs_echeck(hook, "sighook(SIGALRM)")) { return NULL; } @@ -51,7 +51,7 @@ bool check_sighook(void) { bool ret = true; struct sighook *hook = sighook(SIGALRM, alrm_hook, NULL, SH_CONTINUE); - ret &= bfs_pcheck(hook, "sighook(SIGALRM)"); + ret &= bfs_echeck(hook, "sighook(SIGALRM)"); if (!ret) { goto done; } @@ -64,13 +64,13 @@ bool check_sighook(void) { .tv_usec = 100, }, }; - ret &= bfs_pcheck(setitimer(ITIMER_REAL, &ival, NULL) == 0); + ret &= bfs_echeck(setitimer(ITIMER_REAL, &ival, NULL) == 0); if (!ret) { goto unhook; } pthread_t thread; - ret &= bfs_pcheck(thread_create(&thread, NULL, hook_thread, NULL) == 0); + ret &= bfs_echeck(thread_create(&thread, NULL, hook_thread, NULL) == 0); if (!ret) { goto untime; } @@ -85,7 +85,7 @@ bool check_sighook(void) { untime: ival.it_value.tv_usec = 0; - ret &= bfs_pcheck(setitimer(ITIMER_REAL, &ival, NULL) == 0); + ret &= bfs_echeck(setitimer(ITIMER_REAL, &ival, NULL) == 0); if (!ret) { goto unhook; } diff --git a/tests/tests.h b/tests/tests.h index d26a5a0..19b7f5e 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -57,20 +57,17 @@ static inline bool bfs_check(bool ret) { : "Check failed: `%s`%s", \ str, __VA_ARGS__), false)) -/** Get a string description of the last error. */ -const char *bfs_errstr(void); - /** * Check a condition, logging the current error string on failure. */ -#define bfs_pcheck(...) \ - bfs_pcheck_(#__VA_ARGS__, __VA_ARGS__, "", "") +#define bfs_echeck(...) \ + bfs_echeck_(#__VA_ARGS__, __VA_ARGS__, "", bfs_errstr()) -#define bfs_pcheck_(str, cond, format, ...) \ +#define bfs_echeck_(str, cond, format, ...) \ ((cond) ? true : (bfs_diag( \ sizeof(format) > 1 \ - ? "%.0s" format "%s%s: %s" \ - : "Check failed: `%s`%s: %s", \ - str, __VA_ARGS__, bfs_errstr()), false)) + ? "%.0s" format "%s: %s" \ + : "Check failed: `%s`: %s", \ + str, __VA_ARGS__), false)) #endif // BFS_TESTS_H diff --git a/tests/xspawn.c b/tests/xspawn.c index 785ea48..b1d6dc1 100644 --- a/tests/xspawn.c +++ b/tests/xspawn.c @@ -54,7 +54,7 @@ static bool check_use_path(bool use_posix) { bool ret = true; struct bfs_spawn spawn; - ret &= bfs_pcheck(bfs_spawn_init(&spawn) == 0); + ret &= bfs_echeck(bfs_spawn_init(&spawn) == 0); if (!ret) { goto out; } @@ -64,18 +64,18 @@ static bool check_use_path(bool use_posix) { spawn.flags &= ~BFS_SPAWN_USE_POSIX; } - ret &= bfs_pcheck(bfs_spawn_addopen(&spawn, 10, "bin", O_RDONLY | O_DIRECTORY, 0) == 0); - ret &= bfs_pcheck(bfs_spawn_adddup2(&spawn, 10, 11) == 0); - ret &= bfs_pcheck(bfs_spawn_addclose(&spawn, 10) == 0); - ret &= bfs_pcheck(bfs_spawn_addfchdir(&spawn, 11) == 0); - ret &= bfs_pcheck(bfs_spawn_addclose(&spawn, 11) == 0); + ret &= bfs_echeck(bfs_spawn_addopen(&spawn, 10, "bin", O_RDONLY | O_DIRECTORY, 0) == 0); + ret &= bfs_echeck(bfs_spawn_adddup2(&spawn, 10, 11) == 0); + ret &= bfs_echeck(bfs_spawn_addclose(&spawn, 10) == 0); + ret &= bfs_echeck(bfs_spawn_addfchdir(&spawn, 11) == 0); + ret &= bfs_echeck(bfs_spawn_addclose(&spawn, 11) == 0); if (!ret) { goto destroy; } // Check that $PATH is resolved in the parent's environment char **envp; - ret &= bfs_pcheck(envp = envdup()); + ret &= bfs_echeck(envp = envdup()); if (!ret) { goto destroy; } @@ -84,7 +84,7 @@ static bool check_use_path(bool use_posix) { char *old_path = getenv("PATH"); dchar *new_path = NULL; if (old_path) { - ret &= bfs_pcheck(old_path = strdup(old_path)); + ret &= bfs_echeck(old_path = strdup(old_path)); if (!ret) { goto env; } @@ -97,20 +97,20 @@ static bool check_use_path(bool use_posix) { goto path; } - ret &= bfs_pcheck(setenv("PATH", new_path, true) == 0); + ret &= bfs_echeck(setenv("PATH", new_path, true) == 0); if (!ret) { goto path; } char *argv[] = {"xspawnee", old_path, NULL}; pid_t pid = bfs_spawn("xspawnee", &spawn, argv, envp); - ret &= bfs_pcheck(pid >= 0, "bfs_spawn()"); + ret &= bfs_echeck(pid >= 0, "bfs_spawn()"); if (!ret) { goto unset; } int wstatus; - ret &= bfs_pcheck(xwaitpid(pid, &wstatus, 0) == pid) + ret &= bfs_echeck(xwaitpid(pid, &wstatus, 0) == pid) && bfs_check(WIFEXITED(wstatus)); if (ret) { int wexit = WEXITSTATUS(wstatus); @@ -119,9 +119,9 @@ static bool check_use_path(bool use_posix) { unset: if (old_path) { - ret &= bfs_pcheck(setenv("PATH", old_path, true) == 0); + ret &= bfs_echeck(setenv("PATH", old_path, true) == 0); } else { - ret &= bfs_pcheck(unsetenv("PATH") == 0); + ret &= bfs_echeck(unsetenv("PATH") == 0); } path: dstrfree(new_path); @@ -132,7 +132,7 @@ env: } free(envp); destroy: - ret &= bfs_pcheck(bfs_spawn_destroy(&spawn) == 0); + ret &= bfs_echeck(bfs_spawn_destroy(&spawn) == 0); out: return ret; } @@ -142,7 +142,7 @@ static bool check_enoent(bool use_posix) { bool ret = true; struct bfs_spawn spawn; - ret &= bfs_pcheck(bfs_spawn_init(&spawn) == 0); + ret &= bfs_echeck(bfs_spawn_init(&spawn) == 0); if (!ret) { goto out; } @@ -154,9 +154,9 @@ static bool check_enoent(bool use_posix) { char *argv[] = {"eW6f5RM9Qi", NULL}; pid_t pid = bfs_spawn("eW6f5RM9Qi", &spawn, argv, NULL); - ret &= bfs_pcheck(pid < 0 && errno == ENOENT, "bfs_spawn()"); + ret &= bfs_echeck(pid < 0 && errno == ENOENT, "bfs_spawn()"); - ret &= bfs_pcheck(bfs_spawn_destroy(&spawn) == 0); + ret &= bfs_echeck(bfs_spawn_destroy(&spawn) == 0); out: return ret; } @@ -166,18 +166,18 @@ static bool check_resolve(void) { char *exe; exe = bfs_spawn_resolve("sh"); - ret &= bfs_pcheck(exe, "bfs_spawn_resolve('sh')"); + ret &= bfs_echeck(exe, "bfs_spawn_resolve('sh')"); free(exe); exe = bfs_spawn_resolve("/bin/sh"); - ret &= bfs_pcheck(exe && strcmp(exe, "/bin/sh") == 0); + ret &= bfs_echeck(exe && strcmp(exe, "/bin/sh") == 0); free(exe); exe = bfs_spawn_resolve("bin/tests/xspawnee"); - ret &= bfs_pcheck(exe && strcmp(exe, "bin/tests/xspawnee") == 0); + ret &= bfs_echeck(exe && strcmp(exe, "bin/tests/xspawnee") == 0); free(exe); - ret &= bfs_pcheck(!bfs_spawn_resolve("eW6f5RM9Qi") && errno == ENOENT); + ret &= bfs_echeck(!bfs_spawn_resolve("eW6f5RM9Qi") && errno == ENOENT); return ret; } diff --git a/tests/xtime.c b/tests/xtime.c index d9d6c5c..1907e26 100644 --- a/tests/xtime.c +++ b/tests/xtime.c @@ -29,9 +29,9 @@ static bool check_one_xgetdate(const char *str, int error, time_t expected) { int ret = xgetdate(str, &ts); if (error) { - return bfs_pcheck(ret == -1 && errno == error, "xgetdate('%s')", str); + return bfs_echeck(ret == -1 && errno == error, "xgetdate('%s')", str); } else { - return bfs_pcheck(ret == 0, "xgetdate('%s')", str) + return bfs_echeck(ret == 0, "xgetdate('%s')", str) && bfs_check(ts.tv_sec == expected && ts.tv_nsec == 0, "xgetdate('%s'): %jd.%09jd != %jd", str, (intmax_t)ts.tv_sec, (intmax_t)ts.tv_nsec, (intmax_t)expected); @@ -82,12 +82,12 @@ static bool check_xgetdate(void) { static bool check_one_xmktime(time_t expected) { struct tm tm; if (!localtime_r(&expected, &tm)) { - bfs_diag("localtime_r(%jd): %s", (intmax_t)expected, xstrerror(errno)); + bfs_ediag("localtime_r(%jd)", (intmax_t)expected); return false; } time_t actual; - return bfs_pcheck(xmktime(&tm, &actual) == 0, "xmktime(" TM_FORMAT ")", TM_PRINTF(tm)) + return bfs_echeck(xmktime(&tm, &actual) == 0, "xmktime(" TM_FORMAT ")", TM_PRINTF(tm)) && bfs_check(actual == expected, "xmktime(" TM_FORMAT "): %jd != %jd", TM_PRINTF(tm), (intmax_t)actual, (intmax_t)expected); } |