From d1febdd40faf2f66a901c42377a6b6efaad1449c Mon Sep 17 00:00:00 2001
From: Tavian Barnes <tavianator@tavianator.com>
Date: Wed, 28 Aug 2024 09:55:24 -0400
Subject: prelude: Split bfs-specific utilities into new bfs.h header

---
 src/alloc.c     |   3 +
 src/alloc.h     |   3 +
 src/atomic.h    |   3 +
 src/bar.c       |   3 +
 src/bfs.h       | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/bfstd.c     |   3 +
 src/bfstd.h     |   3 +
 src/bftw.c      |   3 +
 src/bftw.h      |   1 +
 src/bit.h       |   3 +
 src/color.c     |   3 +
 src/color.h     |   3 +
 src/ctx.c       |   2 +
 src/ctx.h       |   2 +
 src/diag.c      |   3 +
 src/diag.h      |   3 +
 src/dir.c       |   3 +
 src/dir.h       |   3 +
 src/dstring.c   |   2 +
 src/dstring.h   |   3 +
 src/eval.c      |   3 +
 src/exec.c      |   3 +
 src/expr.c      |   2 +
 src/expr.h      |   2 +
 src/fsade.c     |   3 +
 src/fsade.h     |   2 +
 src/ioq.c       |   3 +
 src/ioq.h       |   2 +
 src/list.h      |   1 +
 src/main.c      |   3 +
 src/mtab.c      |   3 +
 src/opt.c       |   3 +
 src/parse.c     |   3 +
 src/prelude.h   | 197 +--------------------------------------------------
 src/printf.c    |   3 +
 src/pwcache.c   |   2 +
 src/sanity.h    |   1 +
 src/sighook.c   |   3 +
 src/stat.c      |   3 +
 src/stat.h      |   3 +
 src/thread.c    |   2 +
 src/thread.h    |   1 +
 src/trie.c      |   3 +
 src/trie.h      |   1 +
 src/typo.c      |   1 +
 src/version.c   |   2 +
 src/xregex.c    |   3 +
 src/xspawn.c    |   3 +
 src/xspawn.h    |   1 +
 src/xtime.c     |   3 +
 tests/alloc.c   |   2 +
 tests/bfstd.c   |   2 +
 tests/bit.c     |   5 +-
 tests/ioq.c     |   4 +-
 tests/list.c    |   4 +-
 tests/main.c    |   2 +
 tests/mksock.c  |   1 +
 tests/sighook.c |   4 +-
 tests/tests.h   |   1 +
 tests/trie.c    |   5 +-
 tests/xspawn.c  |   2 +
 tests/xtime.c   |   7 +-
 tests/xtouch.c  |   2 +
 63 files changed, 373 insertions(+), 201 deletions(-)
 create mode 100644 src/bfs.h

diff --git a/src/alloc.c b/src/alloc.c
index d7a70e9..43340f7 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3,9 +3,12 @@
 
 #include "prelude.h"
 #include "alloc.h"
+
+#include "bfs.h"
 #include "bit.h"
 #include "diag.h"
 #include "sanity.h"
+
 #include <errno.h>
 #include <stdlib.h>
 #include <stdint.h>
diff --git a/src/alloc.h b/src/alloc.h
index 6b863f2..5113839 100644
--- a/src/alloc.h
+++ b/src/alloc.h
@@ -9,6 +9,9 @@
 #define BFS_ALLOC_H
 
 #include "prelude.h"
+
+#include "bfs.h"
+
 #include <errno.h>
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/atomic.h b/src/atomic.h
index a241a03..5e29974 100644
--- a/src/atomic.h
+++ b/src/atomic.h
@@ -9,6 +9,9 @@
 #define BFS_ATOMIC_H
 
 #include "prelude.h"
+
+#include "bfs.h"
+
 #include <stdatomic.h>
 
 /**
diff --git a/src/bar.c b/src/bar.c
index 6ef1198..c574790 100644
--- a/src/bar.c
+++ b/src/bar.c
@@ -3,12 +3,15 @@
 
 #include "prelude.h"
 #include "bar.h"
+
 #include "alloc.h"
 #include "atomic.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "bit.h"
 #include "dstring.h"
 #include "sighook.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
diff --git a/src/bfs.h b/src/bfs.h
new file mode 100644
index 0000000..8820ab9
--- /dev/null
+++ b/src/bfs.h
@@ -0,0 +1,216 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+/**
+ * Configuration and fundamental utilities.
+ */
+
+#ifndef BFS_H
+#define BFS_H
+
+#include "prelude.h"
+
+// Standard versions
+
+/** Possible __STDC_VERSION__ values. */
+#define C95 199409L
+#define C99 199901L
+#define C11 201112L
+#define C17 201710L
+#define C23 202311L
+
+/** Possible _POSIX_C_SOURCE and _POSIX_<OPTION> values. */
+#define POSIX_1990 1
+#define POSIX_1992 2
+#define POSIX_1993 199309L
+#define POSIX_1995 199506L
+#define POSIX_2001 200112L
+#define POSIX_2008 200809L
+#define POSIX_2024 202405L
+
+// Build configuration
+
+#include "config.h"
+
+#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[];
+
+extern const char bfs_confflags[];
+extern const char bfs_cc[];
+extern const char bfs_cppflags[];
+extern const char bfs_cflags[];
+extern const char bfs_ldflags[];
+extern const char bfs_ldlibs[];
+
+// Get __GLIBC__
+#include <assert.h>
+
+// Fundamental utilities
+
+/**
+ * Get the length of an array.
+ */
+#define countof(...) (sizeof(__VA_ARGS__) / sizeof(0[__VA_ARGS__]))
+
+/**
+ * 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)
+
+// Wrappers for attributes
+
+/**
+ * Silence warnings about switch/case fall-throughs.
+ */
+#if __has_attribute(fallthrough)
+#  define _fallthrough __attribute__((fallthrough))
+#else
+#  define _fallthrough ((void)0)
+#endif
+
+/**
+ * Silence warnings about unused declarations.
+ */
+#if __has_attribute(unused)
+#  define _maybe_unused __attribute__((unused))
+#else
+#  define _maybe_unused
+#endif
+
+/**
+ * Warn if a value is unused.
+ */
+#if __has_attribute(warn_unused_result)
+#  define _nodiscard __attribute__((warn_unused_result))
+#else
+#  define _nodiscard
+#endif
+
+/**
+ * Hint to avoid inlining a function.
+ */
+#if __has_attribute(noinline)
+#  define _noinline __attribute__((noinline))
+#else
+#  define _noinline
+#endif
+
+/**
+ * Marks a non-returning function.
+ */
+#if __STDC_VERSION__ >= C23
+#  define _noreturn [[noreturn]]
+#else
+#  define _noreturn _Noreturn
+#endif
+
+/**
+ * Hint that a function is unlikely to be called.
+ */
+#if __has_attribute(cold)
+#  define _cold _noinline __attribute__((cold))
+#else
+#  define _cold _noinline
+#endif
+
+/**
+ * Adds compiler warnings for bad printf()-style function calls, if supported.
+ */
+#if __has_attribute(format)
+#  define _printf(fmt, args) __attribute__((format(printf, fmt, args)))
+#else
+#  define _printf(fmt, args)
+#endif
+
+/**
+ * Annotates functions that potentially modify and return format strings.
+ */
+#if __has_attribute(format_arg)
+#  define _format_arg(arg) __attribute__((format_arg(arg)))
+#else
+#  define _format_arg(arg)
+#endif
+
+/**
+ * Annotates allocator-like functions.
+ */
+#if __has_attribute(malloc)
+#  if __GNUC__ >= 11 && !__OPTIMIZE__ // malloc(deallocator) disables inlining on GCC
+#    define _malloc(...) _nodiscard __attribute__((malloc(__VA_ARGS__)))
+#  else
+#    define _malloc(...) _nodiscard __attribute__((malloc))
+#  endif
+#else
+#  define _malloc(...) _nodiscard
+#endif
+
+/**
+ * Specifies that a function returns allocations with a given alignment.
+ */
+#if __has_attribute(alloc_align)
+#  define _alloc_align(param) __attribute__((alloc_align(param)))
+#else
+#  define _alloc_align(param)
+#endif
+
+/**
+ * Specifies that a function returns allocations with a given size.
+ */
+#if __has_attribute(alloc_size)
+#  define _alloc_size(...) __attribute__((alloc_size(__VA_ARGS__)))
+#else
+#  define _alloc_size(...)
+#endif
+
+/**
+ * Shorthand for _alloc_align() and _alloc_size().
+ */
+#define _aligned_alloc(align, ...) _alloc_align(align) _alloc_size(__VA_ARGS__)
+
+/**
+ * Check if function multiversioning via GNU indirect functions (ifunc) is supported.
+ *
+ * Disabled on TSan due to https://github.com/google/sanitizers/issues/342.
+ */
+#ifndef BFS_USE_TARGET_CLONES
+#  if __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__) && !__SANITIZE_THREAD__
+#    define BFS_USE_TARGET_CLONES true
+#  endif
+#endif
+
+/**
+ * Apply the target_clones attribute, if available.
+ */
+#if BFS_USE_TARGET_CLONES
+#  define _target_clones(...) __attribute__((target_clones(__VA_ARGS__)))
+#else
+#  define _target_clones(...)
+#endif
+
+#endif // BFS_H
diff --git a/src/bfstd.c b/src/bfstd.c
index a76725d..5a6038d 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -3,11 +3,14 @@
 
 #include "prelude.h"
 #include "bfstd.h"
+
+#include "bfs.h"
 #include "bit.h"
 #include "diag.h"
 #include "sanity.h"
 #include "thread.h"
 #include "xregex.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <langinfo.h>
diff --git a/src/bfstd.h b/src/bfstd.h
index 3a15715..67894cd 100644
--- a/src/bfstd.h
+++ b/src/bfstd.h
@@ -9,6 +9,9 @@
 #define BFS_BFSTD_H
 
 #include "prelude.h"
+
+#include "bfs.h"
+
 #include <stddef.h>
 
 #include <ctype.h>
diff --git a/src/bftw.c b/src/bftw.c
index 11c4825..351cc36 100644
--- a/src/bftw.c
+++ b/src/bftw.c
@@ -20,7 +20,9 @@
 
 #include "prelude.h"
 #include "bftw.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "diag.h"
 #include "dir.h"
@@ -30,6 +32,7 @@
 #include "mtab.h"
 #include "stat.h"
 #include "trie.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
diff --git a/src/bftw.h b/src/bftw.h
index a2a201c..28e0679 100644
--- a/src/bftw.h
+++ b/src/bftw.h
@@ -10,6 +10,7 @@
 
 #include "dir.h"
 #include "stat.h"
+
 #include <stddef.h>
 
 /**
diff --git a/src/bit.h b/src/bit.h
index 7546aba..0c11895 100644
--- a/src/bit.h
+++ b/src/bit.h
@@ -9,6 +9,9 @@
 #define BFS_BIT_H
 
 #include "prelude.h"
+
+#include "bfs.h"
+
 #include <limits.h>
 #include <stdint.h>
 
diff --git a/src/color.c b/src/color.c
index db90f9c..0c38c7d 100644
--- a/src/color.c
+++ b/src/color.c
@@ -3,7 +3,9 @@
 
 #include "prelude.h"
 #include "color.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "bftw.h"
 #include "diag.h"
@@ -13,6 +15,7 @@
 #include "fsade.h"
 #include "stat.h"
 #include "trie.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
diff --git a/src/color.h b/src/color.h
index 6847e3b..6102480 100644
--- a/src/color.h
+++ b/src/color.h
@@ -9,7 +9,10 @@
 #define BFS_COLOR_H
 
 #include "prelude.h"
+
+#include "bfs.h"
 #include "dstring.h"
+
 #include <stdio.h>
 
 /**
diff --git a/src/ctx.c b/src/ctx.c
index b33e0e3..411038e 100644
--- a/src/ctx.c
+++ b/src/ctx.c
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: 0BSD
 
 #include "ctx.h"
+
 #include "alloc.h"
 #include "bfstd.h"
 #include "color.h"
@@ -14,6 +15,7 @@
 #include "stat.h"
 #include "trie.h"
 #include "xtime.h"
+
 #include <errno.h>
 #include <limits.h>
 #include <signal.h>
diff --git a/src/ctx.h b/src/ctx.h
index 4ca4a34..0b4be45 100644
--- a/src/ctx.h
+++ b/src/ctx.h
@@ -9,11 +9,13 @@
 #define BFS_CTX_H
 
 #include "prelude.h"
+
 #include "alloc.h"
 #include "bftw.h"
 #include "diag.h"
 #include "expr.h"
 #include "trie.h"
+
 #include <stddef.h>
 #include <sys/resource.h>
 #include <sys/types.h>
diff --git a/src/diag.c b/src/diag.c
index 6ae088c..30525ac 100644
--- a/src/diag.c
+++ b/src/diag.c
@@ -3,12 +3,15 @@
 
 #include "prelude.h"
 #include "diag.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "color.h"
 #include "ctx.h"
 #include "dstring.h"
 #include "expr.h"
+
 #include <errno.h>
 #include <stdarg.h>
 #include <stdio.h>
diff --git a/src/diag.h b/src/diag.h
index a8e5a5c..2d05654 100644
--- a/src/diag.h
+++ b/src/diag.h
@@ -9,7 +9,10 @@
 #define BFS_DIAG_H
 
 #include "prelude.h"
+
+#include "bfs.h"
 #include "bfstd.h"
+
 #include <stdarg.h>
 
 /**
diff --git a/src/dir.c b/src/dir.c
index fadf1c0..0a93fe0 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -3,11 +3,14 @@
 
 #include "prelude.h"
 #include "dir.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "diag.h"
 #include "sanity.h"
 #include "trie.h"
+
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
diff --git a/src/dir.h b/src/dir.h
index bbba071..0008d45 100644
--- a/src/dir.h
+++ b/src/dir.h
@@ -9,6 +9,9 @@
 #define BFS_DIR_H
 
 #include "prelude.h"
+
+#include "bfs.h"
+
 #include <sys/types.h>
 
 /**
diff --git a/src/dstring.c b/src/dstring.c
index 86ab646..2f3abc5 100644
--- a/src/dstring.c
+++ b/src/dstring.c
@@ -3,9 +3,11 @@
 
 #include "prelude.h"
 #include "dstring.h"
+
 #include "alloc.h"
 #include "bit.h"
 #include "diag.h"
+
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdint.h>
diff --git a/src/dstring.h b/src/dstring.h
index 46d5edb..a6103e3 100644
--- a/src/dstring.h
+++ b/src/dstring.h
@@ -9,7 +9,10 @@
 #define BFS_DSTRING_H
 
 #include "prelude.h"
+
+#include "bfs.h"
 #include "bfstd.h"
+
 #include <stdarg.h>
 #include <stddef.h>
 
diff --git a/src/eval.c b/src/eval.c
index b277d1f..bbafadb 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -7,8 +7,10 @@
 
 #include "prelude.h"
 #include "eval.h"
+
 #include "atomic.h"
 #include "bar.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "bftw.h"
 #include "color.h"
@@ -27,6 +29,7 @@
 #include "stat.h"
 #include "trie.h"
 #include "xregex.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <fnmatch.h>
diff --git a/src/exec.c b/src/exec.c
index 05c4189..8f78d7b 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -3,7 +3,9 @@
 
 #include "prelude.h"
 #include "exec.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "bftw.h"
 #include "color.h"
@@ -11,6 +13,7 @@
 #include "diag.h"
 #include "dstring.h"
 #include "xspawn.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
diff --git a/src/expr.c b/src/expr.c
index db60e34..110e9b7 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: 0BSD
 
 #include "expr.h"
+
 #include "alloc.h"
 #include "ctx.h"
 #include "diag.h"
@@ -10,6 +11,7 @@
 #include "list.h"
 #include "printf.h"
 #include "xregex.h"
+
 #include <string.h>
 
 struct bfs_expr *bfs_expr_new(struct bfs_ctx *ctx, bfs_eval_fn *eval_fn, size_t argc, char **argv, enum bfs_kind kind) {
diff --git a/src/expr.h b/src/expr.h
index b56e28b..a6edff1 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -9,9 +9,11 @@
 #define BFS_EXPR_H
 
 #include "prelude.h"
+
 #include "color.h"
 #include "eval.h"
 #include "stat.h"
+
 #include <sys/types.h>
 #include <time.h>
 
diff --git a/src/fsade.c b/src/fsade.c
index a5073ab..b10c851 100644
--- a/src/fsade.c
+++ b/src/fsade.c
@@ -3,12 +3,15 @@
 
 #include "prelude.h"
 #include "fsade.h"
+
 #include "atomic.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "bftw.h"
 #include "dir.h"
 #include "dstring.h"
 #include "sanity.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stddef.h>
diff --git a/src/fsade.h b/src/fsade.h
index 4a9c6fa..9c7d117 100644
--- a/src/fsade.h
+++ b/src/fsade.h
@@ -11,6 +11,8 @@
 
 #include "prelude.h"
 
+#include "bfs.h"
+
 #define BFS_CAN_CHECK_ACL (BFS_HAS_ACL_GET_FILE || BFS_HAS_ACL_TRIVIAL)
 
 #define BFS_CAN_CHECK_CAPABILITIES BFS_WITH_LIBCAP
diff --git a/src/ioq.c b/src/ioq.c
index 603163d..10d4536 100644
--- a/src/ioq.c
+++ b/src/ioq.c
@@ -120,14 +120,17 @@
 
 #include "prelude.h"
 #include "ioq.h"
+
 #include "alloc.h"
 #include "atomic.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "bit.h"
 #include "diag.h"
 #include "dir.h"
 #include "stat.h"
 #include "thread.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <pthread.h>
diff --git a/src/ioq.h b/src/ioq.h
index d8e1573..8226941 100644
--- a/src/ioq.h
+++ b/src/ioq.h
@@ -9,8 +9,10 @@
 #define BFS_IOQ_H
 
 #include "prelude.h"
+
 #include "dir.h"
 #include "stat.h"
+
 #include <stddef.h>
 
 /**
diff --git a/src/list.h b/src/list.h
index d95483f..b30a96e 100644
--- a/src/list.h
+++ b/src/list.h
@@ -83,6 +83,7 @@
 #define BFS_LIST_H
 
 #include "diag.h"
+
 #include <stddef.h>
 #include <string.h>
 
diff --git a/src/main.c b/src/main.c
index 6f23034..9f78522 100644
--- a/src/main.c
+++ b/src/main.c
@@ -24,6 +24,7 @@
  *     - atomic.h      (atomic operations)
  *     - bar.[ch]      (a terminal status bar)
  *     - bit.h         (bit manipulation)
+ *     - bfs.h         (configuration and fundamental utilities)
  *     - bfstd.[ch]    (standard library wrappers/polyfills)
  *     - color.[ch]    (for pretty terminal colors)
  *     - prelude.h     (configuration and feature/platform detection)
@@ -48,11 +49,13 @@
  */
 
 #include "prelude.h"
+
 #include "bfstd.h"
 #include "ctx.h"
 #include "diag.h"
 #include "eval.h"
 #include "parse.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <locale.h>
diff --git a/src/mtab.c b/src/mtab.c
index dbe17cc..a013e41 100644
--- a/src/mtab.c
+++ b/src/mtab.c
@@ -3,10 +3,13 @@
 
 #include "prelude.h"
 #include "mtab.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "stat.h"
 #include "trie.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
diff --git a/src/opt.c b/src/opt.c
index 02944ce..f75d9c9 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -27,6 +27,8 @@
 
 #include "prelude.h"
 #include "opt.h"
+
+#include "bfs.h"
 #include "bftw.h"
 #include "bit.h"
 #include "color.h"
@@ -38,6 +40,7 @@
 #include "expr.h"
 #include "list.h"
 #include "pwcache.h"
+
 #include <errno.h>
 #include <limits.h>
 #include <stdarg.h>
diff --git a/src/parse.c b/src/parse.c
index 90b6177..a90dc2d 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -10,7 +10,9 @@
 
 #include "prelude.h"
 #include "parse.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "bftw.h"
 #include "color.h"
@@ -31,6 +33,7 @@
 #include "xregex.h"
 #include "xspawn.h"
 #include "xtime.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <fnmatch.h>
diff --git a/src/prelude.h b/src/prelude.h
index 7df178c..5f7203e 100644
--- a/src/prelude.h
+++ b/src/prelude.h
@@ -8,20 +8,11 @@
 #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
-
-// Get the static_assert() definition as well as __GLIBC__
-#include <assert.h>
-
 // Get the convenience macros that became standard spellings in C23
-#if __STDC_VERSION__ < C23
+#if __STDC_VERSION__ < 202311L
 
+/** _Static_assert() => static_assert() */
+#include <assert.h>
 /** _Alignas(), _Alignof() => alignas(), alignof() */
 #include <stdalign.h>
 /** _Bool => bool, true, false */
@@ -38,28 +29,6 @@
 
 #endif // !C23
 
-// bfs packaging configuration
-
-#include "config.h"
-
-#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[];
-
-extern const char bfs_confflags[];
-extern const char bfs_cc[];
-extern const char bfs_cppflags[];
-extern const char bfs_cflags[];
-extern const char bfs_ldflags[];
-extern const char bfs_ldlibs[];
-
 // Feature detection
 
 // https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
@@ -99,164 +68,4 @@ extern const char bfs_ldlibs[];
 #  define __SANITIZE_THREAD__ true
 #endif
 
-// Fundamental utilities
-
-/**
- * Get the length of an array.
- */
-#define countof(...) (sizeof(__VA_ARGS__) / sizeof(0[__VA_ARGS__]))
-
-/**
- * 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)
-
-// Wrappers for attributes
-
-/**
- * Silence warnings about switch/case fall-throughs.
- */
-#if __has_attribute(fallthrough)
-#  define _fallthrough __attribute__((fallthrough))
-#else
-#  define _fallthrough ((void)0)
-#endif
-
-/**
- * Silence warnings about unused declarations.
- */
-#if __has_attribute(unused)
-#  define _maybe_unused __attribute__((unused))
-#else
-#  define _maybe_unused
-#endif
-
-/**
- * Warn if a value is unused.
- */
-#if __has_attribute(warn_unused_result)
-#  define _nodiscard __attribute__((warn_unused_result))
-#else
-#  define _nodiscard
-#endif
-
-/**
- * Hint to avoid inlining a function.
- */
-#if __has_attribute(noinline)
-#  define _noinline __attribute__((noinline))
-#else
-#  define _noinline
-#endif
-
-/**
- * Marks a non-returning function.
- */
-#if __STDC_VERSION__ >= C23
-#  define _noreturn [[noreturn]]
-#else
-#  define _noreturn _Noreturn
-#endif
-
-/**
- * Hint that a function is unlikely to be called.
- */
-#if __has_attribute(cold)
-#  define _cold _noinline __attribute__((cold))
-#else
-#  define _cold _noinline
-#endif
-
-/**
- * Adds compiler warnings for bad printf()-style function calls, if supported.
- */
-#if __has_attribute(format)
-#  define _printf(fmt, args) __attribute__((format(printf, fmt, args)))
-#else
-#  define _printf(fmt, args)
-#endif
-
-/**
- * Annotates functions that potentially modify and return format strings.
- */
-#if __has_attribute(format_arg)
-#  define _format_arg(arg) __attribute__((format_arg(arg)))
-#else
-#  define _format_arg(arg)
-#endif
-
-/**
- * Annotates allocator-like functions.
- */
-#if __has_attribute(malloc)
-#  if __GNUC__ >= 11 && !__OPTIMIZE__ // malloc(deallocator) disables inlining on GCC
-#    define _malloc(...) _nodiscard __attribute__((malloc(__VA_ARGS__)))
-#  else
-#    define _malloc(...) _nodiscard __attribute__((malloc))
-#  endif
-#else
-#  define _malloc(...) _nodiscard
-#endif
-
-/**
- * Specifies that a function returns allocations with a given alignment.
- */
-#if __has_attribute(alloc_align)
-#  define _alloc_align(param) __attribute__((alloc_align(param)))
-#else
-#  define _alloc_align(param)
-#endif
-
-/**
- * Specifies that a function returns allocations with a given size.
- */
-#if __has_attribute(alloc_size)
-#  define _alloc_size(...) __attribute__((alloc_size(__VA_ARGS__)))
-#else
-#  define _alloc_size(...)
-#endif
-
-/**
- * Shorthand for _alloc_align() and _alloc_size().
- */
-#define _aligned_alloc(align, ...) _alloc_align(align) _alloc_size(__VA_ARGS__)
-
-/**
- * Check if function multiversioning via GNU indirect functions (ifunc) is supported.
- *
- * Disabled on TSan due to https://github.com/google/sanitizers/issues/342.
- */
-#ifndef BFS_USE_TARGET_CLONES
-#  if __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__) && !__SANITIZE_THREAD__
-#    define BFS_USE_TARGET_CLONES true
-#  endif
-#endif
-
-/**
- * Apply the target_clones attribute, if available.
- */
-#if BFS_USE_TARGET_CLONES
-#  define _target_clones(...) __attribute__((target_clones(__VA_ARGS__)))
-#else
-#  define _target_clones(...)
-#endif
-
 #endif // BFS_PRELUDE_H
diff --git a/src/printf.c b/src/printf.c
index c57f4ca..39abdcc 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -3,7 +3,9 @@
 
 #include "prelude.h"
 #include "printf.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "bftw.h"
 #include "color.h"
@@ -16,6 +18,7 @@
 #include "mtab.h"
 #include "pwcache.h"
 #include "stat.h"
+
 #include <errno.h>
 #include <grp.h>
 #include <pwd.h>
diff --git a/src/pwcache.c b/src/pwcache.c
index af8c237..35a9925 100644
--- a/src/pwcache.c
+++ b/src/pwcache.c
@@ -3,8 +3,10 @@
 
 #include "prelude.h"
 #include "pwcache.h"
+
 #include "alloc.h"
 #include "trie.h"
+
 #include <errno.h>
 #include <grp.h>
 #include <pwd.h>
diff --git a/src/sanity.h b/src/sanity.h
index 4488be5..17450a3 100644
--- a/src/sanity.h
+++ b/src/sanity.h
@@ -9,6 +9,7 @@
 #define BFS_SANITY_H
 
 #include "prelude.h"
+
 #include <stddef.h>
 
 // Call macro(ptr, size) or macro(ptr, sizeof(*ptr))
diff --git a/src/sighook.c b/src/sighook.c
index c799777..d697895 100644
--- a/src/sighook.c
+++ b/src/sighook.c
@@ -19,11 +19,14 @@
 
 #include "prelude.h"
 #include "sighook.h"
+
 #include "alloc.h"
 #include "atomic.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "diag.h"
 #include "thread.h"
+
 #include <errno.h>
 #include <signal.h>
 #include <stdlib.h>
diff --git a/src/stat.c b/src/stat.c
index 1e340d0..9f2918d 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -3,10 +3,13 @@
 
 #include "prelude.h"
 #include "stat.h"
+
 #include "atomic.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "diag.h"
 #include "sanity.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <string.h>
diff --git a/src/stat.h b/src/stat.h
index 6a8c3f5..a3da1bf 100644
--- a/src/stat.h
+++ b/src/stat.h
@@ -13,6 +13,9 @@
 #define BFS_STAT_H
 
 #include "prelude.h"
+
+#include "bfs.h"
+
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <time.h>
diff --git a/src/thread.c b/src/thread.c
index 3793896..c555d1f 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -3,8 +3,10 @@
 
 #include "prelude.h"
 #include "thread.h"
+
 #include "bfstd.h"
 #include "diag.h"
+
 #include <errno.h>
 #include <pthread.h>
 
diff --git a/src/thread.h b/src/thread.h
index dbf11ce..7ecda86 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -9,6 +9,7 @@
 #define BFS_THREAD_H
 
 #include "prelude.h"
+
 #include <pthread.h>
 
 /** Thread entry point type. */
diff --git a/src/trie.c b/src/trie.c
index 1c4ac77..848f172 100644
--- a/src/trie.c
+++ b/src/trie.c
@@ -83,10 +83,13 @@
 
 #include "prelude.h"
 #include "trie.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bit.h"
 #include "diag.h"
 #include "list.h"
+
 #include <stdint.h>
 #include <string.h>
 
diff --git a/src/trie.h b/src/trie.h
index 4288d76..8f7f94b 100644
--- a/src/trie.h
+++ b/src/trie.h
@@ -6,6 +6,7 @@
 
 #include "alloc.h"
 #include "list.h"
+
 #include <stddef.h>
 #include <stdint.h>
 
diff --git a/src/typo.c b/src/typo.c
index b1c5c44..7b359c4 100644
--- a/src/typo.c
+++ b/src/typo.c
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: 0BSD
 
 #include "typo.h"
+
 #include <limits.h>
 #include <stdint.h>
 #include <stdlib.h>
diff --git a/src/version.c b/src/version.c
index 8383350..2822927 100644
--- a/src/version.c
+++ b/src/version.c
@@ -3,6 +3,8 @@
 
 #include "prelude.h"
 
+#include "bfs.h"
+
 const char bfs_version[] = {
 #include "version.i"
 };
diff --git a/src/xregex.c b/src/xregex.c
index 2d089b2..52f8222 100644
--- a/src/xregex.c
+++ b/src/xregex.c
@@ -3,11 +3,14 @@
 
 #include "prelude.h"
 #include "xregex.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "diag.h"
 #include "sanity.h"
 #include "thread.h"
+
 #include <errno.h>
 #include <pthread.h>
 #include <stdlib.h>
diff --git a/src/xspawn.c b/src/xspawn.c
index 2385a6e..0b83c8d 100644
--- a/src/xspawn.c
+++ b/src/xspawn.c
@@ -3,10 +3,13 @@
 
 #include "prelude.h"
 #include "xspawn.h"
+
 #include "alloc.h"
+#include "bfs.h"
 #include "bfstd.h"
 #include "diag.h"
 #include "list.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
diff --git a/src/xspawn.h b/src/xspawn.h
index 05dcf99..60ef1ab 100644
--- a/src/xspawn.h
+++ b/src/xspawn.h
@@ -9,6 +9,7 @@
 #define BFS_XSPAWN_H
 
 #include "prelude.h"
+
 #include <sys/resource.h>
 #include <sys/types.h>
 #include <unistd.h>
diff --git a/src/xtime.c b/src/xtime.c
index 4828119..75ace72 100644
--- a/src/xtime.c
+++ b/src/xtime.c
@@ -3,8 +3,11 @@
 
 #include "prelude.h"
 #include "xtime.h"
+
+#include "bfs.h"
 #include "bfstd.h"
 #include "diag.h"
+
 #include <errno.h>
 #include <limits.h>
 #include <sys/time.h>
diff --git a/tests/alloc.c b/tests/alloc.c
index 2d3077d..ec8e8f7 100644
--- a/tests/alloc.c
+++ b/tests/alloc.c
@@ -3,8 +3,10 @@
 
 #include "prelude.h"
 #include "tests.h"
+
 #include "alloc.h"
 #include "diag.h"
+
 #include <errno.h>
 #include <stdlib.h>
 #include <stdint.h>
diff --git a/tests/bfstd.c b/tests/bfstd.c
index e59ac34..068e371 100644
--- a/tests/bfstd.c
+++ b/tests/bfstd.c
@@ -3,8 +3,10 @@
 
 #include "prelude.h"
 #include "tests.h"
+
 #include "bfstd.h"
 #include "diag.h"
+
 #include <errno.h>
 #include <langinfo.h>
 #include <stdlib.h>
diff --git a/tests/bit.c b/tests/bit.c
index 125f274..854398c 100644
--- a/tests/bit.c
+++ b/tests/bit.c
@@ -2,9 +2,12 @@
 // SPDX-License-Identifier: 0BSD
 
 #include "prelude.h"
-#include "tests.h"
+
+#include "bfs.h"
 #include "bit.h"
 #include "diag.h"
+#include "tests.h"
+
 #include <limits.h>
 #include <stdint.h>
 #include <string.h>
diff --git a/tests/ioq.c b/tests/ioq.c
index 4e1209e..61a924f 100644
--- a/tests/ioq.c
+++ b/tests/ioq.c
@@ -3,10 +3,12 @@
 
 #include "prelude.h"
 #include "tests.h"
-#include "ioq.h"
+
 #include "bfstd.h"
 #include "diag.h"
 #include "dir.h"
+#include "ioq.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
diff --git a/tests/list.c b/tests/list.c
index 822077e..820fbe4 100644
--- a/tests/list.c
+++ b/tests/list.c
@@ -2,8 +2,10 @@
 // SPDX-License-Identifier: 0BSD
 
 #include "prelude.h"
-#include "tests.h"
+
+#include "bfs.h"
 #include "list.h"
+#include "tests.h"
 
 struct item {
 	int n;
diff --git a/tests/main.c b/tests/main.c
index e4d9e61..9cbdcfb 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -7,8 +7,10 @@
 
 #include "prelude.h"
 #include "tests.h"
+
 #include "bfstd.h"
 #include "color.h"
+
 #include <locale.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/tests/mksock.c b/tests/mksock.c
index 5786cb6..f46df96 100644
--- a/tests/mksock.c
+++ b/tests/mksock.c
@@ -7,6 +7,7 @@
  */
 
 #include "bfstd.h"
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/tests/sighook.c b/tests/sighook.c
index f1c4c27..adc53d8 100644
--- a/tests/sighook.c
+++ b/tests/sighook.c
@@ -3,9 +3,11 @@
 
 #include "prelude.h"
 #include "tests.h"
-#include "sighook.h"
+
 #include "atomic.h"
 #include "thread.h"
+#include "sighook.h"
+
 #include <errno.h>
 #include <pthread.h>
 #include <signal.h>
diff --git a/tests/tests.h b/tests/tests.h
index 01d6096..2c1eb3a 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -9,6 +9,7 @@
 #define BFS_TESTS_H
 
 #include "prelude.h"
+
 #include "bfstd.h"
 #include "diag.h"
 
diff --git a/tests/trie.c b/tests/trie.c
index f380613..41b729e 100644
--- a/tests/trie.c
+++ b/tests/trie.c
@@ -2,9 +2,12 @@
 // SPDX-License-Identifier: 0BSD
 
 #include "prelude.h"
+
+#include "bfs.h"
+#include "diag.h"
 #include "tests.h"
 #include "trie.h"
-#include "diag.h"
+
 #include <stdlib.h>
 #include <string.h>
 
diff --git a/tests/xspawn.c b/tests/xspawn.c
index d77a078..20617de 100644
--- a/tests/xspawn.c
+++ b/tests/xspawn.c
@@ -3,10 +3,12 @@
 
 #include "prelude.h"
 #include "tests.h"
+
 #include "alloc.h"
 #include "bfstd.h"
 #include "dstring.h"
 #include "xspawn.h"
+
 #include <stdlib.h>
 #include <string.h>
 #include <sys/wait.h>
diff --git a/tests/xtime.c b/tests/xtime.c
index ea9e372..6d7716d 100644
--- a/tests/xtime.c
+++ b/tests/xtime.c
@@ -2,10 +2,13 @@
 // SPDX-License-Identifier: 0BSD
 
 #include "prelude.h"
-#include "tests.h"
-#include "xtime.h"
+
+#include "bfs.h"
 #include "bfstd.h"
 #include "diag.h"
+#include "tests.h"
+#include "xtime.h"
+
 #include <errno.h>
 #include <limits.h>
 #include <stdint.h>
diff --git a/tests/xtouch.c b/tests/xtouch.c
index 8660ea5..705d4e2 100644
--- a/tests/xtouch.c
+++ b/tests/xtouch.c
@@ -2,9 +2,11 @@
 // SPDX-License-Identifier: 0BSD
 
 #include "prelude.h"
+
 #include "bfstd.h"
 #include "sanity.h"
 #include "xtime.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
-- 
cgit v1.2.3