From a9c9fc392bf2c3803251e5f63c944cd221a1ca67 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 12 Jan 2024 12:01:07 -0500 Subject: tests: Merge unit test executables into one --- tests/tests.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/tests.h (limited to 'tests/tests.h') diff --git a/tests/tests.h b/tests/tests.h new file mode 100644 index 0000000..34c58b7 --- /dev/null +++ b/tests/tests.h @@ -0,0 +1,26 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +/** + * Unit tests. + */ + +#include "../src/config.h" + +/** Unit test function type. */ +typedef bool test_fn(void); + +/** Memory allocation tests. */ +bool check_alloc(void); + +/** Standard library wrapper tests. */ +bool check_bfstd(void); + +/** Bit manipulation tests. */ +bool check_bit(void); + +/** Trie tests. */ +bool check_trie(void); + +/** Time tests. */ +bool check_xtime(void); -- cgit v1.2.3 From d6cae04b54c1d58223e1719101b7c54d348e8d80 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 13 Jan 2024 11:44:09 -0500 Subject: tests.h: Add a header guard --- tests/tests.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests/tests.h') diff --git a/tests/tests.h b/tests/tests.h index 34c58b7..d2f3611 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -5,6 +5,9 @@ * Unit tests. */ +#ifndef BFS_TESTS_H +#define BFS_TESTS_H + #include "../src/config.h" /** Unit test function type. */ @@ -24,3 +27,5 @@ bool check_trie(void); /** Time tests. */ bool check_xtime(void); + +#endif // BFS_TESTS_H -- cgit v1.2.3 From f0418655db6a344afd5c26efd04a4e4d87128233 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 28 Feb 2024 12:31:11 -0500 Subject: tests/ioq: New unit test --- GNUmakefile | 1 + tests/ioq.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/main.c | 1 + tests/tests.h | 3 +++ 4 files changed, 78 insertions(+) create mode 100644 tests/ioq.c (limited to 'tests/tests.h') diff --git a/GNUmakefile b/GNUmakefile index b0314d8..852621e 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -283,6 +283,7 @@ $(BIN)/tests/units: \ $(OBJ)/tests/alloc.o \ $(OBJ)/tests/bfstd.o \ $(OBJ)/tests/bit.o \ + $(OBJ)/tests/ioq.o \ $(OBJ)/tests/main.o \ $(OBJ)/tests/trie.o \ $(OBJ)/tests/xtime.o \ diff --git a/tests/ioq.c b/tests/ioq.c new file mode 100644 index 0000000..3d35650 --- /dev/null +++ b/tests/ioq.c @@ -0,0 +1,73 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +#include "tests.h" +#include "../src/ioq.h" +#include "../src/bfstd.h" +#include "../src/diag.h" +#include "../src/dir.h" +#include +#include + +/** + * Test for blocking within ioq_slot_push(). + * + * struct ioqq only supports non-blocking reads; if a write encounters a full + * slot, it must block until someone pops from that slot: + * + * Reader Writer + * ────────────────────────── ───────────────────────── + * tail: 0 → 1 + * slots[0]: empty → full + * tail: 1 → 0 + * slots[1]: empty → full + * tail: 0 → 1 + * slots[0]: full → full* (IOQ_BLOCKED) + * ioq_slot_wait() ... + * head: 0 → 1 + * slots[0]: full* → empty + * ioq_slot_wake() + * ... + * slots[0]: empty → full + * + * To reproduce this unlikely scenario, we must fill up the ready queue, then + * call ioq_cancel() which pushes an additional sentinel IOQ_STOP operation. + */ +static void check_ioq_push_block(void) { + // Must be a power of two to fill the entire queue + const size_t depth = 2; + + struct ioq *ioq = ioq_create(depth, 1); + bfs_verify(ioq, "ioq_create(): %s", xstrerror(errno)); + + // 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)); + + int ret = ioq_opendir(ioq, dir, AT_FDCWD, ".", 0, NULL); + bfs_verify(ret == 0, "ioq_opendir(): %s", xstrerror(errno)); + } + bfs_verify(ioq_capacity(ioq) == 0); + + // Now cancel the queue, pushing an additional IOQ_STOP message + ioq_cancel(ioq); + + // Drain the queue + struct ioq_ent *ent; + while ((ent = ioq_pop(ioq, true))) { + bfs_verify(ent->op == IOQ_OPENDIR); + if (ent->result >= 0) { + bfs_closedir(ent->opendir.dir); + } + free(ent->opendir.dir); + ioq_free(ioq, ent); + } + + ioq_destroy(ioq); +} + +bool check_ioq(void) { + check_ioq_push_block(); + return true; +} diff --git a/tests/main.c b/tests/main.c index b7292b4..e69fe35 100644 --- a/tests/main.c +++ b/tests/main.c @@ -98,6 +98,7 @@ int main(int argc, char *argv[]) { run_test(&ctx, "alloc", check_alloc); run_test(&ctx, "bfstd", check_bfstd); run_test(&ctx, "bit", check_bit); + run_test(&ctx, "ioq", check_ioq); run_test(&ctx, "trie", check_trie); run_test(&ctx, "xtime", check_xtime); diff --git a/tests/tests.h b/tests/tests.h index d2f3611..d8adbb9 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -22,6 +22,9 @@ bool check_bfstd(void); /** Bit manipulation tests. */ bool check_bit(void); +/** I/O queue tests. */ +bool check_ioq(void); + /** Trie tests. */ bool check_trie(void); -- cgit v1.2.3 From 4e2f094d29ff8140f2b46a059128c780560db0f1 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 29 Feb 2024 13:23:02 -0500 Subject: tests: New bfs_check() macro We now report failures and continue, rather than aborting after the first failure. --- tests/alloc.c | 22 +++--- tests/bfstd.c | 65 +++++++++-------- tests/bit.c | 108 ++++++++++++++-------------- tests/tests.h | 20 ++++++ tests/trie.c | 46 ++++++------ tests/xtime.c | 220 ++++++++++++++++++++++++++-------------------------------- 6 files changed, 247 insertions(+), 234 deletions(-) (limited to 'tests/tests.h') diff --git a/tests/alloc.c b/tests/alloc.c index e14f131..4ce23d4 100644 --- a/tests/alloc.c +++ b/tests/alloc.c @@ -9,30 +9,32 @@ #include bool check_alloc(void) { + bool ret = true; + // Check sizeof_flex() struct flexible { alignas(64) int foo[8]; int bar[]; }; - bfs_verify(sizeof_flex(struct flexible, bar, 0) >= sizeof(struct flexible)); - bfs_verify(sizeof_flex(struct flexible, bar, 16) % alignof(struct flexible) == 0); + ret &= bfs_check(sizeof_flex(struct flexible, bar, 0) >= sizeof(struct flexible)); + ret &= bfs_check(sizeof_flex(struct flexible, bar, 16) % alignof(struct flexible) == 0); size_t too_many = SIZE_MAX / sizeof(int) + 1; - bfs_verify(sizeof_flex(struct flexible, bar, too_many) == align_floor(alignof(struct flexible), SIZE_MAX)); + ret &= bfs_check(sizeof_flex(struct flexible, bar, too_many) == align_floor(alignof(struct flexible), SIZE_MAX)); // Corner case: sizeof(type) > align_ceil(alignof(type), offsetof(type, member)) // Doesn't happen in typical ABIs - bfs_verify(flex_size(8, 16, 4, 4, 1) == 16); + ret &= bfs_check(flex_size(8, 16, 4, 4, 1) == 16); // Make sure we detect allocation size overflows #if __GNUC__ && !__clang__ # pragma GCC diagnostic ignored "-Walloc-size-larger-than=" #endif - bfs_verify(ALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); - bfs_verify(ZALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); - bfs_verify(ALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); - bfs_verify(ZALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); + ret &= bfs_check(ALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); + ret &= bfs_check(ZALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); + ret &= bfs_check(ALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); + ret &= bfs_check(ZALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); // varena tests struct varena varena; @@ -41,9 +43,9 @@ bool check_alloc(void) { for (size_t i = 0; i < 256; ++i) { bfs_verify(varena_alloc(&varena, i)); struct arena *arena = &varena.arenas[varena.narenas - 1]; - bfs_verify(arena->size >= sizeof_flex(struct flexible, bar, i)); + ret &= bfs_check(arena->size >= sizeof_flex(struct flexible, bar, i)); } varena_destroy(&varena); - return true; + return ret; } diff --git a/tests/bfstd.c b/tests/bfstd.c index d385c6b..4d0ec23 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -14,61 +14,68 @@ #include /** Check the result of xdirname()/xbasename(). */ -static void check_base_dir(const char *path, const char *dir, const char *base) { +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_verify(strcmp(xdir, dir) == 0, "xdirname('%s') == '%s' (!= '%s')", path, xdir, dir); + 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_verify(strcmp(xbase, base) == 0, "xbasename('%s') == '%s' (!= '%s')", path, xbase, base); + ret &= bfs_check(strcmp(xbase, base) == 0, "xbasename('%s') == '%s' (!= '%s')", path, xbase, base); free(xbase); + + return ret; } /** Check the result of wordesc(). */ -static void check_wordesc(const char *str, const char *exp, enum wesc_flags flags) { +static bool check_wordesc(const char *str, const char *exp, enum wesc_flags flags) { char buf[256]; char *end = buf + sizeof(buf); - char *ret = wordesc(buf, end, str, flags); - bfs_verify(ret != end); - bfs_verify(strcmp(buf, exp) == 0, "wordesc(%s) == %s (!= %s)", str, buf, exp); + char *esc = wordesc(buf, end, str, flags); + + return bfs_check(esc != end) + && bfs_check(strcmp(buf, exp) == 0, "wordesc('%s') == '%s' (!= '%s')", str, buf, exp); } bool check_bfstd(void) { + bool ret = true; + // Try to set a UTF-8 locale if (!setlocale(LC_ALL, "C.UTF-8")) { setlocale(LC_ALL, ""); } // From man 3p basename - check_base_dir("usr", ".", "usr"); - check_base_dir("usr/", ".", "usr"); - check_base_dir("", ".", "."); - check_base_dir("/", "/", "/"); + ret &= check_base_dir("usr", ".", "usr"); + ret &= check_base_dir("usr/", ".", "usr"); + ret &= check_base_dir("", ".", "."); + ret &= check_base_dir("/", "/", "/"); // check_base_dir("//", "/" or "//", "/" or "//"); - check_base_dir("///", "/", "/"); - check_base_dir("/usr/", "/", "usr"); - check_base_dir("/usr/lib", "/usr", "lib"); - check_base_dir("//usr//lib//", "//usr", "lib"); - check_base_dir("/home//dwc//test", "/home//dwc", "test"); + ret &= check_base_dir("///", "/", "/"); + ret &= check_base_dir("/usr/", "/", "usr"); + ret &= check_base_dir("/usr/lib", "/usr", "lib"); + ret &= check_base_dir("//usr//lib//", "//usr", "lib"); + ret &= check_base_dir("/home//dwc//test", "/home//dwc", "test"); - check_wordesc("", "\"\"", WESC_SHELL); - check_wordesc("word", "word", WESC_SHELL); - check_wordesc("two words", "\"two words\"", WESC_SHELL); - check_wordesc("word's", "\"word's\"", WESC_SHELL); - check_wordesc("\"word\"", "'\"word\"'", WESC_SHELL); - check_wordesc("\"word's\"", "'\"word'\\''s\"'", WESC_SHELL); - check_wordesc("\033[1mbold's\033[0m", "$'\\e[1mbold\\'s\\e[0m'", WESC_SHELL | WESC_TTY); - check_wordesc("\x7F", "$'\\x7F'", WESC_SHELL | WESC_TTY); + ret &= check_wordesc("", "\"\"", WESC_SHELL); + ret &= check_wordesc("word", "word", WESC_SHELL); + ret &= check_wordesc("two words", "\"two words\"", WESC_SHELL); + ret &= check_wordesc("word's", "\"word's\"", WESC_SHELL); + ret &= check_wordesc("\"word\"", "'\"word\"'", WESC_SHELL); + ret &= check_wordesc("\"word's\"", "'\"word'\\''s\"'", WESC_SHELL); + ret &= check_wordesc("\033[1mbold's\033[0m", "$'\\e[1mbold\\'s\\e[0m'", WESC_SHELL | WESC_TTY); + ret &= check_wordesc("\x7F", "$'\\x7F'", WESC_SHELL | WESC_TTY); const char *charmap = nl_langinfo(CODESET); if (strcmp(charmap, "UTF-8") == 0) { - check_wordesc("\xF0", "$'\\xF0'", WESC_SHELL | WESC_TTY); - check_wordesc("\xF0\x9F", "$'\\xF0\\x9F'", WESC_SHELL | WESC_TTY); - check_wordesc("\xF0\x9F\x98", "$'\\xF0\\x9F\\x98'", WESC_SHELL | WESC_TTY); - check_wordesc("\xF0\x9F\x98\x80", "\xF0\x9F\x98\x80", WESC_SHELL | WESC_TTY); + ret &= check_wordesc("\xF0", "$'\\xF0'", WESC_SHELL | WESC_TTY); + ret &= check_wordesc("\xF0\x9F", "$'\\xF0\\x9F'", WESC_SHELL | WESC_TTY); + ret &= check_wordesc("\xF0\x9F\x98", "$'\\xF0\\x9F\\x98'", WESC_SHELL | WESC_TTY); + ret &= check_wordesc("\xF0\x9F\x98\x80", "\xF0\x9F\x98\x80", WESC_SHELL | WESC_TTY); } - return true; + return ret; } diff --git a/tests/bit.c b/tests/bit.c index 1c6a4de..b944748 100644 --- a/tests/bit.c +++ b/tests/bit.c @@ -52,75 +52,77 @@ bfs_static_assert(UINTMAX_MAX == UWIDTH_MAX(UINTMAX_WIDTH)); bfs_static_assert(INTMAX_MIN == IWIDTH_MIN(INTMAX_WIDTH)); bfs_static_assert(INTMAX_MAX == IWIDTH_MAX(INTMAX_WIDTH)); -#define verify_eq(a, b) \ - bfs_verify((a) == (b), "(0x%jX) %s != %s (0x%jX)", (uintmax_t)(a), #a, #b, (uintmax_t)(b)) +#define check_eq(a, b) \ + bfs_check((a) == (b), "(0x%jX) %s != %s (0x%jX)", (uintmax_t)(a), #a, #b, (uintmax_t)(b)) bool check_bit(void) { - verify_eq(bswap((uint8_t)0x12), 0x12); - verify_eq(bswap((uint16_t)0x1234), 0x3412); - verify_eq(bswap((uint32_t)0x12345678), 0x78563412); - verify_eq(bswap((uint64_t)0x1234567812345678), 0x7856341278563412); - - verify_eq(count_ones(0x0), 0); - verify_eq(count_ones(0x1), 1); - verify_eq(count_ones(0x2), 1); - verify_eq(count_ones(0x3), 2); - verify_eq(count_ones(0x137F), 10); - - verify_eq(count_zeros(0), INT_WIDTH); - verify_eq(count_zeros(0L), LONG_WIDTH); - verify_eq(count_zeros(0LL), LLONG_WIDTH); - verify_eq(count_zeros((uint8_t)0), 8); - verify_eq(count_zeros((uint16_t)0), 16); - verify_eq(count_zeros((uint32_t)0), 32); - verify_eq(count_zeros((uint64_t)0), 64); - - verify_eq(rotate_left((uint8_t)0xA1, 4), 0x1A); - verify_eq(rotate_left((uint16_t)0x1234, 12), 0x4123); - verify_eq(rotate_left((uint32_t)0x12345678, 20), 0x67812345); - verify_eq(rotate_left((uint32_t)0x12345678, 0), 0x12345678); - - verify_eq(rotate_right((uint8_t)0xA1, 4), 0x1A); - verify_eq(rotate_right((uint16_t)0x1234, 12), 0x2341); - verify_eq(rotate_right((uint32_t)0x12345678, 20), 0x45678123); - verify_eq(rotate_right((uint32_t)0x12345678, 0), 0x12345678); + bool ret = true; + + ret &= check_eq(bswap((uint8_t)0x12), 0x12); + ret &= check_eq(bswap((uint16_t)0x1234), 0x3412); + ret &= check_eq(bswap((uint32_t)0x12345678), 0x78563412); + ret &= check_eq(bswap((uint64_t)0x1234567812345678), 0x7856341278563412); + + ret &= check_eq(count_ones(0x0), 0); + ret &= check_eq(count_ones(0x1), 1); + ret &= check_eq(count_ones(0x2), 1); + ret &= check_eq(count_ones(0x3), 2); + ret &= check_eq(count_ones(0x137F), 10); + + ret &= check_eq(count_zeros(0), INT_WIDTH); + ret &= check_eq(count_zeros(0L), LONG_WIDTH); + ret &= check_eq(count_zeros(0LL), LLONG_WIDTH); + ret &= check_eq(count_zeros((uint8_t)0), 8); + ret &= check_eq(count_zeros((uint16_t)0), 16); + ret &= check_eq(count_zeros((uint32_t)0), 32); + ret &= check_eq(count_zeros((uint64_t)0), 64); + + ret &= check_eq(rotate_left((uint8_t)0xA1, 4), 0x1A); + ret &= check_eq(rotate_left((uint16_t)0x1234, 12), 0x4123); + ret &= check_eq(rotate_left((uint32_t)0x12345678, 20), 0x67812345); + ret &= check_eq(rotate_left((uint32_t)0x12345678, 0), 0x12345678); + + ret &= check_eq(rotate_right((uint8_t)0xA1, 4), 0x1A); + ret &= check_eq(rotate_right((uint16_t)0x1234, 12), 0x2341); + ret &= check_eq(rotate_right((uint32_t)0x12345678, 20), 0x45678123); + ret &= check_eq(rotate_right((uint32_t)0x12345678, 0), 0x12345678); for (int i = 0; i < 16; ++i) { uint16_t n = (uint16_t)1 << i; for (int j = i; j < 16; ++j) { uint16_t m = (uint16_t)1 << j; uint16_t nm = n | m; - verify_eq(count_ones(nm), 1 + (n != m)); - verify_eq(count_zeros(nm), 15 - (n != m)); - verify_eq(leading_zeros(nm), 15 - j); - verify_eq(trailing_zeros(nm), i); - verify_eq(first_leading_one(nm), j + 1); - verify_eq(first_trailing_one(nm), i + 1); - verify_eq(bit_width(nm), j + 1); - verify_eq(bit_floor(nm), m); + ret &= check_eq(count_ones(nm), 1 + (n != m)); + ret &= check_eq(count_zeros(nm), 15 - (n != m)); + ret &= check_eq(leading_zeros(nm), 15 - j); + ret &= check_eq(trailing_zeros(nm), i); + ret &= check_eq(first_leading_one(nm), j + 1); + ret &= check_eq(first_trailing_one(nm), i + 1); + ret &= check_eq(bit_width(nm), j + 1); + ret &= check_eq(bit_floor(nm), m); if (n == m) { - verify_eq(bit_ceil(nm), m); - bfs_verify(has_single_bit(nm)); + ret &= check_eq(bit_ceil(nm), m); + ret &= bfs_check(has_single_bit(nm)); } else { if (j < 15) { - verify_eq(bit_ceil(nm), (m << 1)); + ret &= check_eq(bit_ceil(nm), (m << 1)); } - bfs_verify(!has_single_bit(nm)); + ret &= bfs_check(!has_single_bit(nm)); } } } - verify_eq(leading_zeros((uint16_t)0), 16); - verify_eq(trailing_zeros((uint16_t)0), 16); - verify_eq(first_leading_one(0), 0); - verify_eq(first_trailing_one(0), 0); - verify_eq(bit_width(0), 0); - verify_eq(bit_floor(0), 0); - verify_eq(bit_ceil(0), 1); + ret &= check_eq(leading_zeros((uint16_t)0), 16); + ret &= check_eq(trailing_zeros((uint16_t)0), 16); + ret &= check_eq(first_leading_one(0), 0); + ret &= check_eq(first_trailing_one(0), 0); + ret &= check_eq(bit_width(0), 0); + ret &= check_eq(bit_floor(0), 0); + ret &= check_eq(bit_ceil(0), 1); - bfs_verify(!has_single_bit(0)); - bfs_verify(!has_single_bit(UINT32_MAX)); - bfs_verify(has_single_bit((uint32_t)1 << (UINT_WIDTH - 1))); + ret &= bfs_check(!has_single_bit(0)); + ret &= bfs_check(!has_single_bit(UINT32_MAX)); + ret &= bfs_check(has_single_bit((uint32_t)1 << (UINT_WIDTH - 1))); - return true; + return ret; } diff --git a/tests/tests.h b/tests/tests.h index d8adbb9..6629dcf 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -9,6 +9,7 @@ #define BFS_TESTS_H #include "../src/config.h" +#include "../src/diag.h" /** Unit test function type. */ typedef bool test_fn(void); @@ -31,4 +32,23 @@ bool check_trie(void); /** Time tests. */ bool check_xtime(void); +/** Don't ignore the bfs_check() return value. */ +attr(nodiscard) +static inline bool bfs_check(bool ret) { + return ret; +} + +/** + * Check a condition, logging a message on failure but continuing. + */ +#define bfs_check(...) \ + bfs_check(bfs_check_(#__VA_ARGS__, __VA_ARGS__, "", "")) + +#define bfs_check_(str, cond, format, ...) \ + ((cond) ? true : (bfs_diag( \ + sizeof(format) > 1 \ + ? "%.0s" format "%s%s" \ + : "Check failed: `%s`%s", \ + str, __VA_ARGS__), false)) + #endif // BFS_TESTS_H diff --git a/tests/trie.c b/tests/trie.c index f94d7c8..fec0de2 100644 --- a/tests/trie.c +++ b/tests/trie.c @@ -40,11 +40,13 @@ const char *keys[] = { const size_t nkeys = countof(keys); bool check_trie(void) { + bool ret = true; + struct trie trie; trie_init(&trie); for (size_t i = 0; i < nkeys; ++i) { - bfs_verify(!trie_find_str(&trie, keys[i])); + ret &= bfs_check(!trie_find_str(&trie, keys[i])); const char *prefix = NULL; for (size_t j = 0; j < i; ++j) { @@ -58,37 +60,37 @@ bool check_trie(void) { struct trie_leaf *leaf = trie_find_prefix(&trie, keys[i]); if (prefix) { bfs_verify(leaf); - bfs_verify(strcmp(prefix, leaf->key) == 0); + ret &= bfs_check(strcmp(prefix, leaf->key) == 0); } else { - bfs_verify(!leaf); + ret &= bfs_check(!leaf); } leaf = trie_insert_str(&trie, keys[i]); bfs_verify(leaf); - bfs_verify(strcmp(keys[i], leaf->key) == 0); - bfs_verify(leaf->length == strlen(keys[i]) + 1); + ret &= bfs_check(strcmp(keys[i], leaf->key) == 0); + ret &= bfs_check(leaf->length == strlen(keys[i]) + 1); } { size_t i = 0; for_trie (leaf, &trie) { - bfs_verify(leaf == trie_find_str(&trie, keys[i])); - bfs_verify(!leaf->prev || leaf->prev->next == leaf); - bfs_verify(!leaf->next || leaf->next->prev == leaf); + ret &= bfs_check(leaf == trie_find_str(&trie, keys[i])); + ret &= bfs_check(!leaf->prev || leaf->prev->next == leaf); + ret &= bfs_check(!leaf->next || leaf->next->prev == leaf); ++i; } - bfs_verify(i == nkeys); + ret &= bfs_check(i == nkeys); } for (size_t i = 0; i < nkeys; ++i) { struct trie_leaf *leaf = trie_find_str(&trie, keys[i]); bfs_verify(leaf); - bfs_verify(strcmp(keys[i], leaf->key) == 0); - bfs_verify(leaf->length == strlen(keys[i]) + 1); + ret &= bfs_check(strcmp(keys[i], leaf->key) == 0); + ret &= bfs_check(leaf->length == strlen(keys[i]) + 1); trie_remove(&trie, leaf); leaf = trie_find_str(&trie, keys[i]); - bfs_verify(!leaf); + ret &= bfs_check(!leaf); const char *postfix = NULL; for (size_t j = i + 1; j < nkeys; ++j) { @@ -102,14 +104,14 @@ bool check_trie(void) { leaf = trie_find_postfix(&trie, keys[i]); if (postfix) { bfs_verify(leaf); - bfs_verify(strcmp(postfix, leaf->key) == 0); + ret &= bfs_check(strcmp(postfix, leaf->key) == 0); } else { - bfs_verify(!leaf); + ret &= bfs_check(!leaf); } } for_trie (leaf, &trie) { - bfs_verify(false); + ret &= bfs_check(false, "trie should be empty"); } // This tests the "jump" node handling on 32-bit platforms @@ -118,18 +120,18 @@ bool check_trie(void) { bfs_verify(longstr); memset(longstr, 0xAC, longsize); - bfs_verify(!trie_find_mem(&trie, longstr, longsize)); - bfs_verify(trie_insert_mem(&trie, longstr, longsize)); + ret &= bfs_check(!trie_find_mem(&trie, longstr, longsize)); + ret &= bfs_check(trie_insert_mem(&trie, longstr, longsize)); memset(longstr + longsize / 2, 0xAB, longsize / 2); - bfs_verify(!trie_find_mem(&trie, longstr, longsize)); - bfs_verify(trie_insert_mem(&trie, longstr, longsize)); + ret &= bfs_check(!trie_find_mem(&trie, longstr, longsize)); + ret &= bfs_check(trie_insert_mem(&trie, longstr, longsize)); memset(longstr, 0xAA, longsize / 2); - bfs_verify(!trie_find_mem(&trie, longstr, longsize)); - bfs_verify(trie_insert_mem(&trie, longstr, longsize)); + ret &= bfs_check(!trie_find_mem(&trie, longstr, longsize)); + ret &= bfs_check(trie_insert_mem(&trie, longstr, longsize)); free(longstr); trie_destroy(&trie); - return true; + return ret; } diff --git a/tests/xtime.c b/tests/xtime.c index 4a7d55c..f853428 100644 --- a/tests/xtime.c +++ b/tests/xtime.c @@ -12,121 +12,122 @@ #include static bool tm_equal(const struct tm *tma, const struct tm *tmb) { - if (tma->tm_year != tmb->tm_year) { - return false; - } - if (tma->tm_mon != tmb->tm_mon) { - return false; - } - if (tma->tm_mday != tmb->tm_mday) { - return false; - } - if (tma->tm_hour != tmb->tm_hour) { - return false; - } - if (tma->tm_min != tmb->tm_min) { - return false; - } - if (tma->tm_sec != tmb->tm_sec) { - return false; - } - if (tma->tm_wday != tmb->tm_wday) { - return false; - } - if (tma->tm_yday != tmb->tm_yday) { - return false; - } - if (tma->tm_isdst != tmb->tm_isdst) { - return false; - } - - return true; -} - -static void tm_print(FILE *file, const struct tm *tm) { - fprintf(file, "Y%d M%d D%d h%d m%d s%d wd%d yd%d%s\n", - tm->tm_year, tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, - tm->tm_wday, tm->tm_yday, - tm->tm_isdst ? (tm->tm_isdst < 0 ? " (DST?)" : " (DST)") : ""); + return tma->tm_year == tmb->tm_year + && tma->tm_mon == tmb->tm_mon + && tma->tm_mday == tmb->tm_mday + && tma->tm_hour == tmb->tm_hour + && tma->tm_min == tmb->tm_min + && tma->tm_sec == tmb->tm_sec + && tma->tm_wday == tmb->tm_wday + && tma->tm_yday == tmb->tm_yday + && tma->tm_isdst == tmb->tm_isdst; } /** Check one xgetdate() result. */ -static bool compare_xgetdate(const char *str, int error, time_t expected) { +static bool check_one_xgetdate(const char *str, int error, time_t expected) { struct timespec ts; int ret = xgetdate(str, &ts); if (error) { - if (ret != -1 || errno != error) { - fprintf(stderr, "xgetdate('%s'): %s\n", str, xstrerror(errno)); - return false; - } - } else if (ret != 0) { - fprintf(stderr, "xgetdate('%s'): %s\n", str, xstrerror(errno)); - return false; - } else if (ts.tv_sec != expected || ts.tv_nsec != 0) { - fprintf(stderr, "xgetdate('%s'): %jd.%09jd != %jd\n", str, (intmax_t)ts.tv_sec, (intmax_t)ts.tv_nsec, (intmax_t)expected); - return false; + return bfs_check(ret == -1 && errno == error, "xgetdate('%s'): %s", str, xstrerror(errno)); + } else { + return bfs_check(ret == 0, "xgetdate('%s'): %s", str, xstrerror(errno)) + && 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); } - - return true; } /** xgetdate() tests. */ static bool check_xgetdate(void) { - return compare_xgetdate("", EINVAL, 0) - & compare_xgetdate("????", EINVAL, 0) - & compare_xgetdate("1991", EINVAL, 0) - & compare_xgetdate("1991-??", EINVAL, 0) - & compare_xgetdate("1991-12", EINVAL, 0) - & compare_xgetdate("1991-12-", EINVAL, 0) - & compare_xgetdate("1991-12-??", EINVAL, 0) - & compare_xgetdate("1991-12-14", 0, 692668800) - & compare_xgetdate("1991-12-14-", EINVAL, 0) - & compare_xgetdate("1991-12-14T", EINVAL, 0) - & compare_xgetdate("1991-12-14T??", EINVAL, 0) - & compare_xgetdate("1991-12-14T10", 0, 692704800) - & compare_xgetdate("1991-12-14T10:??", EINVAL, 0) - & compare_xgetdate("1991-12-14T10:11", 0, 692705460) - & compare_xgetdate("1991-12-14T10:11:??", EINVAL, 0) - & compare_xgetdate("1991-12-14T10:11:12", 0, 692705472) - & compare_xgetdate("1991-12-14T10Z", 0, 692704800) - & compare_xgetdate("1991-12-14T10:11Z", 0, 692705460) - & compare_xgetdate("1991-12-14T10:11:12Z", 0, 692705472) - & compare_xgetdate("1991-12-14T10:11:12?", EINVAL, 0) - & compare_xgetdate("1991-12-14T03-07", 0, 692704800) - & compare_xgetdate("1991-12-14T06:41-03:30", 0, 692705460) - & compare_xgetdate("1991-12-14T03:11:12-07:00", 0, 692705472) - & compare_xgetdate("19911214 031112-0700", 0, 692705472); + bool ret = true; + + ret &= check_one_xgetdate("", EINVAL, 0); + ret &= check_one_xgetdate("????", EINVAL, 0); + ret &= check_one_xgetdate("1991", EINVAL, 0); + ret &= check_one_xgetdate("1991-??", EINVAL, 0); + ret &= check_one_xgetdate("1991-12", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-??", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-14", 0, 692668800); + ret &= check_one_xgetdate("1991-12-14-", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-14T", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-14T??", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-14T10", 0, 692704800); + ret &= check_one_xgetdate("1991-12-14T10:??", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-14T10:11", 0, 692705460); + ret &= check_one_xgetdate("1991-12-14T10:11:??", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-14T10:11:12", 0, 692705472); + ret &= check_one_xgetdate("1991-12-14T10Z", 0, 692704800); + ret &= check_one_xgetdate("1991-12-14T10:11Z", 0, 692705460); + ret &= check_one_xgetdate("1991-12-14T10:11:12Z", 0, 692705472); + ret &= check_one_xgetdate("1991-12-14T10:11:12?", EINVAL, 0); + ret &= check_one_xgetdate("1991-12-14T03-07", 0, 692704800); + ret &= check_one_xgetdate("1991-12-14T06:41-03:30", 0, 692705460); + ret &= check_one_xgetdate("1991-12-14T03:11:12-07:00", 0, 692705472); + ret &= check_one_xgetdate("19911214 031112-0700", 0, 692705472);; + + return ret; +} + +#define TM_FORMAT "%04d-%02d-%02d %02d:%02d:%02d (%d/7, %d/365%s)" + +#define TM_PRINTF(tm) \ + (1900 + (tm).tm_year), (tm).tm_mon, (tm).tm_mday, \ + (tm).tm_hour, (tm).tm_min, (tm).tm_sec, \ + ((tm).tm_wday + 1), ((tm).tm_yday + 1), \ + ((tm).tm_isdst ? ((tm).tm_isdst < 0 ? ", DST?" : ", DST") : "") + +/** Check one xmktime() result. */ +static bool check_one_xmktime(time_t expected) { + struct tm tm; + if (xlocaltime(&expected, &tm) != 0) { + bfs_diag("xlocaltime(%jd): %s", (intmax_t)expected, xstrerror(errno)); + return false; + } + + time_t actual; + return bfs_check(xmktime(&tm, &actual) == 0, "xmktime(" TM_FORMAT "): %s", TM_PRINTF(tm), xstrerror(errno)) + && bfs_check(actual == expected, "xmktime(" TM_FORMAT "): %jd != %jd", TM_PRINTF(tm), (intmax_t)actual, (intmax_t)expected); } /** xmktime() tests. */ static bool check_xmktime(void) { + bool ret = true; + for (time_t time = -10; time <= 10; ++time) { - struct tm tm; - if (xlocaltime(&time, &tm) != 0) { - perror("xlocaltime()"); - return false; - } - - time_t made; - if (xmktime(&tm, &made) != 0) { - perror("xmktime()"); - return false; - } - - if (time != made) { - fprintf(stderr, "Mismatch: %jd != %jd\n", (intmax_t)time, (intmax_t)made); - tm_print(stderr, &tm); - return false; - } + ret &= check_one_xmktime(time); + } + + return ret; +} + +/** Check one xtimegm() result. */ +static bool check_one_xtimegm(const struct tm *tm) { + struct tm tma = *tm, tmb = *tm; + time_t ta, tb; + ta = mktime(&tma); + if (xtimegm(&tmb, &tb) != 0) { + tb = -1; } - return true; + bool ret = true; + ret &= bfs_check(ta == tb, "%jd != %jd", (intmax_t)ta, (intmax_t)tb); + ret &= bfs_check(ta == -1 || tm_equal(&tma, &tmb)); + + if (!ret) { + bfs_diag("mktime(): " TM_FORMAT, TM_PRINTF(tma)); + bfs_diag("xtimegm(): " TM_FORMAT, TM_PRINTF(tmb)); + bfs_diag("(input): " TM_FORMAT, TM_PRINTF(*tm)); + } + + return ret; } /** xtimegm() tests. */ static bool check_xtimegm(void) { + bool ret = true; + struct tm tm = { .tm_isdst = -1, }; @@ -137,33 +138,10 @@ static bool check_xtimegm(void) { for (tm.tm_hour = -1; tm.tm_hour <= 24; tm.tm_hour += 5) for (tm.tm_min = -1; tm.tm_min <= 60; tm.tm_min += 31) for (tm.tm_sec = -60; tm.tm_sec <= 120; tm.tm_sec += 5) { - struct tm tma = tm, tmb = tm; - time_t ta, tb; - ta = mktime(&tma); - if (xtimegm(&tmb, &tb) != 0) { - tb = -1; - } - - bool fail = false; - if (ta != tb) { - printf("Mismatch: %jd != %jd\n", (intmax_t)ta, (intmax_t)tb); - fail = true; - } - if (ta != -1 && !tm_equal(&tma, &tmb)) { - printf("mktime(): "); - tm_print(stdout, &tma); - printf("xtimegm(): "); - tm_print(stdout, &tmb); - fail = true; - } - if (fail) { - printf("Input: "); - tm_print(stdout, &tm); - return false; - } + ret &= check_one_xtimegm(&tm); } - return true; + return ret; } bool check_xtime(void) { @@ -173,7 +151,9 @@ bool check_xtime(void) { } tzset(); - return check_xgetdate() - & check_xmktime() - & check_xtimegm(); + bool ret = true; + ret &= check_xgetdate(); + ret &= check_xmktime(); + ret &= check_xtimegm(); + return ret; } -- cgit v1.2.3 From 25769288f62816d733004c9e8347c35dd0e4ce2a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 27 Mar 2024 11:20:20 -0400 Subject: tests: New bfs_pcheck() macro to report xstrerror(errno) --- tests/main.c | 6 ++++++ tests/tests.h | 16 ++++++++++++++++ tests/xtime.c | 6 +++--- 3 files changed, 25 insertions(+), 3 deletions(-) (limited to 'tests/tests.h') diff --git a/tests/main.c b/tests/main.c index 8849e8c..7dec320 100644 --- a/tests/main.c +++ b/tests/main.c @@ -6,8 +6,10 @@ */ #include "tests.h" +#include "../src/bfstd.h" #include "../src/color.h" #include "../src/config.h" +#include #include #include #include @@ -88,6 +90,10 @@ 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/tests.h b/tests/tests.h index 6629dcf..b644450 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -51,4 +51,20 @@ 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_pcheck_(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)) + #endif // BFS_TESTS_H diff --git a/tests/xtime.c b/tests/xtime.c index ec499d8..f85402e 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_check(ret == -1 && errno == error, "xgetdate('%s'): %s", str, xstrerror(errno)); + return bfs_pcheck(ret == -1 && errno == error, "xgetdate('%s')", str); } else { - return bfs_check(ret == 0, "xgetdate('%s'): %s", str, xstrerror(errno)) + return bfs_pcheck(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); @@ -87,7 +87,7 @@ static bool check_one_xmktime(time_t expected) { } time_t actual; - return bfs_check(xmktime(&tm, &actual) == 0, "xmktime(" TM_FORMAT "): %s", TM_PRINTF(tm), xstrerror(errno)) + return bfs_pcheck(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); } -- cgit v1.2.3 From bca78d2597c78b0166d76d023eee1354f5abd04e Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 27 Mar 2024 11:27:01 -0400 Subject: tests/xspawn: New unit test --- GNUmakefile | 10 +++- tests/main.c | 1 + tests/tests.h | 3 ++ tests/xspawn.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xspawnee.c | 17 ++++++ 5 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 tests/xspawn.c create mode 100644 tests/xspawnee.c (limited to 'tests/tests.h') diff --git a/GNUmakefile b/GNUmakefile index 7dcd76f..080fb17 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -270,10 +270,15 @@ LIBBFS := \ $(BIN)/bfs: $(OBJ)/src/main.o $(LIBBFS) # Testing utilities -TEST_UTILS := $(BIN)/tests/mksock $(BIN)/tests/xtouch +TEST_UTILS := \ + $(BIN)/tests/mksock \ + $(BIN)/tests/xspawnee \ + $(BIN)/tests/xtouch $(BIN)/tests/mksock: $(OBJ)/tests/mksock.o $(LIBBFS) +$(BIN)/tests/xspawnee: $(OBJ)/tests/xspawnee.o + $(BIN)/tests/xtouch: $(OBJ)/tests/xtouch.o $(LIBBFS) # All test binaries @@ -286,6 +291,7 @@ $(BIN)/tests/units: \ $(OBJ)/tests/ioq.o \ $(OBJ)/tests/main.o \ $(OBJ)/tests/trie.o \ + $(OBJ)/tests/xspawn.o \ $(OBJ)/tests/xtime.o \ $(LIBBFS) @@ -294,7 +300,7 @@ tests: $(TESTS) .PHONY: tests # Run the unit tests -unit-tests: $(BIN)/tests/units +unit-tests: $(BIN)/tests/units $(BIN)/tests/xspawnee $< .PHONY: unit-tests diff --git a/tests/main.c b/tests/main.c index 7dec320..69903d4 100644 --- a/tests/main.c +++ b/tests/main.c @@ -117,6 +117,7 @@ int main(int argc, char *argv[]) { run_test(&ctx, "bit", check_bit); run_test(&ctx, "ioq", check_ioq); run_test(&ctx, "trie", check_trie); + run_test(&ctx, "xspawn", check_xspawn); run_test(&ctx, "xtime", check_xtime); done: diff --git a/tests/tests.h b/tests/tests.h index b644450..351badb 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -29,6 +29,9 @@ bool check_ioq(void); /** Trie tests. */ bool check_trie(void); +/** Process spawning tests. */ +bool check_xspawn(void); + /** Time tests. */ bool check_xtime(void); diff --git a/tests/xspawn.c b/tests/xspawn.c new file mode 100644 index 0000000..e356842 --- /dev/null +++ b/tests/xspawn.c @@ -0,0 +1,154 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +#include "tests.h" +#include "../src/alloc.h" +#include "../src/bfstd.h" +#include "../src/config.h" +#include "../src/dstring.h" +#include "../src/xspawn.h" +#include +#include +#include + +/** Duplicate the current environment. */ +static char **envdup(void) { + extern char **environ; + + char **envp = NULL; + size_t envc = 0; + + for (char **var = environ; ; ++var) { + char *copy = NULL; + if (*var) { + copy = strdup(*var); + if (!copy) { + goto fail; + } + } + + char **dest = RESERVE(char *, &envp, &envc); + if (!dest) { + free(copy); + goto fail; + } + *dest = copy; + + if (!*var) { + break; + } + } + + return envp; + +fail: + for (size_t i = 0; i < envc; ++i) { + free(envp[i]); + } + free(envp); + return NULL; +} + +/** Check that we resolve executables in $PATH correctly. */ +static bool check_path_resolution(bool use_posix) { + bool ret = true; + + struct bfs_spawn spawn; + ret &= bfs_pcheck(bfs_spawn_init(&spawn) == 0); + if (!ret) { + goto out; + } + + spawn.flags |= BFS_SPAWN_USE_PATH; + if (!use_posix) { + spawn.flags &= ~BFS_SPAWN_USE_POSIX; + } + + const char *builddir = getenv("BUILDDIR"); + dchar *bin = dstrprintf("%s/bin", builddir ? builddir : "."); + ret &= bfs_pcheck(bin, "dstrprintf()"); + if (!ret) { + goto destroy; + } + + ret &= bfs_pcheck(bfs_spawn_addopen(&spawn, 10, bin, O_RDONLY | O_DIRECTORY, 0) == 0); + ret &= bfs_pcheck(bfs_spawn_addfchdir(&spawn, 10) == 0); + ret &= bfs_pcheck(bfs_spawn_addclose(&spawn, 10) == 0); + if (!ret) { + goto bin; + } + + // Check that $PATH is resolved in the parent's environment + char **envp; + ret &= bfs_pcheck(envp = envdup()); + if (!ret) { + goto bin; + } + + // Check that $PATH is resolved after the file actions + char *old_path = getenv("PATH"); + dchar *new_path = NULL; + if (old_path) { + ret &= bfs_pcheck(old_path = strdup(old_path)); + if (!ret) { + goto env; + } + new_path = dstrprintf("tests:%s", old_path); + } else { + new_path = dstrdup("tests"); + } + ret &= bfs_check(new_path); + if (!ret) { + goto path; + } + + ret &= bfs_pcheck(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()"); + if (!ret) { + goto unset; + } + + int wstatus; + ret &= bfs_pcheck(xwaitpid(pid, &wstatus, 0) == pid) + && bfs_check(WIFEXITED(wstatus)); + if (ret) { + int wexit = WEXITSTATUS(wstatus); + ret &= bfs_check(wexit == EXIT_SUCCESS, "xspawnee: exit(%d)", wexit); + } + +unset: + if (old_path) { + ret &= bfs_pcheck(setenv("PATH", old_path, true) == 0); + } else { + ret &= bfs_pcheck(unsetenv("PATH") == 0); + } +path: + dstrfree(new_path); + free(old_path); +env: + for (char **var = envp; *var; ++var) { + free(*var); + } + free(envp); +bin: + dstrfree(bin); +destroy: + ret &= bfs_pcheck(bfs_spawn_destroy(&spawn) == 0); +out: + return ret; +} + +bool check_xspawn(void) { + bool ret = true; + + ret &= check_path_resolution(true); + ret &= check_path_resolution(false); + + return ret; +} diff --git a/tests/xspawnee.c b/tests/xspawnee.c new file mode 100644 index 0000000..b0a76ca --- /dev/null +++ b/tests/xspawnee.c @@ -0,0 +1,17 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +#include +#include + +/** Child binary for bfs_spawn() tests. */ +int main(int argc, char *argv[]) { + if (argc >= 2) { + const char *path = getenv("PATH"); + if (!path || strcmp(path, argv[1]) != 0) { + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} -- cgit v1.2.3 From 1501910dd0d09c50057c8358901663a87333bd8f Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 18 Apr 2024 14:51:42 -0400 Subject: tests: Add ../src to the include path --- config/flags.mk | 1 + tests/alloc.c | 6 +++--- tests/bfstd.c | 6 +++--- tests/bit.c | 6 +++--- tests/ioq.c | 10 +++++----- tests/main.c | 6 +++--- tests/mksock.c | 2 +- tests/tests.h | 4 ++-- tests/trie.c | 6 +++--- tests/xspawn.c | 10 +++++----- tests/xtime.c | 8 ++++---- tests/xtouch.c | 8 ++++---- 12 files changed, 37 insertions(+), 36 deletions(-) (limited to 'tests/tests.h') diff --git a/config/flags.mk b/config/flags.mk index 1043779..d02cc8b 100644 --- a/config/flags.mk +++ b/config/flags.mk @@ -28,6 +28,7 @@ export XLDLIBS=${LDLIBS} # Immutable flags export BFS_CPPFLAGS= \ + -Isrc \ -D__EXTENSIONS__ \ -D_ATFILE_SOURCE \ -D_BSD_SOURCE \ diff --git a/tests/alloc.c b/tests/alloc.c index 9f08111..54b84ba 100644 --- a/tests/alloc.c +++ b/tests/alloc.c @@ -2,9 +2,9 @@ // SPDX-License-Identifier: 0BSD #include "tests.h" -#include "../src/alloc.h" -#include "../src/config.h" -#include "../src/diag.h" +#include "alloc.h" +#include "config.h" +#include "diag.h" #include #include #include diff --git a/tests/bfstd.c b/tests/bfstd.c index dc5ceaa..5e408ca 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -2,9 +2,9 @@ // SPDX-License-Identifier: 0BSD #include "tests.h" -#include "../src/bfstd.h" -#include "../src/config.h" -#include "../src/diag.h" +#include "bfstd.h" +#include "config.h" +#include "diag.h" #include #include #include diff --git a/tests/bit.c b/tests/bit.c index 6548c30..b444e50 100644 --- a/tests/bit.c +++ b/tests/bit.c @@ -2,9 +2,9 @@ // SPDX-License-Identifier: 0BSD #include "tests.h" -#include "../src/bit.h" -#include "../src/config.h" -#include "../src/diag.h" +#include "bit.h" +#include "config.h" +#include "diag.h" #include #include #include diff --git a/tests/ioq.c b/tests/ioq.c index 1ce8f75..a69f2bf 100644 --- a/tests/ioq.c +++ b/tests/ioq.c @@ -2,11 +2,11 @@ // SPDX-License-Identifier: 0BSD #include "tests.h" -#include "../src/ioq.h" -#include "../src/bfstd.h" -#include "../src/config.h" -#include "../src/diag.h" -#include "../src/dir.h" +#include "ioq.h" +#include "bfstd.h" +#include "config.h" +#include "diag.h" +#include "dir.h" #include #include #include diff --git a/tests/main.c b/tests/main.c index 69903d4..281c417 100644 --- a/tests/main.c +++ b/tests/main.c @@ -6,9 +6,9 @@ */ #include "tests.h" -#include "../src/bfstd.h" -#include "../src/color.h" -#include "../src/config.h" +#include "bfstd.h" +#include "color.h" +#include "config.h" #include #include #include diff --git a/tests/mksock.c b/tests/mksock.c index f3b61da..5786cb6 100644 --- a/tests/mksock.c +++ b/tests/mksock.c @@ -6,7 +6,7 @@ * program does the job. */ -#include "../src/bfstd.h" +#include "bfstd.h" #include #include #include diff --git a/tests/tests.h b/tests/tests.h index 351badb..d61ffd7 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -8,8 +8,8 @@ #ifndef BFS_TESTS_H #define BFS_TESTS_H -#include "../src/config.h" -#include "../src/diag.h" +#include "config.h" +#include "diag.h" /** Unit test function type. */ typedef bool test_fn(void); diff --git a/tests/trie.c b/tests/trie.c index fec0de2..2a6eb48 100644 --- a/tests/trie.c +++ b/tests/trie.c @@ -2,9 +2,9 @@ // SPDX-License-Identifier: 0BSD #include "tests.h" -#include "../src/trie.h" -#include "../src/config.h" -#include "../src/diag.h" +#include "trie.h" +#include "config.h" +#include "diag.h" #include #include diff --git a/tests/xspawn.c b/tests/xspawn.c index c1bac36..fd8362e 100644 --- a/tests/xspawn.c +++ b/tests/xspawn.c @@ -2,11 +2,11 @@ // SPDX-License-Identifier: 0BSD #include "tests.h" -#include "../src/alloc.h" -#include "../src/bfstd.h" -#include "../src/config.h" -#include "../src/dstring.h" -#include "../src/xspawn.h" +#include "alloc.h" +#include "bfstd.h" +#include "config.h" +#include "dstring.h" +#include "xspawn.h" #include #include #include diff --git a/tests/xtime.c b/tests/xtime.c index f85402e..fd7aa0f 100644 --- a/tests/xtime.c +++ b/tests/xtime.c @@ -2,10 +2,10 @@ // SPDX-License-Identifier: 0BSD #include "tests.h" -#include "../src/xtime.h" -#include "../src/bfstd.h" -#include "../src/config.h" -#include "../src/diag.h" +#include "xtime.h" +#include "bfstd.h" +#include "config.h" +#include "diag.h" #include #include #include diff --git a/tests/xtouch.c b/tests/xtouch.c index fad272f..b1daec7 100644 --- a/tests/xtouch.c +++ b/tests/xtouch.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD -#include "../src/bfstd.h" -#include "../src/config.h" -#include "../src/sanity.h" -#include "../src/xtime.h" +#include "bfstd.h" +#include "config.h" +#include "sanity.h" +#include "xtime.h" #include #include #include -- cgit v1.2.3 From c66379749f423413913b406609dfe9311ba6e555 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 18 Apr 2024 14:53:56 -0400 Subject: Rename config.h to prelude.h --- src/alloc.c | 2 +- src/alloc.h | 2 +- src/bar.c | 2 +- src/bfstd.c | 2 +- src/bfstd.h | 2 +- src/bftw.c | 2 +- src/bit.h | 2 +- src/color.c | 2 +- src/color.h | 2 +- src/config.h | 377 --------------------------------------------------------- src/ctx.h | 2 +- src/diag.c | 2 +- src/diag.h | 2 +- src/dir.c | 2 +- src/dstring.c | 2 +- src/dstring.h | 2 +- src/eval.c | 2 +- src/eval.h | 2 +- src/exec.c | 2 +- src/expr.h | 2 +- src/fsade.c | 2 +- src/fsade.h | 2 +- src/ioq.c | 2 +- src/ioq.h | 2 +- src/main.c | 4 +- src/mtab.c | 2 +- src/mtab.h | 2 +- src/opt.c | 2 +- src/parse.c | 2 +- src/prelude.h | 377 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/printf.c | 2 +- src/pwcache.c | 2 +- src/sanity.h | 2 +- src/stat.c | 2 +- src/stat.h | 2 +- src/thread.c | 2 +- src/thread.h | 2 +- src/trie.c | 2 +- src/xregex.c | 2 +- src/xspawn.c | 2 +- src/xspawn.h | 2 +- src/xtime.c | 2 +- tests/alloc.c | 2 +- tests/bfstd.c | 2 +- tests/bit.c | 2 +- tests/ioq.c | 2 +- tests/main.c | 2 +- tests/tests.h | 2 +- tests/trie.c | 2 +- tests/xspawn.c | 2 +- tests/xtime.c | 2 +- tests/xtouch.c | 2 +- 52 files changed, 428 insertions(+), 428 deletions(-) delete mode 100644 src/config.h create mode 100644 src/prelude.h (limited to 'tests/tests.h') diff --git a/src/alloc.c b/src/alloc.c index b65d0c5..ec8608f 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "alloc.h" #include "bit.h" -#include "config.h" #include "diag.h" #include "sanity.h" #include diff --git a/src/alloc.h b/src/alloc.h index ae055bc..095134a 100644 --- a/src/alloc.h +++ b/src/alloc.h @@ -8,7 +8,7 @@ #ifndef BFS_ALLOC_H #define BFS_ALLOC_H -#include "config.h" +#include "prelude.h" #include #include #include diff --git a/src/bar.c b/src/bar.c index 8ab4112..184d9a0 100644 --- a/src/bar.c +++ b/src/bar.c @@ -1,11 +1,11 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "bar.h" #include "atomic.h" #include "bfstd.h" #include "bit.h" -#include "config.h" #include "dstring.h" #include #include diff --git a/src/bfstd.c b/src/bfstd.c index 2499f00..e1b4804 100644 --- a/src/bfstd.c +++ b/src/bfstd.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "bfstd.h" #include "bit.h" -#include "config.h" #include "diag.h" #include "sanity.h" #include "thread.h" diff --git a/src/bfstd.h b/src/bfstd.h index fc22971..42f5d5b 100644 --- a/src/bfstd.h +++ b/src/bfstd.h @@ -8,7 +8,7 @@ #ifndef BFS_BFSTD_H #define BFS_BFSTD_H -#include "config.h" +#include "prelude.h" #include "sanity.h" #include diff --git a/src/bftw.c b/src/bftw.c index 6130c44..c4d3c17 100644 --- a/src/bftw.c +++ b/src/bftw.c @@ -18,10 +18,10 @@ * various helper functions to take fewer parameters. */ +#include "prelude.h" #include "bftw.h" #include "alloc.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include "dir.h" #include "dstring.h" diff --git a/src/bit.h b/src/bit.h index 69df21e..17cfbcf 100644 --- a/src/bit.h +++ b/src/bit.h @@ -8,7 +8,7 @@ #ifndef BFS_BIT_H #define BFS_BIT_H -#include "config.h" +#include "prelude.h" #include #include diff --git a/src/color.c b/src/color.c index 8c32a68..f004bf2 100644 --- a/src/color.c +++ b/src/color.c @@ -1,11 +1,11 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "color.h" #include "alloc.h" #include "bfstd.h" #include "bftw.h" -#include "config.h" #include "diag.h" #include "dir.h" #include "dstring.h" diff --git a/src/color.h b/src/color.h index e3e7973..3278cd6 100644 --- a/src/color.h +++ b/src/color.h @@ -8,7 +8,7 @@ #ifndef BFS_COLOR_H #define BFS_COLOR_H -#include "config.h" +#include "prelude.h" #include "dstring.h" #include diff --git a/src/config.h b/src/config.h deleted file mode 100644 index 2eff1fc..0000000 --- a/src/config.h +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright © Tavian Barnes -// SPDX-License-Identifier: 0BSD - -/** - * Configuration and feature/platform detection. - */ - -#ifndef BFS_CONFIG_H -#define BFS_CONFIG_H - -// Possible __STDC_VERSION__ values - -#define C95 199409L -#define C99 199901L -#define C11 201112L -#define C17 201710L -#define C23 202311L - -#include - -#if __STDC_VERSION__ < C23 -# include -# include -# include -#endif - -// bfs packaging configuration - -#ifndef BFS_COMMAND -# define BFS_COMMAND "bfs" -#endif -#ifndef BFS_HOMEPAGE -# define BFS_HOMEPAGE "https://tavianator.com/projects/bfs.html" -#endif - -// This is a symbol instead of a literal so we don't have to rebuild everything -// when the version number changes -extern const char bfs_version[]; - -// Check for system headers - -#ifdef __has_include - -#if __has_include() -# define BFS_HAS_MNTENT_H true -#endif -#if __has_include() -# define BFS_HAS_PATHS_H true -#endif -#if __has_include() -# define BFS_HAS_SYS_ACL_H true -#endif -#if __has_include() -# define BFS_HAS_SYS_CAPABILITY_H true -#endif -#if __has_include() -# define BFS_HAS_SYS_EXTATTR_H true -#endif -#if __has_include() -# define BFS_HAS_SYS_MKDEV_H true -#endif -#if __has_include() -# define BFS_HAS_SYS_PARAM_H true -#endif -#if __has_include() -# define BFS_HAS_SYS_SYSMACROS_H true -#endif -#if __has_include() -# define BFS_HAS_SYS_XATTR_H true -#endif -#if __has_include() -# define BFS_HAS_THREADS_H true -#endif -#if __has_include() -# define BFS_HAS_UTIL_H true -#endif - -#else // !__has_include - -#define BFS_HAS_MNTENT_H __GLIBC__ -#define BFS_HAS_PATHS_H true -#define BFS_HAS_SYS_ACL_H true -#define BFS_HAS_SYS_CAPABILITY_H __linux__ -#define BFS_HAS_SYS_EXTATTR_H __FreeBSD__ -#define BFS_HAS_SYS_MKDEV_H false -#define BFS_HAS_SYS_PARAM_H true -#define BFS_HAS_SYS_SYSMACROS_H __GLIBC__ -#define BFS_HAS_SYS_XATTR_H __linux__ -#define BFS_HAS_THREADS_H (!__STDC_NO_THREADS__) -#define BFS_HAS_UTIL_H __NetBSD__ - -#endif // !__has_include - -#ifndef BFS_USE_MNTENT_H -# define BFS_USE_MNTENT_H BFS_HAS_MNTENT_H -#endif -#ifndef BFS_USE_PATHS_H -# define BFS_USE_PATHS_H BFS_HAS_PATHS_H -#endif -#ifndef BFS_USE_SYS_ACL_H -# define BFS_USE_SYS_ACL_H (BFS_HAS_SYS_ACL_H && !__illumos__ && (!__linux__ || BFS_USE_LIBACL)) -#endif -#ifndef BFS_USE_SYS_CAPABILITY_H -# define BFS_USE_SYS_CAPABILITY_H (BFS_HAS_SYS_CAPABILITY_H && !__FreeBSD__ && (!__linux__ || BFS_USE_LIBCAP)) -#endif -#ifndef BFS_USE_SYS_EXTATTR_H -# define BFS_USE_SYS_EXTATTR_H (BFS_HAS_SYS_EXTATTR_H && !__DragonFly__) -#endif -#ifndef BFS_USE_SYS_MKDEV_H -# define BFS_USE_SYS_MKDEV_H BFS_HAS_SYS_MKDEV_H -#endif -#ifndef BFS_USE_SYS_PARAM_H -# define BFS_USE_SYS_PARAM_H BFS_HAS_SYS_PARAM_H -#endif -#ifndef BFS_USE_SYS_SYSMACROS_H -# define BFS_USE_SYS_SYSMACROS_H BFS_HAS_SYS_SYSMACROS_H -#endif -#ifndef BFS_USE_SYS_XATTR_H -# define BFS_USE_SYS_XATTR_H BFS_HAS_SYS_XATTR_H -#endif -#ifndef BFS_USE_THREADS_H -# define BFS_USE_THREADS_H BFS_HAS_THREADS_H -#endif -#ifndef BFS_USE_UTIL_H -# define BFS_USE_UTIL_H BFS_HAS_UTIL_H -#endif - -// Stub out feature detection on old/incompatible compilers - -#ifndef __has_feature -# define __has_feature(feat) false -#endif - -#ifndef __has_c_attribute -# define __has_c_attribute(attr) false -#endif - -#ifndef __has_attribute -# define __has_attribute(attr) false -#endif - -// Platform detection - -// Get the definition of BSD if available -#if BFS_USE_SYS_PARAM_H -# include -#endif - -#ifndef __GLIBC_PREREQ -# define __GLIBC_PREREQ(maj, min) false -#endif - -#ifndef __NetBSD_Prereq__ -# define __NetBSD_Prereq__(maj, min, patch) false -#endif - -// Fundamental utilities - -/** - * Get the length of an array. - */ -#define countof(array) (sizeof(array) / sizeof(0[array])) - -/** - * False sharing/destructive interference/largest cache line size. - */ -#ifdef __GCC_DESTRUCTIVE_SIZE -# define FALSE_SHARING_SIZE __GCC_DESTRUCTIVE_SIZE -#else -# define FALSE_SHARING_SIZE 64 -#endif - -/** - * True sharing/constructive interference/smallest cache line size. - */ -#ifdef __GCC_CONSTRUCTIVE_SIZE -# define TRUE_SHARING_SIZE __GCC_CONSTRUCTIVE_SIZE -#else -# define TRUE_SHARING_SIZE 64 -#endif - -/** - * Alignment specifier that avoids false sharing. - */ -#define cache_align alignas(FALSE_SHARING_SIZE) - -#if __COSMOPOLITAN__ -typedef long double max_align_t; -#endif - -// Wrappers for attributes - -/** - * Silence warnings about switch/case fall-throughs. - */ -#if __has_attribute(fallthrough) -# define fallthru __attribute__((fallthrough)) -#else -# define fallthru ((void)0) -#endif - -/** - * Silence warnings about unused declarations. - */ -#if __has_attribute(unused) -# define attr_maybe_unused __attribute__((unused)) -#else -# define attr_maybe_unused -#endif - -/** - * Warn if a value is unused. - */ -#if __has_attribute(warn_unused_result) -# define attr_nodiscard __attribute__((warn_unused_result)) -#else -# define attr_nodiscard -#endif - -/** - * Hint to avoid inlining a function. - */ -#if __has_attribute(noinline) -# define attr_noinline __attribute__((noinline)) -#else -# define attr_noinline -#endif - -/** - * Hint that a function is unlikely to be called. - */ -#if __has_attribute(cold) -# define attr_cold attr_noinline __attribute__((cold)) -#else -# define attr_cold attr_noinline -#endif - -/** - * Adds compiler warnings for bad printf()-style function calls, if supported. - */ -#if __has_attribute(format) -# define attr_printf(fmt, args) __attribute__((format(printf, fmt, args))) -#else -# define attr_printf(fmt, args) -#endif - -/** - * Annotates allocator-like functions. - */ -#if __has_attribute(malloc) -# if __GNUC__ >= 11 && !__OPTIMIZE__ // malloc(deallocator) disables inlining on GCC -# define attr_malloc(...) attr_nodiscard __attribute__((malloc(__VA_ARGS__))) -# else -# define attr_malloc(...) attr_nodiscard __attribute__((malloc)) -# endif -#else -# define attr_malloc(...) attr_nodiscard -#endif - -/** - * Specifies that a function returns allocations with a given alignment. - */ -#if __has_attribute(alloc_align) -# define attr_alloc_align(param) __attribute__((alloc_align(param))) -#else -# define attr_alloc_align(param) -#endif - -/** - * Specifies that a function returns allocations with a given size. - */ -#if __has_attribute(alloc_size) -# define attr_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__))) -#else -# define attr_alloc_size(...) -#endif - -/** - * Shorthand for attr_alloc_align() and attr_alloc_size(). - */ -#define attr_aligned_alloc(align, ...) \ - attr_alloc_align(align) \ - attr_alloc_size(__VA_ARGS__) - -/** - * Check if function multiversioning via GNU indirect functions (ifunc) is supported. - */ -#ifndef BFS_USE_TARGET_CLONES -# if __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__) -# define BFS_USE_TARGET_CLONES true -# endif -#endif - -/** - * Apply the target_clones attribute, if available. - */ -#if BFS_USE_TARGET_CLONES -# define attr_target_clones(...) __attribute__((target_clones(__VA_ARGS__))) -#else -# define attr_target_clones(...) -#endif - -/** - * Shorthand for multiple attributes at once. attr(a, b(c), d) is equivalent to - * - * attr_a - * attr_b(c) - * attr_d - */ -#define attr(...) \ - attr__(attr_##__VA_ARGS__, none, none, none, none, none, none, none, none, none, ) - -/** - * attr() helper. For exposition, pretend we support only 2 args, instead of 9. - * There are a few cases: - * - * attr() - * => attr__(attr_, none, none) - * => attr_ => - * attr_none => - * attr_too_many_none() => - * - * attr(a) - * => attr__(attr_a, none, none) - * => attr_a => __attribute__((a)) - * attr_none => - * attr_too_many_none() => - * - * attr(a, b(c)) - * => attr__(attr_a, b(c), none, none) - * => attr_a => __attribute__((a)) - * attr_b(c) => __attribute__((b(c))) - * attr_too_many_none(none) => - * - * attr(a, b(c), d) - * => attr__(attr_a, b(c), d, none, none) - * => attr_a => __attribute__((a)) - * attr_b(c) => __attribute__((b(c))) - * attr_too_many_d(none, none) => error - * - * Some attribute names are the same as standard library functions, e.g. printf. - * Standard libraries are permitted to define these functions as macros, like - * - * #define printf(...) __builtin_printf(__VA_ARGS__) - * - * The token paste in - * - * #define attr(...) attr__(attr_##__VA_ARGS__, none, none) - * - * is necessary to prevent macro expansion before evaluating attr__(). - * Otherwise, we could get - * - * attr(printf(1, 2)) - * => attr__(__builtin_printf(1, 2), none, none) - * => attr____builtin_printf(1, 2) - * => error - */ -#define attr__(a1, a2, a3, a4, a5, a6, a7, a8, a9, none, ...) \ - a1 \ - attr_##a2 \ - attr_##a3 \ - attr_##a4 \ - attr_##a5 \ - attr_##a6 \ - attr_##a7 \ - attr_##a8 \ - attr_##a9 \ - attr_too_many_##none(__VA_ARGS__) - -// Ignore `attr_none` from expanding 1-9 argument attr(a1, a2, ...) -#define attr_none -// Ignore `attr_` from expanding 0-argument attr() -#define attr_ -// Only trigger an error on more than 9 arguments -#define attr_too_many_none(...) - -#endif // BFS_CONFIG_H diff --git a/src/ctx.h b/src/ctx.h index e14db21..fc3020c 100644 --- a/src/ctx.h +++ b/src/ctx.h @@ -8,9 +8,9 @@ #ifndef BFS_CTX_H #define BFS_CTX_H +#include "prelude.h" #include "alloc.h" #include "bftw.h" -#include "config.h" #include "diag.h" #include "expr.h" #include "trie.h" diff --git a/src/diag.c b/src/diag.c index cb27b92..deb6f26 100644 --- a/src/diag.c +++ b/src/diag.c @@ -1,11 +1,11 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "diag.h" #include "alloc.h" #include "bfstd.h" #include "color.h" -#include "config.h" #include "ctx.h" #include "dstring.h" #include "expr.h" diff --git a/src/diag.h b/src/diag.h index 4054c48..2b13609 100644 --- a/src/diag.h +++ b/src/diag.h @@ -8,7 +8,7 @@ #ifndef BFS_DIAG_H #define BFS_DIAG_H -#include "config.h" +#include "prelude.h" #include /** diff --git a/src/dir.c b/src/dir.c index 98518f2..53c9be3 100644 --- a/src/dir.c +++ b/src/dir.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "dir.h" #include "alloc.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include "sanity.h" #include "trie.h" diff --git a/src/dstring.c b/src/dstring.c index 10b0fad..913dda8 100644 --- a/src/dstring.c +++ b/src/dstring.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "dstring.h" #include "alloc.h" #include "bit.h" -#include "config.h" #include "diag.h" #include #include diff --git a/src/dstring.h b/src/dstring.h index 6006199..9ea7eb9 100644 --- a/src/dstring.h +++ b/src/dstring.h @@ -8,8 +8,8 @@ #ifndef BFS_DSTRING_H #define BFS_DSTRING_H +#include "prelude.h" #include "bfstd.h" -#include "config.h" #include #include diff --git a/src/eval.c b/src/eval.c index d0112c2..b103912 100644 --- a/src/eval.c +++ b/src/eval.c @@ -5,12 +5,12 @@ * Implementation of all the primary expressions. */ +#include "prelude.h" #include "eval.h" #include "bar.h" #include "bfstd.h" #include "bftw.h" #include "color.h" -#include "config.h" #include "ctx.h" #include "diag.h" #include "dir.h" diff --git a/src/eval.h b/src/eval.h index ae43628..4dd7996 100644 --- a/src/eval.h +++ b/src/eval.h @@ -9,7 +9,7 @@ #ifndef BFS_EVAL_H #define BFS_EVAL_H -#include "config.h" +#include "prelude.h" struct bfs_ctx; struct bfs_expr; diff --git a/src/exec.c b/src/exec.c index 60bfd28..e782d49 100644 --- a/src/exec.c +++ b/src/exec.c @@ -1,12 +1,12 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "exec.h" #include "alloc.h" #include "bfstd.h" #include "bftw.h" #include "color.h" -#include "config.h" #include "ctx.h" #include "diag.h" #include "dstring.h" diff --git a/src/expr.h b/src/expr.h index 75cb5fd..7bcace7 100644 --- a/src/expr.h +++ b/src/expr.h @@ -8,8 +8,8 @@ #ifndef BFS_EXPR_H #define BFS_EXPR_H +#include "prelude.h" #include "color.h" -#include "config.h" #include "eval.h" #include "stat.h" #include diff --git a/src/fsade.c b/src/fsade.c index 0810c7f..34a4d57 100644 --- a/src/fsade.c +++ b/src/fsade.c @@ -1,11 +1,11 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "fsade.h" #include "atomic.h" #include "bfstd.h" #include "bftw.h" -#include "config.h" #include "dir.h" #include "dstring.h" #include "sanity.h" diff --git a/src/fsade.h b/src/fsade.h index 1f1dbfc..6300852 100644 --- a/src/fsade.h +++ b/src/fsade.h @@ -9,7 +9,7 @@ #ifndef BFS_FSADE_H #define BFS_FSADE_H -#include "config.h" +#include "prelude.h" #define BFS_CAN_CHECK_ACL BFS_USE_SYS_ACL_H diff --git a/src/ioq.c b/src/ioq.c index b936681..189bdac 100644 --- a/src/ioq.c +++ b/src/ioq.c @@ -118,12 +118,12 @@ * [1]: https://arxiv.org/abs/2201.02179 */ +#include "prelude.h" #include "ioq.h" #include "alloc.h" #include "atomic.h" #include "bfstd.h" #include "bit.h" -#include "config.h" #include "diag.h" #include "dir.h" #include "stat.h" diff --git a/src/ioq.h b/src/ioq.h index 818eea6..d8e1573 100644 --- a/src/ioq.h +++ b/src/ioq.h @@ -8,7 +8,7 @@ #ifndef BFS_IOQ_H #define BFS_IOQ_H -#include "config.h" +#include "prelude.h" #include "dir.h" #include "stat.h" #include diff --git a/src/main.c b/src/main.c index e120f03..9d8b206 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,7 @@ * - bit.h (bit manipulation) * - bfstd.[ch] (standard library wrappers/polyfills) * - color.[ch] (for pretty terminal colors) - * - config.h (configuration and feature/platform detection) + * - prelude.h (configuration and feature/platform detection) * - diag.[ch] (formats diagnostic messages) * - dir.[ch] (a directory API facade) * - dstring.[ch] (a dynamic string library) @@ -45,8 +45,8 @@ * - xtime.[ch] (date/time handling utilities) */ +#include "prelude.h" #include "bfstd.h" -#include "config.h" #include "ctx.h" #include "diag.h" #include "eval.h" diff --git a/src/mtab.c b/src/mtab.c index 86ae151..7905d14 100644 --- a/src/mtab.c +++ b/src/mtab.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "mtab.h" #include "alloc.h" #include "bfstd.h" -#include "config.h" #include "stat.h" #include "trie.h" #include diff --git a/src/mtab.h b/src/mtab.h index d99d78f..67290c2 100644 --- a/src/mtab.h +++ b/src/mtab.h @@ -8,7 +8,7 @@ #ifndef BFS_MTAB_H #define BFS_MTAB_H -#include "config.h" +#include "prelude.h" struct bfs_stat; diff --git a/src/opt.c b/src/opt.c index b74b4e1..ffc795b 100644 --- a/src/opt.c +++ b/src/opt.c @@ -25,11 +25,11 @@ * effects are reachable at all, skipping the traversal if not. */ +#include "prelude.h" #include "opt.h" #include "bftw.h" #include "bit.h" #include "color.h" -#include "config.h" #include "ctx.h" #include "diag.h" #include "dir.h" diff --git a/src/parse.c b/src/parse.c index a3e32fe..c2ae58f 100644 --- a/src/parse.c +++ b/src/parse.c @@ -8,12 +8,12 @@ * flags like always-true options, and skipping over paths wherever they appear. */ +#include "prelude.h" #include "parse.h" #include "alloc.h" #include "bfstd.h" #include "bftw.h" #include "color.h" -#include "config.h" #include "ctx.h" #include "diag.h" #include "dir.h" diff --git a/src/prelude.h b/src/prelude.h new file mode 100644 index 0000000..c3a0752 --- /dev/null +++ b/src/prelude.h @@ -0,0 +1,377 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +/** + * Configuration and feature/platform detection. + */ + +#ifndef BFS_PRELUDE_H +#define BFS_PRELUDE_H + +// Possible __STDC_VERSION__ values + +#define C95 199409L +#define C99 199901L +#define C11 201112L +#define C17 201710L +#define C23 202311L + +#include + +#if __STDC_VERSION__ < C23 +# include +# include +# include +#endif + +// bfs packaging configuration + +#ifndef BFS_COMMAND +# define BFS_COMMAND "bfs" +#endif +#ifndef BFS_HOMEPAGE +# define BFS_HOMEPAGE "https://tavianator.com/projects/bfs.html" +#endif + +// This is a symbol instead of a literal so we don't have to rebuild everything +// when the version number changes +extern const char bfs_version[]; + +// Check for system headers + +#ifdef __has_include + +#if __has_include() +# define BFS_HAS_MNTENT_H true +#endif +#if __has_include() +# define BFS_HAS_PATHS_H true +#endif +#if __has_include() +# define BFS_HAS_SYS_ACL_H true +#endif +#if __has_include() +# define BFS_HAS_SYS_CAPABILITY_H true +#endif +#if __has_include() +# define BFS_HAS_SYS_EXTATTR_H true +#endif +#if __has_include() +# define BFS_HAS_SYS_MKDEV_H true +#endif +#if __has_include() +# define BFS_HAS_SYS_PARAM_H true +#endif +#if __has_include() +# define BFS_HAS_SYS_SYSMACROS_H true +#endif +#if __has_include() +# define BFS_HAS_SYS_XATTR_H true +#endif +#if __has_include() +# define BFS_HAS_THREADS_H true +#endif +#if __has_include() +# define BFS_HAS_UTIL_H true +#endif + +#else // !__has_include + +#define BFS_HAS_MNTENT_H __GLIBC__ +#define BFS_HAS_PATHS_H true +#define BFS_HAS_SYS_ACL_H true +#define BFS_HAS_SYS_CAPABILITY_H __linux__ +#define BFS_HAS_SYS_EXTATTR_H __FreeBSD__ +#define BFS_HAS_SYS_MKDEV_H false +#define BFS_HAS_SYS_PARAM_H true +#define BFS_HAS_SYS_SYSMACROS_H __GLIBC__ +#define BFS_HAS_SYS_XATTR_H __linux__ +#define BFS_HAS_THREADS_H (!__STDC_NO_THREADS__) +#define BFS_HAS_UTIL_H __NetBSD__ + +#endif // !__has_include + +#ifndef BFS_USE_MNTENT_H +# define BFS_USE_MNTENT_H BFS_HAS_MNTENT_H +#endif +#ifndef BFS_USE_PATHS_H +# define BFS_USE_PATHS_H BFS_HAS_PATHS_H +#endif +#ifndef BFS_USE_SYS_ACL_H +# define BFS_USE_SYS_ACL_H (BFS_HAS_SYS_ACL_H && !__illumos__ && (!__linux__ || BFS_USE_LIBACL)) +#endif +#ifndef BFS_USE_SYS_CAPABILITY_H +# define BFS_USE_SYS_CAPABILITY_H (BFS_HAS_SYS_CAPABILITY_H && !__FreeBSD__ && (!__linux__ || BFS_USE_LIBCAP)) +#endif +#ifndef BFS_USE_SYS_EXTATTR_H +# define BFS_USE_SYS_EXTATTR_H (BFS_HAS_SYS_EXTATTR_H && !__DragonFly__) +#endif +#ifndef BFS_USE_SYS_MKDEV_H +# define BFS_USE_SYS_MKDEV_H BFS_HAS_SYS_MKDEV_H +#endif +#ifndef BFS_USE_SYS_PARAM_H +# define BFS_USE_SYS_PARAM_H BFS_HAS_SYS_PARAM_H +#endif +#ifndef BFS_USE_SYS_SYSMACROS_H +# define BFS_USE_SYS_SYSMACROS_H BFS_HAS_SYS_SYSMACROS_H +#endif +#ifndef BFS_USE_SYS_XATTR_H +# define BFS_USE_SYS_XATTR_H BFS_HAS_SYS_XATTR_H +#endif +#ifndef BFS_USE_THREADS_H +# define BFS_USE_THREADS_H BFS_HAS_THREADS_H +#endif +#ifndef BFS_USE_UTIL_H +# define BFS_USE_UTIL_H BFS_HAS_UTIL_H +#endif + +// Stub out feature detection on old/incompatible compilers + +#ifndef __has_feature +# define __has_feature(feat) false +#endif + +#ifndef __has_c_attribute +# define __has_c_attribute(attr) false +#endif + +#ifndef __has_attribute +# define __has_attribute(attr) false +#endif + +// Platform detection + +// Get the definition of BSD if available +#if BFS_USE_SYS_PARAM_H +# include +#endif + +#ifndef __GLIBC_PREREQ +# define __GLIBC_PREREQ(maj, min) false +#endif + +#ifndef __NetBSD_Prereq__ +# define __NetBSD_Prereq__(maj, min, patch) false +#endif + +// Fundamental utilities + +/** + * Get the length of an array. + */ +#define countof(array) (sizeof(array) / sizeof(0[array])) + +/** + * False sharing/destructive interference/largest cache line size. + */ +#ifdef __GCC_DESTRUCTIVE_SIZE +# define FALSE_SHARING_SIZE __GCC_DESTRUCTIVE_SIZE +#else +# define FALSE_SHARING_SIZE 64 +#endif + +/** + * True sharing/constructive interference/smallest cache line size. + */ +#ifdef __GCC_CONSTRUCTIVE_SIZE +# define TRUE_SHARING_SIZE __GCC_CONSTRUCTIVE_SIZE +#else +# define TRUE_SHARING_SIZE 64 +#endif + +/** + * Alignment specifier that avoids false sharing. + */ +#define cache_align alignas(FALSE_SHARING_SIZE) + +#if __COSMOPOLITAN__ +typedef long double max_align_t; +#endif + +// Wrappers for attributes + +/** + * Silence warnings about switch/case fall-throughs. + */ +#if __has_attribute(fallthrough) +# define fallthru __attribute__((fallthrough)) +#else +# define fallthru ((void)0) +#endif + +/** + * Silence warnings about unused declarations. + */ +#if __has_attribute(unused) +# define attr_maybe_unused __attribute__((unused)) +#else +# define attr_maybe_unused +#endif + +/** + * Warn if a value is unused. + */ +#if __has_attribute(warn_unused_result) +# define attr_nodiscard __attribute__((warn_unused_result)) +#else +# define attr_nodiscard +#endif + +/** + * Hint to avoid inlining a function. + */ +#if __has_attribute(noinline) +# define attr_noinline __attribute__((noinline)) +#else +# define attr_noinline +#endif + +/** + * Hint that a function is unlikely to be called. + */ +#if __has_attribute(cold) +# define attr_cold attr_noinline __attribute__((cold)) +#else +# define attr_cold attr_noinline +#endif + +/** + * Adds compiler warnings for bad printf()-style function calls, if supported. + */ +#if __has_attribute(format) +# define attr_printf(fmt, args) __attribute__((format(printf, fmt, args))) +#else +# define attr_printf(fmt, args) +#endif + +/** + * Annotates allocator-like functions. + */ +#if __has_attribute(malloc) +# if __GNUC__ >= 11 && !__OPTIMIZE__ // malloc(deallocator) disables inlining on GCC +# define attr_malloc(...) attr_nodiscard __attribute__((malloc(__VA_ARGS__))) +# else +# define attr_malloc(...) attr_nodiscard __attribute__((malloc)) +# endif +#else +# define attr_malloc(...) attr_nodiscard +#endif + +/** + * Specifies that a function returns allocations with a given alignment. + */ +#if __has_attribute(alloc_align) +# define attr_alloc_align(param) __attribute__((alloc_align(param))) +#else +# define attr_alloc_align(param) +#endif + +/** + * Specifies that a function returns allocations with a given size. + */ +#if __has_attribute(alloc_size) +# define attr_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__))) +#else +# define attr_alloc_size(...) +#endif + +/** + * Shorthand for attr_alloc_align() and attr_alloc_size(). + */ +#define attr_aligned_alloc(align, ...) \ + attr_alloc_align(align) \ + attr_alloc_size(__VA_ARGS__) + +/** + * Check if function multiversioning via GNU indirect functions (ifunc) is supported. + */ +#ifndef BFS_USE_TARGET_CLONES +# if __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__) +# define BFS_USE_TARGET_CLONES true +# endif +#endif + +/** + * Apply the target_clones attribute, if available. + */ +#if BFS_USE_TARGET_CLONES +# define attr_target_clones(...) __attribute__((target_clones(__VA_ARGS__))) +#else +# define attr_target_clones(...) +#endif + +/** + * Shorthand for multiple attributes at once. attr(a, b(c), d) is equivalent to + * + * attr_a + * attr_b(c) + * attr_d + */ +#define attr(...) \ + attr__(attr_##__VA_ARGS__, none, none, none, none, none, none, none, none, none, ) + +/** + * attr() helper. For exposition, pretend we support only 2 args, instead of 9. + * There are a few cases: + * + * attr() + * => attr__(attr_, none, none) + * => attr_ => + * attr_none => + * attr_too_many_none() => + * + * attr(a) + * => attr__(attr_a, none, none) + * => attr_a => __attribute__((a)) + * attr_none => + * attr_too_many_none() => + * + * attr(a, b(c)) + * => attr__(attr_a, b(c), none, none) + * => attr_a => __attribute__((a)) + * attr_b(c) => __attribute__((b(c))) + * attr_too_many_none(none) => + * + * attr(a, b(c), d) + * => attr__(attr_a, b(c), d, none, none) + * => attr_a => __attribute__((a)) + * attr_b(c) => __attribute__((b(c))) + * attr_too_many_d(none, none) => error + * + * Some attribute names are the same as standard library functions, e.g. printf. + * Standard libraries are permitted to define these functions as macros, like + * + * #define printf(...) __builtin_printf(__VA_ARGS__) + * + * The token paste in + * + * #define attr(...) attr__(attr_##__VA_ARGS__, none, none) + * + * is necessary to prevent macro expansion before evaluating attr__(). + * Otherwise, we could get + * + * attr(printf(1, 2)) + * => attr__(__builtin_printf(1, 2), none, none) + * => attr____builtin_printf(1, 2) + * => error + */ +#define attr__(a1, a2, a3, a4, a5, a6, a7, a8, a9, none, ...) \ + a1 \ + attr_##a2 \ + attr_##a3 \ + attr_##a4 \ + attr_##a5 \ + attr_##a6 \ + attr_##a7 \ + attr_##a8 \ + attr_##a9 \ + attr_too_many_##none(__VA_ARGS__) + +// Ignore `attr_none` from expanding 1-9 argument attr(a1, a2, ...) +#define attr_none +// Ignore `attr_` from expanding 0-argument attr() +#define attr_ +// Only trigger an error on more than 9 arguments +#define attr_too_many_none(...) + +#endif // BFS_PRELUDE_H diff --git a/src/printf.c b/src/printf.c index 3b8269e..4df399b 100644 --- a/src/printf.c +++ b/src/printf.c @@ -1,12 +1,12 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "printf.h" #include "alloc.h" #include "bfstd.h" #include "bftw.h" #include "color.h" -#include "config.h" #include "ctx.h" #include "diag.h" #include "dir.h" diff --git a/src/pwcache.c b/src/pwcache.c index 79437d8..af8c237 100644 --- a/src/pwcache.c +++ b/src/pwcache.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "pwcache.h" #include "alloc.h" -#include "config.h" #include "trie.h" #include #include diff --git a/src/sanity.h b/src/sanity.h index 423e6ff..e168b8f 100644 --- a/src/sanity.h +++ b/src/sanity.h @@ -8,7 +8,7 @@ #ifndef BFS_SANITY_H #define BFS_SANITY_H -#include "config.h" +#include "prelude.h" #include #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) diff --git a/src/stat.c b/src/stat.c index 2f2743b..eca5bab 100644 --- a/src/stat.c +++ b/src/stat.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "stat.h" #include "atomic.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include "sanity.h" #include diff --git a/src/stat.h b/src/stat.h index 856a2ca..1fdd263 100644 --- a/src/stat.h +++ b/src/stat.h @@ -12,7 +12,7 @@ #ifndef BFS_STAT_H #define BFS_STAT_H -#include "config.h" +#include "prelude.h" #include #include #include diff --git a/src/thread.c b/src/thread.c index 200d8c3..3793896 100644 --- a/src/thread.c +++ b/src/thread.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "thread.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include #include diff --git a/src/thread.h b/src/thread.h index 8174fe4..db11bd8 100644 --- a/src/thread.h +++ b/src/thread.h @@ -8,7 +8,7 @@ #ifndef BFS_THREAD_H #define BFS_THREAD_H -#include "config.h" +#include "prelude.h" #include #if __STDC_VERSION__ < C23 && !defined(thread_local) diff --git a/src/trie.c b/src/trie.c index f275064..808953e 100644 --- a/src/trie.c +++ b/src/trie.c @@ -81,10 +81,10 @@ * and insert intermediate singleton "jump" nodes when necessary. */ +#include "prelude.h" #include "trie.h" #include "alloc.h" #include "bit.h" -#include "config.h" #include "diag.h" #include "list.h" #include diff --git a/src/xregex.c b/src/xregex.c index 3df27f0..c2711bc 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "xregex.h" #include "alloc.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include "sanity.h" #include "thread.h" diff --git a/src/xspawn.c b/src/xspawn.c index 347625d..113d7ec 100644 --- a/src/xspawn.c +++ b/src/xspawn.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "xspawn.h" #include "alloc.h" #include "bfstd.h" -#include "config.h" #include "list.h" #include #include diff --git a/src/xspawn.h b/src/xspawn.h index a20cbd0..6a8f54a 100644 --- a/src/xspawn.h +++ b/src/xspawn.h @@ -8,7 +8,7 @@ #ifndef BFS_XSPAWN_H #define BFS_XSPAWN_H -#include "config.h" +#include "prelude.h" #include #include #include diff --git a/src/xtime.c b/src/xtime.c index bcf6dd3..91ed915 100644 --- a/src/xtime.c +++ b/src/xtime.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "xtime.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include #include diff --git a/tests/alloc.c b/tests/alloc.c index 54b84ba..6c0defd 100644 --- a/tests/alloc.c +++ b/tests/alloc.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "tests.h" #include "alloc.h" -#include "config.h" #include "diag.h" #include #include diff --git a/tests/bfstd.c b/tests/bfstd.c index 5e408ca..07b68b0 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "tests.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include #include diff --git a/tests/bit.c b/tests/bit.c index b444e50..674d1b2 100644 --- a/tests/bit.c +++ b/tests/bit.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "tests.h" #include "bit.h" -#include "config.h" #include "diag.h" #include #include diff --git a/tests/ioq.c b/tests/ioq.c index a69f2bf..ef5ee3b 100644 --- a/tests/ioq.c +++ b/tests/ioq.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "tests.h" #include "ioq.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include "dir.h" #include diff --git a/tests/main.c b/tests/main.c index 281c417..429772b 100644 --- a/tests/main.c +++ b/tests/main.c @@ -5,10 +5,10 @@ * Entry point for unit tests. */ +#include "prelude.h" #include "tests.h" #include "bfstd.h" #include "color.h" -#include "config.h" #include #include #include diff --git a/tests/tests.h b/tests/tests.h index d61ffd7..9078938 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -8,7 +8,7 @@ #ifndef BFS_TESTS_H #define BFS_TESTS_H -#include "config.h" +#include "prelude.h" #include "diag.h" /** Unit test function type. */ diff --git a/tests/trie.c b/tests/trie.c index 2a6eb48..4667322 100644 --- a/tests/trie.c +++ b/tests/trie.c @@ -1,9 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "tests.h" #include "trie.h" -#include "config.h" #include "diag.h" #include #include diff --git a/tests/xspawn.c b/tests/xspawn.c index fd8362e..7362aa5 100644 --- a/tests/xspawn.c +++ b/tests/xspawn.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "tests.h" #include "alloc.h" #include "bfstd.h" -#include "config.h" #include "dstring.h" #include "xspawn.h" #include diff --git a/tests/xtime.c b/tests/xtime.c index fd7aa0f..a7c63d2 100644 --- a/tests/xtime.c +++ b/tests/xtime.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "tests.h" #include "xtime.h" #include "bfstd.h" -#include "config.h" #include "diag.h" #include #include diff --git a/tests/xtouch.c b/tests/xtouch.c index b1daec7..82d749d 100644 --- a/tests/xtouch.c +++ b/tests/xtouch.c @@ -1,8 +1,8 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD +#include "prelude.h" #include "bfstd.h" -#include "config.h" #include "sanity.h" #include "xtime.h" #include -- cgit v1.2.3