From 9463fdd30d392c98de7b5712d30dfbaeada40e99 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 25 Jan 2023 16:14:11 -0500 Subject: Replace license boilerplate with SPDX tags And while I'm at it, remove years from copyright declarations. Link: https://spdx.dev/about/ Link: https://daniel.haxx.se/blog/2023/01/08/copyright-without-years/ --- src/xregex.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'src/xregex.c') diff --git a/src/xregex.c b/src/xregex.c index 6f0e5a1..5f5480f 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -1,18 +1,5 @@ -/**************************************************************************** - * bfs * - * Copyright (C) 2022 Tavian Barnes * - * * - * Permission to use, copy, modify, and/or distribute this software for any * - * purpose with or without fee is hereby granted. * - * * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ****************************************************************************/ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD #include "xregex.h" #include "config.h" -- cgit v1.2.3 From 7e5357a1cf40ebaa7ffaeebfd3a88c3ba93eb1a7 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 3 May 2023 09:29:19 -0400 Subject: style: Don't use tabs to indent preprocessor directives --- src/bfstd.c | 6 ++--- src/bfstd.h | 32 +++++++++++------------ src/config.h | 84 ++++++++++++++++++++++++++++++------------------------------ src/dir.c | 20 +++++++-------- src/eval.c | 22 ++++++++-------- src/fsade.c | 8 +++--- src/fsade.h | 8 +++--- src/mtab.c | 20 +++++++-------- src/printf.c | 8 +++--- src/stat.c | 10 ++++---- src/stat.h | 8 +++--- src/trie.c | 30 +++++++++++----------- src/xregex.c | 28 ++++++++++---------- src/xspawn.c | 2 +- 14 files changed, 143 insertions(+), 143 deletions(-) (limited to 'src/xregex.c') diff --git a/src/bfstd.c b/src/bfstd.c index bc31288..1dc322b 100644 --- a/src/bfstd.c +++ b/src/bfstd.c @@ -19,13 +19,13 @@ #include #if BFS_USE_SYS_SYSMACROS_H -# include +# include #elif BFS_USE_SYS_MKDEV_H -# include +# include #endif #if BFS_USE_UTIL_H -# include +# include #endif bool is_nonexistence_error(int error) { diff --git a/src/bfstd.h b/src/bfstd.h index f85b74f..028e4e6 100644 --- a/src/bfstd.h +++ b/src/bfstd.h @@ -21,29 +21,29 @@ bool is_nonexistence_error(int error); #include #ifndef O_EXEC -# ifdef O_PATH -# define O_EXEC O_PATH -# else -# define O_EXEC O_RDONLY -# endif +# ifdef O_PATH +# define O_EXEC O_PATH +# else +# define O_EXEC O_RDONLY +# endif #endif #ifndef O_SEARCH -# ifdef O_PATH -# define O_SEARCH O_PATH -# else -# define O_SEARCH O_RDONLY -# endif +# ifdef O_PATH +# define O_SEARCH O_PATH +# else +# define O_SEARCH O_RDONLY +# endif #endif #ifndef O_DIRECTORY -# define O_DIRECTORY 0 +# define O_DIRECTORY 0 #endif #include #if !defined(FNM_CASEFOLD) && defined(FNM_IGNORECASE) -# define FNM_CASEFOLD FNM_IGNORECASE +# define FNM_CASEFOLD FNM_IGNORECASE #endif // #include @@ -144,10 +144,10 @@ int xminor(dev_t dev); // #include #if __APPLE__ -# define st_atim st_atimespec -# define st_ctim st_ctimespec -# define st_mtim st_mtimespec -# define st_birthtim st_birthtimespec +# define st_atim st_atimespec +# define st_ctim st_ctimespec +# define st_mtim st_mtimespec +# define st_birthtim st_birthtimespec #endif // #include diff --git a/src/config.h b/src/config.h index 34ae11d..5f54250 100644 --- a/src/config.h +++ b/src/config.h @@ -14,13 +14,13 @@ // bfs packaging configuration #ifndef BFS_COMMAND -# define BFS_COMMAND "bfs" +# define BFS_COMMAND "bfs" #endif #ifndef BFS_VERSION -# define BFS_VERSION "2.6.3" +# define BFS_VERSION "2.6.3" #endif #ifndef BFS_HOMEPAGE -# define BFS_HOMEPAGE "https://tavianator.com/projects/bfs.html" +# define BFS_HOMEPAGE "https://tavianator.com/projects/bfs.html" #endif // Check for system headers @@ -28,34 +28,34 @@ #ifdef __has_include #if __has_include() -# define BFS_HAS_MNTENT_H true +# define BFS_HAS_MNTENT_H true #endif #if __has_include() -# define BFS_HAS_PATHS_H true +# define BFS_HAS_PATHS_H true #endif #if __has_include() -# define BFS_HAS_SYS_ACL_H true +# define BFS_HAS_SYS_ACL_H true #endif #if __has_include() -# define BFS_HAS_SYS_CAPABILITY_H true +# define BFS_HAS_SYS_CAPABILITY_H true #endif #if __has_include() -# define BFS_HAS_SYS_EXTATTR_H true +# define BFS_HAS_SYS_EXTATTR_H true #endif #if __has_include() -# define BFS_HAS_SYS_MKDEV_H true +# define BFS_HAS_SYS_MKDEV_H true #endif #if __has_include() -# define BFS_HAS_SYS_PARAM_H true +# define BFS_HAS_SYS_PARAM_H true #endif #if __has_include() -# define BFS_HAS_SYS_SYSMACROS_H true +# define BFS_HAS_SYS_SYSMACROS_H true #endif #if __has_include() -# define BFS_HAS_SYS_XATTR_H true +# define BFS_HAS_SYS_XATTR_H true #endif #if __has_include() -# define BFS_HAS_UTIL_H true +# define BFS_HAS_UTIL_H true #endif #else // !__has_include @@ -74,59 +74,59 @@ #endif // !__has_include #ifndef BFS_USE_MNTENT_H -# define BFS_USE_MNTENT_H BFS_HAS_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 +# 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 +# define BFS_USE_SYS_ACL_H BFS_HAS_SYS_ACL_H #endif #ifndef BFS_USE_SYS_CAPABILITY_H -# define BFS_USE_SYS_CAPABILITY_H BFS_HAS_SYS_CAPABILITY_H +# define BFS_USE_SYS_CAPABILITY_H BFS_HAS_SYS_CAPABILITY_H #endif #ifndef BFS_USE_SYS_EXTATTR_H -# define BFS_USE_SYS_EXTATTR_H BFS_HAS_SYS_EXTATTR_H +# define BFS_USE_SYS_EXTATTR_H BFS_HAS_SYS_EXTATTR_H #endif #ifndef BFS_USE_SYS_MKDEV_H -# define BFS_USE_SYS_MKDEV_H BFS_HAS_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 +# 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 +# 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 +# define BFS_USE_SYS_XATTR_H BFS_HAS_SYS_XATTR_H #endif #ifndef BFS_USE_UTIL_H -# define BFS_USE_UTIL_H BFS_HAS_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 +# define __has_feature(feat) false #endif #ifndef __has_c_attribute -# define __has_c_attribute(attr) false +# define __has_c_attribute(attr) false #endif #ifndef __has_attribute -# define __has_attribute(attr) false +# define __has_attribute(attr) false #endif // Platform detection // Get the definition of BSD if available #if BFS_USE_SYS_PARAM_H -# include +# include #endif #ifndef __GLIBC_PREREQ -# define __GLIBC_PREREQ(maj, min) false +# define __GLIBC_PREREQ(maj, min) false #endif // Wrappers for fundamental language features/extensions @@ -135,11 +135,11 @@ * Silence compiler warnings about switch/case fall-throughs. */ #if __has_c_attribute(fallthrough) -# define BFS_FALLTHROUGH [[fallthrough]] +# define BFS_FALLTHROUGH [[fallthrough]] #elif __has_attribute(fallthrough) -# define BFS_FALLTHROUGH __attribute__((fallthrough)) +# define BFS_FALLTHROUGH __attribute__((fallthrough)) #else -# define BFS_FALLTHROUGH ((void)0) +# define BFS_FALLTHROUGH ((void)0) #endif /** @@ -173,40 +173,40 @@ * Adds compiler warnings for bad printf()-style function calls, if supported. */ #if __has_attribute(format) -# define BFS_FORMATTER(fmt, args) __attribute__((format(printf, fmt, args))) +# define BFS_FORMATTER(fmt, args) __attribute__((format(printf, fmt, args))) #else -# define BFS_FORMATTER(fmt, args) +# define BFS_FORMATTER(fmt, args) #endif /** * Check if function multiversioning via GNU indirect functions (ifunc) is supported. */ #if !defined(BFS_TARGET_CLONES) && __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__ || __NetBSD__) -# define BFS_TARGET_CLONES true +# define BFS_TARGET_CLONES true #endif /** * Ignore a particular GCC warning for a region of code. */ #if __GNUC__ -# define BFS_PRAGMA_STRINGIFY(...) _Pragma(#__VA_ARGS__) -# define BFS_SUPPRESS(warning) \ - _Pragma("GCC diagnostic push"); \ +# define BFS_PRAGMA_STRINGIFY(...) _Pragma(#__VA_ARGS__) +# define BFS_SUPPRESS(warning) \ + _Pragma("GCC diagnostic push"); \ BFS_PRAGMA_STRINGIFY(GCC diagnostic ignored warning) -# define BFS_UNSUPPRESS() \ +# define BFS_UNSUPPRESS() \ _Pragma("GCC diagnostic pop") #else -# define BFS_SUPPRESS(warning) -# define BFS_UNSUPPRESS() +# define BFS_SUPPRESS(warning) +# define BFS_UNSUPPRESS() #endif /** * Initialize a variable, unless sanitizers would detect uninitialized uses. */ #if __has_feature(memory_sanitizer) -# define BFS_UNINIT(var, value) var = var +# define BFS_UNINIT(var, value) var = var #else -# define BFS_UNINIT(var, value) var = value +# define BFS_UNINIT(var, value) var = value #endif #endif // BFS_CONFIG_H diff --git a/src/dir.c b/src/dir.c index 2719c15..eb6e3e0 100644 --- a/src/dir.c +++ b/src/dir.c @@ -16,16 +16,16 @@ #include #ifndef BFS_GETDENTS -# define BFS_GETDENTS (__linux__ || __FreeBSD__) +# define BFS_GETDENTS (__linux__ || __FreeBSD__) #endif #if BFS_GETDENTS -# if __has_feature(memory_sanitizer) -# include -# endif -# if __linux__ -# include -# endif +# if __has_feature(memory_sanitizer) +# include +# endif +# if __linux__ +# include +# endif /** getdents() syscall wrapper. */ static ssize_t bfs_getdents(int fd, void *buf, size_t size) { @@ -119,10 +119,10 @@ struct bfs_dir { }; #if BFS_GETDENTS -# define DIR_SIZE (64 << 10) -# define BUF_SIZE (DIR_SIZE - sizeof(struct bfs_dir)) +# define DIR_SIZE (64 << 10) +# define BUF_SIZE (DIR_SIZE - sizeof(struct bfs_dir)) #else -# define DIR_SIZE sizeof(struct bfs_dir) +# define DIR_SIZE sizeof(struct bfs_dir) #endif struct bfs_dir *bfs_opendir(int at_fd, const char *at_path) { diff --git a/src/eval.c b/src/eval.c index 53ce605..687ba32 100644 --- a/src/eval.c +++ b/src/eval.c @@ -943,9 +943,9 @@ bool eval_xtype(const struct bfs_expr *expr, struct bfs_eval *state) { } #if _POSIX_MONOTONIC_CLOCK > 0 -# define BFS_CLOCK CLOCK_MONOTONIC +# define BFS_CLOCK CLOCK_MONOTONIC #elif _POSIX_TIMERS > 0 -# define BFS_CLOCK CLOCK_REALTIME +# define BFS_CLOCK CLOCK_REALTIME #endif /** @@ -1194,15 +1194,15 @@ static bool eval_file_unique(struct bfs_eval *state, struct trie *seen) { } } -#define DEBUG_FLAG(flags, flag) \ - do { \ - if ((flags & flag) || flags == flag) { \ - fputs(#flag, stderr); \ - flags ^= flag; \ - if (flags) { \ - fputs(" | ", stderr); \ - } \ - } \ +#define DEBUG_FLAG(flags, flag) \ + do { \ + if ((flags & flag) || flags == flag) { \ + fputs(#flag, stderr); \ + flags ^= flag; \ + if (flags) { \ + fputs(" | ", stderr); \ + } \ + } \ } while (0) /** diff --git a/src/fsade.c b/src/fsade.c index a61a6b8..aefbb75 100644 --- a/src/fsade.c +++ b/src/fsade.c @@ -13,17 +13,17 @@ #include #if BFS_CAN_CHECK_ACL -# include +# include #endif #if BFS_CAN_CHECK_CAPABILITIES -# include +# include #endif #if BFS_USE_SYS_EXTATTR_H -# include +# include #elif BFS_USE_SYS_XATTR_H -# include +# include #endif #if BFS_CAN_CHECK_ACL || BFS_CAN_CHECK_CAPABILITIES || BFS_CAN_CHECK_XATTRS diff --git a/src/fsade.h b/src/fsade.h index 9bef892..557da26 100644 --- a/src/fsade.h +++ b/src/fsade.h @@ -15,10 +15,10 @@ #define BFS_CAN_CHECK_ACL BFS_USE_SYS_ACL_H #if !defined(BFS_CAN_CHECK_CAPABILITIES) && BFS_USE_SYS_CAPABILITY_H && !__FreeBSD__ -# include -# ifdef CAP_CHOWN -# define BFS_CAN_CHECK_CAPABILITIES true -# endif +# include +# ifdef CAP_CHOWN +# define BFS_CAN_CHECK_CAPABILITIES true +# endif #endif #define BFS_CAN_CHECK_XATTRS (BFS_USE_SYS_EXTATTR_H || BFS_USE_SYS_XATTR_H) diff --git a/src/mtab.c b/src/mtab.c index 0e377a1..27f1743 100644 --- a/src/mtab.c +++ b/src/mtab.c @@ -15,23 +15,23 @@ #include #if BFS_USE_MNTENT_H -# define BFS_MNTENT 1 +# define BFS_MNTENT 1 #elif BSD -# define BFS_MNTINFO 1 +# define BFS_MNTINFO 1 #elif __SVR4 -# define BFS_MNTTAB 1 +# define BFS_MNTTAB 1 #endif #if BFS_MNTENT -# include -# include -# include +# include +# include +# include #elif BFS_MNTINFO -# include -# include +# include +# include #elif BFS_MNTTAB -# include -# include +# include +# include #endif /** diff --git a/src/printf.c b/src/printf.c index 1b4f2d4..726d54d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -72,10 +72,10 @@ static bool should_color(CFILE *cfile, const struct bfs_printf *directive) { /** * Print a value to a temporary buffer before formatting it. */ -#define BFS_PRINTF_BUF(buf, format, ...) \ - char buf[256]; \ - int ret = snprintf(buf, sizeof(buf), format, __VA_ARGS__); \ - assert(ret >= 0 && (size_t)ret < sizeof(buf)); \ +#define BFS_PRINTF_BUF(buf, format, ...) \ + char buf[256]; \ + int ret = snprintf(buf, sizeof(buf), format, __VA_ARGS__); \ + assert(ret >= 0 && (size_t)ret < sizeof(buf)); \ (void)ret /** diff --git a/src/stat.c b/src/stat.c index aaa5eac..f3d9046 100644 --- a/src/stat.c +++ b/src/stat.c @@ -13,15 +13,15 @@ #include #if defined(STATX_BASIC_STATS) && (!__ANDROID__ || __ANDROID_API__ >= 30) -# define BFS_LIBC_STATX true +# define BFS_LIBC_STATX true #elif __linux__ -# include -# include -# include +# include +# include +# include #endif #if BFS_LIBC_STATX || defined(__NR_statx) -# define BFS_STATX true +# define BFS_STATX true #endif const char *bfs_stat_field_name(enum bfs_stat_field field) { diff --git a/src/stat.h b/src/stat.h index 7a70146..e08dd4d 100644 --- a/src/stat.h +++ b/src/stat.h @@ -17,7 +17,7 @@ #include #if BFS_USE_SYS_PARAM_H -# include +# include #endif /** @@ -61,11 +61,11 @@ enum bfs_stat_flags { }; #ifdef DEV_BSIZE -# define BFS_STAT_BLKSIZE DEV_BSIZE +# define BFS_STAT_BLKSIZE DEV_BSIZE #elif defined(S_BLKSIZE) -# define BFS_STAT_BLKSIZE S_BLKSIZE +# define BFS_STAT_BLKSIZE S_BLKSIZE #else -# define BFS_STAT_BLKSIZE 512 +# define BFS_STAT_BLKSIZE 512 #endif /** diff --git a/src/trie.c b/src/trie.c index 43df9dc..9f2e45f 100644 --- a/src/trie.c +++ b/src/trie.c @@ -94,9 +94,9 @@ static_assert(CHAR_BIT == 8, "This trie implementation assumes 8-bit bytes."); #if BFS_TARGET_CLONES && (__i386__ || __x86_64__) -# define TARGET_CLONES_POPCNT __attribute__((target_clones("popcnt", "default"))) +# define TARGET_CLONES_POPCNT __attribute__((target_clones("popcnt", "default"))) #else -# define TARGET_CLONES_POPCNT +# define TARGET_CLONES_POPCNT #endif /** Number of bits for the sparse array bitmap, aka the range of a nibble. */ @@ -367,23 +367,23 @@ static size_t trie_node_size(unsigned int size) { } #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define TRIE_BSWAP(n) (n) +# define TRIE_BSWAP(n) (n) #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# if __SIZEOF_SIZE_T__ == 8 -# define TRIE_BSWAP(n) __builtin_bswap64(n) -# elif __SIZEOF_SIZE_T__ == 4 -# define TRIE_BSWAP(n) __builtin_bswap32(n) -# endif +# if __SIZEOF_SIZE_T__ == 8 +# define TRIE_BSWAP(n) __builtin_bswap64(n) +# elif __SIZEOF_SIZE_T__ == 4 +# define TRIE_BSWAP(n) __builtin_bswap32(n) +# endif #endif #ifdef TRIE_BSWAP -# if __SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__ -# define TRIE_CTZ(n) __builtin_ctzll(n) -# elif __SIZEOF_SIZE_T__ == __SIZEOF_LONG__ -# define TRIE_CTZ(n) __builtin_ctzl(n) -# elif __SIZEOF_SIZE_T__ == __SIZEOF_INT__ -# define TRIE_CTZ(n) __builtin_ctz(n) -# endif +# if __SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__ +# define TRIE_CTZ(n) __builtin_ctzll(n) +# elif __SIZEOF_SIZE_T__ == __SIZEOF_LONG__ +# define TRIE_CTZ(n) __builtin_ctzl(n) +# elif __SIZEOF_SIZE_T__ == __SIZEOF_INT__ +# define TRIE_CTZ(n) __builtin_ctz(n) +# endif #endif /** Find the offset of the first nibble that differs between two keys. */ diff --git a/src/xregex.c b/src/xregex.c index 5f5480f..a7153b7 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -9,10 +9,10 @@ #include #if BFS_WITH_ONIGURUMA -# include -# include +# include +# include #else -# include +# include #endif struct bfs_regex { @@ -43,20 +43,20 @@ static int bfs_onig_encoding(OnigEncoding *penc) { // from the current locale. const char *charmap = nl_langinfo(CODESET); if (charmap) { -#define BFS_MAP_ENCODING(name, value) \ - do { \ - if (strcmp(charmap, name) == 0) { \ - enc = value; \ - } \ +#define BFS_MAP_ENCODING(name, value) \ + do { \ + if (strcmp(charmap, name) == 0) { \ + enc = value; \ + } \ } while (0) -#define BFS_MAP_ENCODING2(name1, name2, value) \ - do { \ - BFS_MAP_ENCODING(name1, value); \ - BFS_MAP_ENCODING(name2, value); \ +#define BFS_MAP_ENCODING2(name1, name2, value) \ + do { \ + BFS_MAP_ENCODING(name1, value); \ + BFS_MAP_ENCODING(name2, value); \ } while (0) // These names were found with locale -m on Linux and FreeBSD -#define BFS_MAP_ISO_8859(n) \ +#define BFS_MAP_ISO_8859(n) \ BFS_MAP_ENCODING2("ISO-8859-" #n, "ISO8859-" #n, ONIG_ENCODING_ISO_8859_ ## n) BFS_MAP_ISO_8859(1); @@ -78,7 +78,7 @@ static int bfs_onig_encoding(OnigEncoding *penc) { BFS_MAP_ENCODING("UTF-8", ONIG_ENCODING_UTF8); -#define BFS_MAP_EUC(name) \ +#define BFS_MAP_EUC(name) \ BFS_MAP_ENCODING2("EUC-" #name, "euc" #name, ONIG_ENCODING_EUC_ ## name) BFS_MAP_EUC(JP); diff --git a/src/xspawn.c b/src/xspawn.c index a185200..a6d18a3 100644 --- a/src/xspawn.c +++ b/src/xspawn.c @@ -16,7 +16,7 @@ #include #if BFS_USE_PATHS_H -# include +# include #endif /** -- cgit v1.2.3 From 526133c11eb9a26a4cffb20bcd10bcbb36d940de Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 18 May 2023 16:44:30 -0400 Subject: Switch from assert() to bfs_assert()/bfs_verify() --- src/bfstd.c | 3 +- src/bftw.c | 28 ++++++++-------- src/color.c | 5 ++- src/diag.c | 3 +- src/dir.c | 4 +-- src/eval.c | 11 +++---- src/exec.c | 7 ++-- src/opt.c | 13 ++++---- src/parse.c | 7 ++-- src/printf.c | 5 ++- src/trie.c | 33 ++++++++++--------- src/xregex.c | 4 +-- tests/bfstd.c | 13 ++++---- tests/bit.c | 100 +++++++++++++++++++++++++++++----------------------------- tests/trie.c | 56 ++++++++++++++++---------------- 15 files changed, 140 insertions(+), 152 deletions(-) (limited to 'src/xregex.c') diff --git a/src/bfstd.c b/src/bfstd.c index 91383a2..37f5276 100644 --- a/src/bfstd.c +++ b/src/bfstd.c @@ -5,7 +5,6 @@ #include "config.h" #include "diag.h" #include "xregex.h" -#include #include #include #include @@ -393,7 +392,7 @@ void close_quietly(int fd) { int xclose(int fd) { int ret = close(fd); if (ret != 0) { - assert(errno != EBADF); + bfs_verify(errno != EBADF); } return ret; } diff --git a/src/bftw.c b/src/bftw.c index 14805de..6ec5cfa 100644 --- a/src/bftw.c +++ b/src/bftw.c @@ -19,13 +19,13 @@ #include "bftw.h" #include "bfstd.h" #include "config.h" +#include "diag.h" #include "dir.h" #include "dstring.h" #include "list.h" #include "mtab.h" #include "stat.h" #include "trie.h" -#include #include #include #include @@ -114,7 +114,7 @@ static void bftw_cache_remove(struct bftw_cache *cache, struct bftw_file *file) /** Close a bftw_file. */ static void bftw_file_close(struct bftw_cache *cache, struct bftw_file *file) { - assert(file->fd >= 0); + bfs_assert(file->fd >= 0); if (LIST_ATTACHED(cache, file, lru)) { bftw_cache_remove(cache, file); @@ -137,7 +137,7 @@ static int bftw_cache_pop(struct bftw_cache *cache) { /** Add a bftw_file to the cache. */ static int bftw_cache_add(struct bftw_cache *cache, struct bftw_file *file) { - assert(file->fd >= 0); + bfs_assert(file->fd >= 0); if (cache->capacity == 0 && bftw_cache_pop(cache) != 0) { bftw_file_close(cache, file); @@ -145,7 +145,7 @@ static int bftw_cache_add(struct bftw_cache *cache, struct bftw_file *file) { return -1; } - assert(cache->capacity > 0); + bfs_assert(cache->capacity > 0); --cache->capacity; LIST_INSERT(cache, cache->target, file, lru); @@ -169,9 +169,9 @@ static size_t bftw_child_nameoff(const struct bftw_file *parent) { /** Destroy a cache. */ static void bftw_cache_destroy(struct bftw_cache *cache) { - assert(!cache->head); - assert(!cache->tail); - assert(!cache->target); + bfs_assert(!cache->head); + bfs_assert(!cache->tail); + bfs_assert(!cache->target); } /** Create a new bftw_file. */ @@ -230,7 +230,7 @@ static struct bftw_file *bftw_file_new(struct bftw_file *parent, const char *nam * The opened file descriptor, or negative on error. */ static int bftw_file_openat(struct bftw_cache *cache, struct bftw_file *file, struct bftw_file *base, const char *at_path) { - assert(file->fd < 0); + bfs_assert(file->fd < 0); int at_fd = AT_FDCWD; if (base) { @@ -332,7 +332,7 @@ static struct bfs_dir *bftw_file_opendir(struct bftw_cache *cache, struct bftw_f /** Free a bftw_file. */ static void bftw_file_free(struct bftw_cache *cache, struct bftw_file *file) { - assert(file->refcount == 0); + bfs_assert(file->refcount == 0); if (file->fd >= 0) { bftw_file_close(cache, file); @@ -770,7 +770,7 @@ static enum bftw_action bftw_call_back(struct bftw_state *state, const char *nam /** Pop a directory to read from the queue. */ static bool bftw_pop_dir(struct bftw_state *state) { - assert(!state->file); + bfs_assert(!state->file); if (!state->dirs.head) { return false; @@ -787,7 +787,7 @@ static bool bftw_pop_dir(struct bftw_state *state) { /** Pop a file to visit from the queue. */ static bool bftw_pop_file(struct bftw_state *state) { - assert(!state->file); + bfs_assert(!state->file); state->file = state->files.head; if (state->file) { @@ -802,8 +802,8 @@ static bool bftw_pop_file(struct bftw_state *state) { * Open the current directory. */ static int bftw_opendir(struct bftw_state *state) { - assert(!state->dir); - assert(!state->de); + bfs_assert(!state->dir); + bfs_assert(!state->de); state->direrror = 0; @@ -863,7 +863,7 @@ static int bftw_gc(struct bftw_state *state, enum bftw_gc_flags flags) { if (state->dir) { struct bftw_file *file = state->file; - assert(file && file->fd >= 0); + bfs_assert(file && file->fd >= 0); if (file->refcount > 1) { // Keep the fd around if any subdirectories exist diff --git a/src/color.c b/src/color.c index 43ea9a4..a723084 100644 --- a/src/color.c +++ b/src/color.c @@ -12,7 +12,6 @@ #include "fsade.h" #include "stat.h" #include "trie.h" -#include #include #include #include @@ -699,7 +698,7 @@ static int print_colored(CFILE *cfile, const char *esc, const char *str, size_t /** Find the offset of the first broken path component. */ static ssize_t first_broken_offset(const char *path, const struct BFTW *ftwbuf, enum bfs_stat_flags flags, size_t max) { ssize_t ret = max; - assert(ret >= 0); + bfs_assert(ret >= 0); if (bftw_type(ftwbuf, flags) != BFS_ERROR) { goto out; @@ -1100,7 +1099,7 @@ static int cbuff(CFILE *cfile, const char *format, ...) { } int cvfprintf(CFILE *cfile, const char *format, va_list args) { - assert(dstrlen(cfile->buffer) == 0); + bfs_assert(dstrlen(cfile->buffer) == 0); int ret = -1; if (cvbuff(cfile, format, args) == 0) { diff --git a/src/diag.c b/src/diag.c index d7ffaa6..04e3678 100644 --- a/src/diag.c +++ b/src/diag.c @@ -6,7 +6,6 @@ #include "ctx.h" #include "color.h" #include "expr.h" -#include #include #include #include @@ -117,7 +116,7 @@ static bool highlight_expr_recursive(const struct bfs_ctx *ctx, const struct bfs for (size_t i = 0; i < ctx->argc; ++i) { if (&ctx->argv[i] == expr->argv) { for (size_t j = 0; j < expr->argc; ++j) { - assert(i + j < ctx->argc); + bfs_assert(i + j < ctx->argc); args[i + j] = true; ret = true; } diff --git a/src/dir.c b/src/dir.c index 6739f10..d9ee63b 100644 --- a/src/dir.c +++ b/src/dir.c @@ -4,7 +4,7 @@ #include "dir.h" #include "bfstd.h" #include "config.h" -#include +#include "diag.h" #include #include #include @@ -249,7 +249,7 @@ int bfs_closedir(struct bfs_dir *dir) { int ret = xclose(dir->fd); #else int ret = closedir(dir->dir); - assert(ret == 0 || errno != EBADF); + bfs_verify(ret == 0 || errno != EBADF); #endif free(dir); return ret; diff --git a/src/eval.c b/src/eval.c index 6cad3a9..342debd 100644 --- a/src/eval.c +++ b/src/eval.c @@ -26,7 +26,6 @@ #include "trie.h" #include "xregex.h" #include "xtime.h" -#include #include #include #include @@ -990,7 +989,7 @@ static bool eval_expr(struct bfs_expr *expr, struct bfs_eval *state) { } } - assert(!state->quit); + bfs_assert(!state->quit); bool ret = expr->eval_fn(expr, state); @@ -1006,10 +1005,10 @@ static bool eval_expr(struct bfs_expr *expr, struct bfs_eval *state) { } if (bfs_expr_never_returns(expr)) { - assert(state->quit); + bfs_assert(state->quit); } else if (!state->quit) { - assert(!expr->always_true || ret); - assert(!expr->always_false || !ret); + bfs_assert(!expr->always_true || ret); + bfs_assert(!expr->always_false || !ret); } return ret; @@ -1511,7 +1510,7 @@ static void dump_bftw_flags(enum bftw_flags flags) { DEBUG_FLAG(flags, BFTW_SORT); DEBUG_FLAG(flags, BFTW_BUFFER); - assert(!flags); + bfs_assert(flags == 0, "Missing bftw flag 0x%X", flags); } /** diff --git a/src/exec.c b/src/exec.c index 7f22d36..5912ad6 100644 --- a/src/exec.c +++ b/src/exec.c @@ -10,7 +10,6 @@ #include "diag.h" #include "dstring.h" #include "xspawn.h" -#include #include #include #include @@ -276,12 +275,12 @@ static void bfs_exec_free_arg(char *arg, const char *tmpl) { /** Open a file to use as the working directory. */ static int bfs_exec_openwd(struct bfs_exec *execbuf, const struct BFTW *ftwbuf) { - assert(execbuf->wd_fd < 0); - assert(!execbuf->wd_path); + bfs_assert(execbuf->wd_fd < 0); + bfs_assert(!execbuf->wd_path); if (ftwbuf->at_fd != AT_FDCWD) { // Rely on at_fd being the immediate parent - assert(xbaseoff(ftwbuf->at_path) == 0); + bfs_assert(xbaseoff(ftwbuf->at_path) == 0); execbuf->wd_fd = ftwbuf->at_fd; if (!(execbuf->flags & BFS_EXEC_MULTI)) { diff --git a/src/opt.c b/src/opt.c index 4ce9425..4699af4 100644 --- a/src/opt.c +++ b/src/opt.c @@ -35,7 +35,6 @@ #include "exec.h" #include "expr.h" #include "pwcache.h" -#include #include #include #include @@ -308,7 +307,7 @@ struct opt_state { /** Log an optimization. */ BFS_FORMATTER(3, 4) static bool opt_debug(const struct opt_state *state, int level, const char *format, ...) { - assert(state->ctx->optlevel >= level); + bfs_assert(state->ctx->optlevel >= level); if (bfs_debug(state->ctx, DEBUG_OPT, "${cyn}-O%d${rs}: ", level)) { va_list args; @@ -387,7 +386,7 @@ static struct bfs_expr *de_morgan(const struct opt_state *state, struct bfs_expr has_parent = false; } - assert(expr->eval_fn == eval_and || expr->eval_fn == eval_or); + bfs_assert(expr->eval_fn == eval_and || expr->eval_fn == eval_or); if (expr->eval_fn == eval_and) { expr->eval_fn = eval_or; expr->argv = &fake_or_arg; @@ -446,7 +445,7 @@ static struct bfs_expr *optimize_expr_recursive(struct opt_state *state, struct * Optimize a negation. */ static struct bfs_expr *optimize_not_expr(const struct opt_state *state, struct bfs_expr *expr) { - assert(expr->eval_fn == eval_not); + bfs_assert(expr->eval_fn == eval_not); struct bfs_expr *rhs = expr->rhs; @@ -498,7 +497,7 @@ fail: /** Optimize a conjunction. */ static struct bfs_expr *optimize_and_expr(const struct opt_state *state, struct bfs_expr *expr) { - assert(expr->eval_fn == eval_and); + bfs_assert(expr->eval_fn == eval_and); struct bfs_expr *lhs = expr->lhs; struct bfs_expr *rhs = expr->rhs; @@ -569,7 +568,7 @@ fail: /** Optimize a disjunction. */ static struct bfs_expr *optimize_or_expr(const struct opt_state *state, struct bfs_expr *expr) { - assert(expr->eval_fn == eval_or); + bfs_assert(expr->eval_fn == eval_or); struct bfs_expr *lhs = expr->lhs; struct bfs_expr *rhs = expr->rhs; @@ -673,7 +672,7 @@ static struct bfs_expr *ignore_result(const struct opt_state *state, struct bfs_ /** Optimize a comma expression. */ static struct bfs_expr *optimize_comma_expr(const struct opt_state *state, struct bfs_expr *expr) { - assert(expr->eval_fn == eval_comma); + bfs_assert(expr->eval_fn == eval_comma); struct bfs_expr *lhs = expr->lhs; struct bfs_expr *rhs = expr->rhs; diff --git a/src/parse.c b/src/parse.c index 807892c..1a04e68 100644 --- a/src/parse.c +++ b/src/parse.c @@ -29,7 +29,6 @@ #include "xregex.h" #include "xspawn.h" #include "xtime.h" -#include #include #include #include @@ -134,7 +133,7 @@ static struct bfs_expr *new_unary_expr(bfs_eval_fn *eval_fn, struct bfs_expr *rh expr->lhs = NULL; expr->rhs = rhs; - assert(bfs_expr_is_parent(expr)); + bfs_assert(bfs_expr_is_parent(expr)); expr->persistent_fds = rhs->persistent_fds; expr->ephemeral_fds = rhs->ephemeral_fds; @@ -154,7 +153,7 @@ static struct bfs_expr *new_binary_expr(bfs_eval_fn *eval_fn, struct bfs_expr *l expr->lhs = lhs; expr->rhs = rhs; - assert(bfs_expr_is_parent(expr)); + bfs_assert(bfs_expr_is_parent(expr)); expr->persistent_fds = lhs->persistent_fds + rhs->persistent_fds; if (lhs->ephemeral_fds > rhs->ephemeral_fds) { @@ -263,7 +262,7 @@ static void init_highlight(const struct bfs_ctx *ctx, bool *args) { static void highlight_args(const struct bfs_ctx *ctx, char **argv, size_t argc, bool *args) { size_t i = argv - ctx->argv; for (size_t j = 0; j < argc; ++j) { - assert(i + j < ctx->argc); + bfs_assert(i + j < ctx->argc); args[i + j] = true; } } diff --git a/src/printf.c b/src/printf.c index 9ccc216..6520d2d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -16,7 +16,6 @@ #include "pwcache.h" #include "stat.h" #include "xtime.h" -#include #include #include #include @@ -74,7 +73,7 @@ static bool should_color(CFILE *cfile, const struct bfs_printf *directive) { #define BFS_PRINTF_BUF(buf, format, ...) \ char buf[256]; \ int ret = snprintf(buf, sizeof(buf), format, __VA_ARGS__); \ - assert(ret >= 0 && (size_t)ret < sizeof(buf)); \ + bfs_assert(ret >= 0 && (size_t)ret < sizeof(buf)); \ (void)ret /** @@ -190,7 +189,7 @@ static int bfs_printf_strftime(CFILE *cfile, const struct bfs_printf *directive, break; } - assert(ret >= 0 && (size_t)ret < sizeof(buf)); + bfs_assert(ret >= 0 && (size_t)ret < sizeof(buf)); (void)ret; return dyn_fprintf(cfile->file, directive, buf); diff --git a/src/trie.c b/src/trie.c index a2921de..8543eb1 100644 --- a/src/trie.c +++ b/src/trie.c @@ -86,7 +86,6 @@ #include "config.h" #include "diag.h" #include "list.h" -#include #include #include #include @@ -139,27 +138,27 @@ static bool trie_is_leaf(uintptr_t ptr) { /** Decode a pointer to a leaf. */ static struct trie_leaf *trie_decode_leaf(uintptr_t ptr) { - assert(trie_is_leaf(ptr)); + bfs_assert(trie_is_leaf(ptr)); return (struct trie_leaf *)(ptr ^ 1); } /** Encode a pointer to a leaf. */ static uintptr_t trie_encode_leaf(const struct trie_leaf *leaf) { uintptr_t ptr = (uintptr_t)leaf ^ 1; - assert(trie_is_leaf(ptr)); + bfs_assert(trie_is_leaf(ptr)); return ptr; } /** Decode a pointer to an internal node. */ static struct trie_node *trie_decode_node(uintptr_t ptr) { - assert(!trie_is_leaf(ptr)); + bfs_assert(!trie_is_leaf(ptr)); return (struct trie_node *)ptr; } /** Encode a pointer to an internal node. */ static uintptr_t trie_encode_node(const struct trie_node *node) { uintptr_t ptr = (uintptr_t)node; - assert(!trie_is_leaf(ptr)); + bfs_assert(!trie_is_leaf(ptr)); return ptr; } @@ -341,9 +340,9 @@ static void trie_leaf_free(struct trie *trie, struct trie_leaf *leaf) { /** Compute the size of a trie node with a certain number of children. */ static size_t trie_node_size(unsigned int size) { // Empty nodes aren't supported - assert(size > 0); + bfs_assert(size > 0); // Node size must be a power of two - assert(has_single_bit(size)); + bfs_assert(has_single_bit(size)); return flex_sizeof(struct trie_node, children, size); } @@ -435,7 +434,7 @@ static struct trie_leaf *trie_node_insert(struct trie *trie, uintptr_t *ptr, str unsigned int bit = 1U << nibble; // The child must not already be present - assert(!(node->bitmap & bit)); + bfs_assert(!(node->bitmap & bit)); node->bitmap |= bit; unsigned int target = count_ones(node->bitmap & (bit - 1)); @@ -474,7 +473,7 @@ static struct trie_leaf *trie_node_insert(struct trie *trie, uintptr_t *ptr, str static uintptr_t *trie_jump(uintptr_t *ptr, const char *key, size_t *offset) { // We only ever need to jump to leaf nodes, since internal nodes are // guaranteed to be within OFFSET_MAX anyway - assert(trie_is_leaf(*ptr)); + bfs_assert(trie_is_leaf(*ptr)); struct trie_node *node = malloc(trie_node_size(1)); if (!node) { @@ -512,7 +511,7 @@ static uintptr_t *trie_jump(uintptr_t *ptr, const char *key, size_t *offset) { static struct trie_leaf *trie_split(struct trie *trie, uintptr_t *ptr, struct trie_leaf *leaf, struct trie_leaf *rep, size_t offset, size_t mismatch) { unsigned char key_nibble = trie_key_nibble(leaf->key, mismatch); unsigned char rep_nibble = trie_key_nibble(rep->key, mismatch); - assert(key_nibble != rep_nibble); + bfs_assert(key_nibble != rep_nibble); struct trie_node *node = malloc(trie_node_size(2)); if (!node) { @@ -570,11 +569,11 @@ static struct trie_leaf *trie_insert_mem_impl(struct trie *trie, const void *key unsigned char nibble = trie_key_nibble(key, offset); unsigned int bit = 1U << nibble; if (node->bitmap & bit) { - assert(offset < mismatch); + bfs_assert(offset < mismatch); unsigned int index = count_ones(node->bitmap & (bit - 1)); ptr = &node->children[index]; } else { - assert(offset == mismatch); + bfs_assert(offset == mismatch); return trie_node_insert(trie, ptr, leaf, nibble); } } @@ -600,7 +599,7 @@ static void trie_free_singletons(struct trie *trie, uintptr_t ptr) { struct trie_node *node = trie_decode_node(ptr); // Make sure the bitmap is a power of two, i.e. it has just one child - assert(has_single_bit(node->bitmap)); + bfs_assert(has_single_bit(node->bitmap)); ptr = node->children[0]; free(node); @@ -651,12 +650,12 @@ static void trie_remove_impl(struct trie *trie, struct trie_leaf *leaf) { while (!trie_is_leaf(*child)) { struct trie_node *node = trie_decode_node(*child); offset += node->offset; - assert((offset >> 1) < leaf->length); + bfs_assert((offset >> 1) < leaf->length); unsigned char nibble = trie_key_nibble(leaf->key, offset); unsigned int bit = 1U << nibble; unsigned int bitmap = node->bitmap; - assert(bitmap & bit); + bfs_assert(bitmap & bit); unsigned int index = count_ones(bitmap & (bit - 1)); // Advance the parent pointer, unless this node had only one child @@ -669,7 +668,7 @@ static void trie_remove_impl(struct trie *trie, struct trie_leaf *leaf) { child = &node->children[index]; } - assert(trie_decode_leaf(*child) == leaf); + bfs_assert(trie_decode_leaf(*child) == leaf); if (!parent) { trie_free_singletons(trie, trie->root); @@ -683,7 +682,7 @@ static void trie_remove_impl(struct trie *trie, struct trie_leaf *leaf) { node->bitmap ^= child_bit; unsigned int parent_size = count_ones(node->bitmap); - assert(parent_size > 0); + bfs_assert(parent_size > 0); if (parent_size == 1 && trie_collapse_node(parent, node, child_index) == 0) { return; } diff --git a/src/xregex.c b/src/xregex.c index a7153b7..1143f23 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -3,7 +3,7 @@ #include "xregex.h" #include "config.h" -#include +#include "diag.h" #include #include #include @@ -140,7 +140,7 @@ int bfs_regcomp(struct bfs_regex **preg, const char *pattern, enum bfs_regex_typ syntax = ONIG_SYNTAX_GREP; break; } - assert(syntax); + bfs_assert(syntax); OnigOptionType options = syntax->options; if (flags & BFS_REGEX_ICASE) { diff --git a/tests/bfstd.c b/tests/bfstd.c index a986a23..1812a00 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -1,10 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD -#undef NDEBUG #include "../src/bfstd.h" #include "../src/config.h" -#include +#include "../src/diag.h" #include #include #include @@ -39,11 +38,11 @@ int main(void) { alignas(64) int foo; int bar[]; }; - assert(flex_sizeof(struct flexible, bar, 0) >= sizeof(struct flexible)); - assert(flex_sizeof(struct flexible, bar, 16) % alignof(struct flexible) == 0); - assert(flex_sizeof(struct flexible, bar, SIZE_MAX / sizeof(int) + 1) - == align_floor(alignof(struct flexible), SIZE_MAX)); - assert(flex_sizeof_impl(8, 16, 4, 4, 1) == 16); + bfs_verify(flex_sizeof(struct flexible, bar, 0) >= sizeof(struct flexible)); + bfs_verify(flex_sizeof(struct flexible, bar, 16) % alignof(struct flexible) == 0); + bfs_verify(flex_sizeof(struct flexible, bar, SIZE_MAX / sizeof(int) + 1) + == align_floor(alignof(struct flexible), SIZE_MAX)); + bfs_verify(flex_sizeof_impl(8, 16, 4, 4, 1) == 16); // From man 3p basename check_base_dir("usr", ".", "usr"); diff --git a/tests/bit.c b/tests/bit.c index 7a7b0f3..cb339f4 100644 --- a/tests/bit.c +++ b/tests/bit.c @@ -1,11 +1,8 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD -#undef NDEBUG - #include "../src/bit.h" #include "../src/diag.h" -#include #include #include #include @@ -54,68 +51,71 @@ 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)) + int main(void) { - assert(bswap((uint8_t)0x12) == 0x12); - assert(bswap((uint16_t)0x1234) == 0x3412); - assert(bswap((uint32_t)0x12345678) == 0x78563412); - assert(bswap((uint64_t)0x1234567812345678) == 0x7856341278563412); - - assert(count_ones(0x0) == 0); - assert(count_ones(0x1) == 1); - assert(count_ones(0x2) == 1); - assert(count_ones(0x3) == 2); - assert(count_ones(0x137F) == 10); - - assert(count_zeros(0) == INT_WIDTH); - assert(count_zeros(0L) == LONG_WIDTH); - assert(count_zeros(0LL) == LLONG_WIDTH); - assert(count_zeros((uint8_t)0) == 8); - assert(count_zeros((uint16_t)0) == 16); - assert(count_zeros((uint32_t)0) == 32); - assert(count_zeros((uint64_t)0) == 64); - - assert(rotate_left((uint8_t)0xA1, 4) == 0x1A); - assert(rotate_left((uint16_t)0x1234, 12) == 0x4123); - assert(rotate_left((uint32_t)0x12345678, 20) == 0x67812345); - assert(rotate_left((uint32_t)0x12345678, 0) == 0x12345678); - - assert(rotate_right((uint8_t)0xA1, 4) == 0x1A); - assert(rotate_right((uint16_t)0x1234, 12) == 0x2341); - assert(rotate_right((uint32_t)0x12345678, 20) == 0x45678123); - assert(rotate_right((uint32_t)0x12345678, 0) == 0x12345678); + 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); 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; - assert(count_ones(nm) == 1 + (n != m)); - assert(count_zeros(nm) == 15 - (n != m)); - assert(leading_zeros(nm) == 15 - j); - assert(trailing_zeros(nm) == i); - assert(first_leading_one(nm) == j + 1); - assert(first_trailing_one(nm) == i + 1); - assert(bit_width(nm) == j + 1); - assert(bit_floor(nm) == 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); if (n == m) { - assert(bit_ceil(nm) == m); - assert(has_single_bit(nm)); + verify_eq(bit_ceil(nm), m); + bfs_verify(has_single_bit(nm)); } else { if (j < 15) { - assert(bit_ceil(nm) == (m << 1)); + verify_eq(bit_ceil(nm), (m << 1)); } - assert(!has_single_bit(nm)); + bfs_verify(!has_single_bit(nm)); } } } - assert(leading_zeros((uint16_t)0) == 16); - assert(trailing_zeros((uint16_t)0) == 16); - assert(first_leading_one(0) == 0); - assert(first_trailing_one(0) == 0); - assert(bit_width(0) == 0); - assert(bit_floor(0) == 0); - assert(bit_ceil(0) == 1); + 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); return EXIT_SUCCESS; } diff --git a/tests/trie.c b/tests/trie.c index ced14d4..e687f96 100644 --- a/tests/trie.c +++ b/tests/trie.c @@ -1,11 +1,9 @@ // Copyright © Tavian Barnes // SPDX-License-Identifier: 0BSD -#undef NDEBUG - #include "../src/trie.h" #include "../src/config.h" -#include +#include "../src/diag.h" #include #include @@ -45,7 +43,7 @@ int main(void) { trie_init(&trie); for (size_t i = 0; i < nkeys; ++i) { - assert(!trie_find_str(&trie, keys[i])); + bfs_verify(!trie_find_str(&trie, keys[i])); const char *prefix = NULL; for (size_t j = 0; j < i; ++j) { @@ -58,38 +56,38 @@ int main(void) { struct trie_leaf *leaf = trie_find_prefix(&trie, keys[i]); if (prefix) { - assert(leaf); - assert(strcmp(prefix, leaf->key) == 0); + bfs_verify(leaf); + bfs_verify(strcmp(prefix, leaf->key) == 0); } else { - assert(!leaf); + bfs_verify(!leaf); } leaf = trie_insert_str(&trie, keys[i]); - assert(leaf); - assert(strcmp(keys[i], leaf->key) == 0); - assert(leaf->length == strlen(keys[i]) + 1); + bfs_verify(leaf); + bfs_verify(strcmp(keys[i], leaf->key) == 0); + bfs_verify(leaf->length == strlen(keys[i]) + 1); } { size_t i = 0; TRIE_FOR_EACH(&trie, leaf) { - assert(leaf == trie_find_str(&trie, keys[i])); - assert(!leaf->prev || leaf->prev->next == leaf); - assert(!leaf->next || leaf->next->prev == leaf); + 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); ++i; } - assert(i == nkeys); + bfs_verify(i == nkeys); } for (size_t i = 0; i < nkeys; ++i) { struct trie_leaf *leaf = trie_find_str(&trie, keys[i]); - assert(leaf); - assert(strcmp(keys[i], leaf->key) == 0); - assert(leaf->length == strlen(keys[i]) + 1); + bfs_verify(leaf); + bfs_verify(strcmp(keys[i], leaf->key) == 0); + bfs_verify(leaf->length == strlen(keys[i]) + 1); trie_remove(&trie, leaf); leaf = trie_find_str(&trie, keys[i]); - assert(!leaf); + bfs_verify(!leaf); const char *postfix = NULL; for (size_t j = i + 1; j < nkeys; ++j) { @@ -102,33 +100,33 @@ int main(void) { leaf = trie_find_postfix(&trie, keys[i]); if (postfix) { - assert(leaf); - assert(strcmp(postfix, leaf->key) == 0); + bfs_verify(leaf); + bfs_verify(strcmp(postfix, leaf->key) == 0); } else { - assert(!leaf); + bfs_verify(!leaf); } } TRIE_FOR_EACH(&trie, leaf) { - assert(false); + bfs_verify(false); } // This tests the "jump" node handling on 32-bit platforms size_t longsize = 1 << 20; char *longstr = malloc(longsize); - assert(longstr); + bfs_verify(longstr); memset(longstr, 0xAC, longsize); - assert(!trie_find_mem(&trie, longstr, longsize)); - assert(trie_insert_mem(&trie, longstr, longsize)); + bfs_verify(!trie_find_mem(&trie, longstr, longsize)); + bfs_verify(trie_insert_mem(&trie, longstr, longsize)); memset(longstr + longsize/2, 0xAB, longsize/2); - assert(!trie_find_mem(&trie, longstr, longsize)); - assert(trie_insert_mem(&trie, longstr, longsize)); + bfs_verify(!trie_find_mem(&trie, longstr, longsize)); + bfs_verify(trie_insert_mem(&trie, longstr, longsize)); memset(longstr, 0xAA, longsize/2); - assert(!trie_find_mem(&trie, longstr, longsize)); - assert(trie_insert_mem(&trie, longstr, longsize)); + bfs_verify(!trie_find_mem(&trie, longstr, longsize)); + bfs_verify(trie_insert_mem(&trie, longstr, longsize)); free(longstr); trie_destroy(&trie); -- cgit v1.2.3 From 24a67ef8265e5873c0967ded296a9e57ed9f2914 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 25 May 2023 14:19:21 -0400 Subject: sanity: Add wrappers for sanitizer interfaces --- src/config.h | 9 ------ src/dir.c | 12 ++------ src/fsade.c | 9 +++--- src/parse.c | 1 + src/sanity.h | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/stat.c | 18 ++++++------ src/xregex.c | 8 ++---- 7 files changed, 110 insertions(+), 36 deletions(-) create mode 100644 src/sanity.h (limited to 'src/xregex.c') diff --git a/src/config.h b/src/config.h index f06300e..dbe3c74 100644 --- a/src/config.h +++ b/src/config.h @@ -191,15 +191,6 @@ static inline size_t flex_sizeof_impl(size_t align, size_t min, size_t offset, s return ret; } -/** - * Initialize a variable, unless sanitizers would detect uninitialized uses. - */ -#if __has_feature(memory_sanitizer) -# define uninit(var, value) var -#else -# define uninit(var, value) value -#endif - // Wrappers for attributes /** diff --git a/src/dir.c b/src/dir.c index d9ee63b..01d26db 100644 --- a/src/dir.c +++ b/src/dir.c @@ -5,6 +5,7 @@ #include "bfstd.h" #include "config.h" #include "diag.h" +#include "sanity.h" #include #include #include @@ -18,18 +19,13 @@ #endif #if BFS_GETDENTS -# if __has_feature(memory_sanitizer) -# include -# endif # if __linux__ # include # endif /** getdents() syscall wrapper. */ static ssize_t bfs_getdents(int fd, void *buf, size_t size) { -#if __has_feature(memory_sanitizer) - __msan_allocated_memory(buf, size); -#endif + sanitize_uninit(buf, size); #if __linux__ && __GLIBC__ && !__GLIBC_PREREQ(2, 30) ssize_t ret = syscall(SYS_getdents64, fd, buf, size); @@ -39,11 +35,9 @@ static ssize_t bfs_getdents(int fd, void *buf, size_t size) { ssize_t ret = getdents(fd, buf, size); #endif -#if __has_feature(memory_sanitizer) if (ret > 0) { - __msan_unpoison(buf, ret); + sanitize_init(buf, ret); } -#endif return ret; } diff --git a/src/fsade.c b/src/fsade.c index 4d67940..ba89b60 100644 --- a/src/fsade.c +++ b/src/fsade.c @@ -159,13 +159,12 @@ static int bfs_check_acl_type(acl_t acl, acl_type_t type) { #if __FreeBSD__ int trivial; + int ret = acl_is_trivial_np(acl, &trivial); -#if __has_feature(memory_sanitizer) - // msan seems to be missing an interceptor for acl_is_trivial_np() - trivial = 0; -#endif + // msan seems to be missing an interceptor for acl_is_trivial_np() + sanitize_init(&trivial); - if (acl_is_trivial_np(acl, &trivial) < 0) { + if (ret < 0) { return -1; } else if (trivial) { return 0; diff --git a/src/parse.c b/src/parse.c index 1a04e68..59a1e7d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -24,6 +24,7 @@ #include "opt.h" #include "printf.h" #include "pwcache.h" +#include "sanity.h" #include "stat.h" #include "typo.h" #include "xregex.h" diff --git a/src/sanity.h b/src/sanity.h new file mode 100644 index 0000000..5696036 --- /dev/null +++ b/src/sanity.h @@ -0,0 +1,89 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +/** + * Sanitizer interface. + */ + +#ifndef BFS_SANITY_H +#define BFS_SANITY_H + +#include "config.h" +#include + +#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +# define SANITIZE_ADDRESS true +#endif + +#if __has_feature(memory_sanitizer) || defined(__SANITIZE_MEMORY__) +# define SANITIZE_MEMORY true +#endif + +#if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__) +# define SANITIZE_THREAD true +#endif + +// Call macro(ptr, size) or macro(ptr, sizeof(*ptr)) +#define SANITIZE_CALL(...) \ + SANITIZE_CALL_(__VA_ARGS__, ) + +#define SANITIZE_CALL_(macro, ptr, ...) \ + SANITIZE_CALL__(macro, ptr, __VA_ARGS__ sizeof(*(ptr)), ) + +#define SANITIZE_CALL__(macro, ptr, size, ...) \ + macro(ptr, size) + +#if SANITIZE_ADDRESS +# include + +/** + * sanitize_alloc(ptr, size = sizeof(*ptr)) + * + * Mark a memory region as allocated. + */ +#define sanitize_alloc(...) SANITIZE_CALL(__asan_unpoison_memory_region, __VA_ARGS__) + +/** + * sanitize_free(ptr, size = sizeof(*ptr)) + * + * Mark a memory region as free. + */ +#define sanitize_free(...) SANITIZE_CALL(__asan_poison_memory_region, __VA_ARGS__) + +#else +# define sanitize_alloc sanitize_uninit +# define sanitize_free sanitize_uninit +#endif + +#if SANITIZE_MEMORY +# include + +/** + * sanitize_init(ptr, size = sizeof(*ptr)) + * + * Mark a memory region as initialized. + */ +#define sanitize_init(...) SANITIZE_CALL(__msan_unpoison, __VA_ARGS__) + +/** + * sanitize_uninit(ptr, size = sizeof(*ptr)) + * + * Mark a memory region as uninitialized. + */ +#define sanitize_uninit(...) SANITIZE_CALL(__msan_allocated_memory, __VA_ARGS__) + +#else +# define sanitize_init(...) +# define sanitize_uninit(...) +#endif + +/** + * Initialize a variable, unless sanitizers would detect uninitialized uses. + */ +#if SANITIZE_MEMORY +# define uninit(var, value) var +#else +# define uninit(var, value) value +#endif + +#endif // BFS_SANITY_H diff --git a/src/stat.c b/src/stat.c index 590a1d6..3f70e6c 100644 --- a/src/stat.c +++ b/src/stat.c @@ -5,6 +5,7 @@ #include "bfstd.h" #include "config.h" #include "diag.h" +#include "sanity.h" #include #include #include @@ -132,17 +133,18 @@ static int bfs_stat_impl(int at_fd, const char *at_path, int at_flags, struct bf * Wrapper for the statx() system call, which had no glibc wrapper prior to 2.28. */ static int bfs_statx(int at_fd, const char *at_path, int at_flags, unsigned int mask, struct statx *buf) { -#if __has_feature(memory_sanitizer) - // -fsanitize=memory doesn't know about statx(), so tell it the memory - // got initialized - memset(buf, 0, sizeof(*buf)); -#endif - #if BFS_LIBC_STATX - return statx(at_fd, at_path, at_flags, mask, buf); + int ret = statx(at_fd, at_path, at_flags, mask, buf); #else - return syscall(SYS_statx, at_fd, at_path, at_flags, mask, buf); + int ret = syscall(SYS_statx, at_fd, at_path, at_flags, mask, buf); #endif + + if (ret == 0) { + // -fsanitize=memory doesn't know about statx() + sanitize_init(buf); + } + + return ret; } /** diff --git a/src/xregex.c b/src/xregex.c index 1143f23..ce59ff5 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -4,6 +4,7 @@ #include "xregex.h" #include "config.h" #include "diag.h" +#include "sanity.h" #include #include #include @@ -175,13 +176,10 @@ int bfs_regcomp(struct bfs_regex **preg, const char *pattern, enum bfs_regex_typ cflags |= REG_ICASE; } -#if __has_feature(memory_sanitizer) - // https://github.com/google/sanitizers/issues/1496 - memset(®ex->impl, 0, sizeof(regex->impl)); -#endif - regex->err = regcomp(®ex->impl, pattern, cflags); if (regex->err != 0) { + // https://github.com/google/sanitizers/issues/1496 + sanitize_init(®ex->impl); return -1; } #endif -- cgit v1.2.3 From 36906834d9e6f8381e71ec3ddb66952c509ad869 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 9 Jun 2023 10:50:05 -0400 Subject: xregex: Initialize Oniguruma thread-safely --- src/xregex.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'src/xregex.c') diff --git a/src/xregex.c b/src/xregex.c index ce59ff5..89c2e90 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -6,6 +6,7 @@ #include "diag.h" #include "sanity.h" #include +#include #include #include @@ -29,16 +30,14 @@ struct bfs_regex { }; #if BFS_WITH_ONIGURUMA -/** Get (and initialize) the appropriate encoding for the current locale. */ -static int bfs_onig_encoding(OnigEncoding *penc) { - static OnigEncoding enc = NULL; - if (enc) { - *penc = enc; - return ONIG_NORMAL; - } +static int bfs_onig_status; +static OnigEncoding bfs_onig_enc; + +/** pthread_once() callback. */ +static void bfs_onig_once(void) { // Fall back to ASCII by default - enc = ONIG_ENCODING_ASCII; + bfs_onig_enc = ONIG_ENCODING_ASCII; // Oniguruma has no locale support, so try to guess the right encoding // from the current locale. @@ -47,7 +46,7 @@ static int bfs_onig_encoding(OnigEncoding *penc) { #define BFS_MAP_ENCODING(name, value) \ do { \ if (strcmp(charmap, name) == 0) { \ - enc = value; \ + bfs_onig_enc = value; \ } \ } while (0) #define BFS_MAP_ENCODING2(name1, name2, value) \ @@ -97,12 +96,21 @@ static int bfs_onig_encoding(OnigEncoding *penc) { BFS_MAP_ENCODING("GB18030", ONIG_ENCODING_BIG5); } - int ret = onig_initialize(&enc, 1); - if (ret != ONIG_NORMAL) { - enc = NULL; + bfs_onig_status = onig_initialize(&bfs_onig_enc, 1); + if (bfs_onig_status != ONIG_NORMAL) { + bfs_onig_enc = NULL; + } +} + +/** Initialize Oniguruma. */ +static int bfs_onig_initialize(OnigEncoding *enc) { + static pthread_once_t once = PTHREAD_ONCE_INIT; + if (pthread_once(&once, bfs_onig_once) != 0) { + return ONIGERR_FAIL_TO_INITIALIZE; } - *penc = enc; - return ret; + + *enc = bfs_onig_enc; + return bfs_onig_status; } #endif @@ -141,7 +149,7 @@ int bfs_regcomp(struct bfs_regex **preg, const char *pattern, enum bfs_regex_typ syntax = ONIG_SYNTAX_GREP; break; } - bfs_assert(syntax); + bfs_assert(syntax, "Invalid regex type"); OnigOptionType options = syntax->options; if (flags & BFS_REGEX_ICASE) { @@ -149,7 +157,7 @@ int bfs_regcomp(struct bfs_regex **preg, const char *pattern, enum bfs_regex_typ } OnigEncoding enc; - regex->err = bfs_onig_encoding(&enc); + regex->err = bfs_onig_initialize(&enc); if (regex->err != ONIG_NORMAL) { return -1; } -- cgit v1.2.3 From 90ded13e589b0089167ef25ca3d26be599dfec9b Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 19 Jun 2023 12:11:36 -0400 Subject: alloc: New header for memory allocation utilities --- Makefile | 3 +- src/alloc.c | 50 ++++++++++++++++++++ src/alloc.h | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/bfstd.c | 13 ----- src/bfstd.h | 12 ----- src/bftw.c | 5 +- src/color.c | 5 +- src/config.h | 50 -------------------- src/ctx.c | 31 ++---------- src/dstring.c | 3 +- src/exec.c | 26 ++++------ src/ioq.c | 26 ++++------ src/ioq.h | 4 +- src/main.c | 1 + src/mtab.c | 5 +- src/parse.c | 28 ++--------- src/pwcache.c | 5 +- src/trie.c | 7 ++- src/xregex.c | 3 +- src/xspawn.c | 3 +- tests/alloc.c | 24 ++++++++++ tests/bfstd.c | 13 +---- 22 files changed, 271 insertions(+), 195 deletions(-) create mode 100644 src/alloc.c create mode 100644 src/alloc.h create mode 100644 tests/alloc.c (limited to 'src/xregex.c') diff --git a/Makefile b/Makefile index fb28e29..d38f581 100644 --- a/Makefile +++ b/Makefile @@ -217,6 +217,7 @@ $(OBJ)/FLAGS: $(OBJ)/FLAGS.new # All object files except the entry point LIBBFS := \ + $(OBJ)/src/alloc.o \ $(OBJ)/src/bar.o \ $(OBJ)/src/bfstd.o \ $(OBJ)/src/bftw.o \ @@ -246,7 +247,7 @@ LIBBFS := \ $(BIN)/bfs: $(OBJ)/src/main.o $(LIBBFS) # Standalone unit tests -UNITS := bfstd bit trie xtimegm +UNITS := alloc bfstd bit trie xtimegm UNIT_TESTS := $(UNITS:%=$(BIN)/tests/%) UNIT_CHECKS := $(UNITS:%=check-%) diff --git a/src/alloc.c b/src/alloc.c new file mode 100644 index 0000000..0003108 --- /dev/null +++ b/src/alloc.c @@ -0,0 +1,50 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +#include "alloc.h" +#include "bit.h" +#include "diag.h" +#include +#include +#include + +/** Portable aligned_alloc()/posix_memalign(). */ +static void *xmemalign(size_t align, size_t size) { + bfs_assert(has_single_bit(align)); + bfs_assert(align >= sizeof(void *)); + bfs_assert((size & (align - 1)) == 0); + +#if __APPLE__ + void *ptr = NULL; + errno = posix_memalign(&ptr, align, size); + return ptr; +#else + return aligned_alloc(align, size); +#endif +} + +void *alloc(size_t align, size_t size) { + bfs_assert(has_single_bit(align)); + bfs_assert((size & (align - 1)) == 0); + + if (align <= alignof(max_align_t)) { + return malloc(size); + } else { + return xmemalign(align, size); + } +} + +void *zalloc(size_t align, size_t size) { + bfs_assert(has_single_bit(align)); + bfs_assert((size & (align - 1)) == 0); + + if (align <= alignof(max_align_t)) { + return calloc(1, size); + } + + void *ret = xmemalign(align, size); + if (ret) { + memset(ret, 0, size); + } + return ret; +} diff --git a/src/alloc.h b/src/alloc.h new file mode 100644 index 0000000..899a4ec --- /dev/null +++ b/src/alloc.h @@ -0,0 +1,149 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +/** + * Memory allocation. + */ + +#ifndef BFS_ALLOC_H +#define BFS_ALLOC_H + +#include "config.h" +#include + +/** Round down to a multiple of an alignment. */ +static inline size_t align_floor(size_t align, size_t size) { + return size & ~(align - 1); +} + +/** Round up to a multiple of an alignment. */ +static inline size_t align_ceil(size_t align, size_t size) { + return align_floor(align, size + align - 1); +} + +/** + * Saturating array size. + * + * @param align + * Array element alignment. + * @param size + * Array element size. + * @param count + * Array element count. + * @return + * size * count, saturating to the maximum aligned value on overflow. + */ +static inline size_t array_size(size_t align, size_t size, size_t count) { + size_t ret = size * count; + return ret / size == count ? ret : ~(align - 1); +} + +/** Saturating array sizeof. */ +#define sizeof_array(type, count) \ + array_size(alignof(type), sizeof(type), count) + +/** Size of a struct/union field. */ +#define sizeof_member(type, member) \ + sizeof(((type *)NULL)->member) + +/** + * Saturating flexible struct size. + * + * @param align + * Struct alignment. + * @param min + * Minimum struct size. + * @param offset + * Flexible array member offset. + * @param size + * Flexible array element size. + * @param count + * Flexible array element count. + * @return + * The size of the struct with count flexible array elements. Saturates + * to the maximum aligned value on overflow. + */ +static inline size_t flex_size(size_t align, size_t min, size_t offset, size_t size, size_t count) { + size_t ret = size * count; + size_t overflow = ret / size != count; + + size_t extra = offset + align - 1; + ret += extra; + overflow |= ret < extra; + ret |= -overflow; + ret = align_floor(align, ret); + + // Make sure flex_sizeof(type, member, 0) >= sizeof(type), even if the + // type has more padding than necessary for alignment + if (min > align_ceil(align, offset)) { + ret = ret < min ? min : ret; + } + + return ret; +} + +/** + * Computes the size of a flexible struct. + * + * @param type + * The type of the struct containing the flexible array. + * @param member + * The name of the flexible array member. + * @param count + * The length of the flexible array. + * @return + * The size of the struct with count flexible array elements. Saturates + * to the maximum aligned value on overflow. + */ +#define sizeof_flex(type, member, count) \ + flex_size(alignof(type), sizeof(type), offsetof(type, member), sizeof_member(type, member[0]), count) + +/** + * General memory allocator. + * + * @param align + * The required alignment. + * @param size + * The size of the allocation. + * @return + * The allocated memory, or NULL on failure. + */ +void *alloc(size_t align, size_t size); + +/** + * Zero-initialized memory allocator. + * + * @param align + * The required alignment. + * @param size + * The size of the allocation. + * @return + * The allocated memory, or NULL on failure. + */ +void *zalloc(size_t align, size_t size); + +/** Allocate memory for the given type. */ +#define ALLOC(type) \ + (type *)alloc(alignof(type), sizeof(type)) + +/** Allocate zeroed memory for the given type. */ +#define ZALLOC(type) \ + (type *)zalloc(alignof(type), sizeof(type)) + +/** Allocate memory for an array. */ +#define ALLOC_ARRAY(type, count) \ + (type *)alloc(alignof(type), sizeof_array(type, count)); + +/** Allocate zeroed memory for an array. */ +#define ZALLOC_ARRAY(type, count) \ + (type *)zalloc(alignof(type), sizeof_array(type, count)); + +/** Allocate memory for a flexible struct. */ +#define ALLOC_FLEX(type, member, count) \ + (type *)alloc(alignof(type), sizeof_flex(type, member, count)) + +/** Allocate zeroed memory for a flexible struct. */ +#define ZALLOC_FLEX(type, member, count) \ + (type *)zalloc(alignof(type), sizeof_flex(type, member, count)) + +#endif // BFS_ALLOC_H diff --git a/src/bfstd.c b/src/bfstd.c index 856c76c..0e8ba5f 100644 --- a/src/bfstd.c +++ b/src/bfstd.c @@ -143,19 +143,6 @@ char *xgetdelim(FILE *file, char delim) { } } -void *xmemalign(size_t align, size_t size) { - bfs_assert(has_single_bit(align)); - bfs_assert((size & (align - 1)) == 0); - -#if __APPLE__ - void *ptr = NULL; - errno = posix_memalign(&ptr, align, size); - return ptr; -#else - return aligned_alloc(align, size); -#endif -} - /** Compile and execute a regular expression for xrpmatch(). */ static int xrpregex(nl_item item, const char *response) { const char *pattern = nl_langinfo(item); diff --git a/src/bfstd.h b/src/bfstd.h index 6f2e21e..cafe28f 100644 --- a/src/bfstd.h +++ b/src/bfstd.h @@ -105,18 +105,6 @@ char *xgetdelim(FILE *file, char delim); // #include -/** - * Portable version of aligned_alloc()/posix_memalign(). - * - * @param align - * The allocation's alignment. - * @param size - * The allocation's size. - * @return - * The allocation, or NULL on failure. - */ -void *xmemalign(size_t align, size_t size); - /** * Process a yes/no prompt. * diff --git a/src/bftw.c b/src/bftw.c index e711963..7ab14c7 100644 --- a/src/bftw.c +++ b/src/bftw.c @@ -17,6 +17,7 @@ */ #include "bftw.h" +#include "alloc.h" #include "bfstd.h" #include "config.h" #include "diag.h" @@ -241,9 +242,7 @@ static void bftw_cache_destroy(struct bftw_cache *cache) { /** Create a new bftw_file. */ static struct bftw_file *bftw_file_new(struct bftw_file *parent, const char *name) { size_t namelen = strlen(name); - size_t size = flex_sizeof(struct bftw_file, name, namelen + 1); - - struct bftw_file *file = malloc(size); + struct bftw_file *file = ALLOC_FLEX(struct bftw_file, name, namelen + 1); if (!file) { return NULL; } diff --git a/src/color.c b/src/color.c index 1edd8b5..b54ad53 100644 --- a/src/color.c +++ b/src/color.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "color.h" +#include "alloc.h" #include "bfstd.h" #include "bftw.h" #include "config.h" @@ -404,7 +405,7 @@ static void parse_gnu_ls_colors(struct colors *colors, const char *ls_colors) { } struct colors *parse_colors(void) { - struct colors *colors = malloc(sizeof(struct colors)); + struct colors *colors = ALLOC(struct colors); if (!colors) { return NULL; } @@ -497,7 +498,7 @@ void free_colors(struct colors *colors) { } CFILE *cfwrap(FILE *file, const struct colors *colors, bool close) { - CFILE *cfile = malloc(sizeof(*cfile)); + CFILE *cfile = ALLOC(CFILE); if (!cfile) { return NULL; } diff --git a/src/config.h b/src/config.h index 73348ac..1671a0d 100644 --- a/src/config.h +++ b/src/config.h @@ -141,56 +141,6 @@ */ #define countof(array) (sizeof(array) / sizeof(0[array])) -/** - * Round down to a multiple of an alignment. - */ -static inline size_t align_floor(size_t align, size_t size) { - return size & ~(align - 1); -} - -/** - * Round up to a multiple of an alignment. - */ -static inline size_t align_ceil(size_t align, size_t size) { - return align_floor(align, size + align - 1); -} - -/** - * Computes the size of a struct containing a flexible array member of the given - * length. - * - * @param type - * The type of the struct containing the flexible array. - * @param member - * The name of the flexible array member. - * @param count - * The length of the flexible array. - */ -#define flex_sizeof(type, member, count) \ - flex_sizeof_impl(alignof(type), sizeof(type), offsetof(type, member), sizeof(((type *)NULL)->member[0]), count) - -static inline size_t flex_sizeof_impl(size_t align, size_t min, size_t offset, size_t size, size_t count) { - size_t ret = size * count; - size_t overflow = ret / size != count; - - ret += offset; - overflow |= ret < offset; - - size_t mask = align - 1; - ret += mask; - overflow |= ret < mask; - ret |= -overflow; - ret &= ~mask; - - // Make sure flex_sizeof(type, member, 0) >= sizeof(type), even if the - // type has more padding than necessary for alignment - if (min > align_ceil(align, offset) && ret < min) { - ret = min; - } - - return ret; -} - /** * False sharing/destructive interference/largest cache line size. */ diff --git a/src/ctx.c b/src/ctx.c index e8ce0e8..a940bed 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "ctx.h" +#include "alloc.h" #include "color.h" #include "darray.h" #include "diag.h" @@ -42,43 +43,17 @@ const char *debug_flag_name(enum debug_flags flag) { } struct bfs_ctx *bfs_ctx_new(void) { - struct bfs_ctx *ctx = malloc(sizeof(*ctx)); + struct bfs_ctx *ctx = ZALLOC(struct bfs_ctx); if (!ctx) { return NULL; } - ctx->argv = NULL; - ctx->paths = NULL; - ctx->expr = NULL; - ctx->exclude = NULL; - - ctx->mindepth = 0; ctx->maxdepth = INT_MAX; ctx->flags = BFTW_RECOVER; ctx->strategy = BFTW_BFS; - ctx->threads = 0; ctx->optlevel = 3; - ctx->debug = 0; - ctx->ignore_races = false; - ctx->posixly_correct = false; - ctx->status = false; - ctx->unique = false; - ctx->warn = false; - ctx->xargs_safe = false; - - ctx->colors = NULL; - ctx->colors_error = 0; - ctx->cout = NULL; - ctx->cerr = NULL; - - ctx->users = NULL; - ctx->groups = NULL; - - ctx->mtab = NULL; - ctx->mtab_error = 0; trie_init(&ctx->files); - ctx->nfiles = 0; struct rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { @@ -155,7 +130,7 @@ CFILE *bfs_ctx_dedup(struct bfs_ctx *ctx, CFILE *cfile, const char *path) { return ctx_file->cfile; } - leaf->value = ctx_file = malloc(sizeof(*ctx_file)); + leaf->value = ctx_file = ALLOC(struct bfs_ctx_file); if (!ctx_file) { trie_remove(&ctx->files, leaf); return NULL; diff --git a/src/dstring.c b/src/dstring.c index 2c9869d..7ca74d0 100644 --- a/src/dstring.c +++ b/src/dstring.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "dstring.h" +#include "alloc.h" #include "diag.h" #include #include @@ -24,7 +25,7 @@ static struct dstring *dstrheader(const char *dstr) { /** Get the correct size for a dstring with the given capacity. */ static size_t dstrsize(size_t capacity) { - return flex_sizeof(struct dstring, data, capacity + 1); + return sizeof_flex(struct dstring, data, capacity + 1); } /** Allocate a dstring with the given contents. */ diff --git a/src/exec.c b/src/exec.c index 5912ad6..ea7f897 100644 --- a/src/exec.c +++ b/src/exec.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "exec.h" +#include "alloc.h" #include "bfstd.h" #include "bftw.h" #include "ctx.h" @@ -124,26 +125,16 @@ static void bfs_exec_parse_error(const struct bfs_ctx *ctx, const struct bfs_exe } struct bfs_exec *bfs_exec_parse(const struct bfs_ctx *ctx, char **argv, enum bfs_exec_flags flags) { - struct bfs_exec *execbuf = malloc(sizeof(*execbuf)); + struct bfs_exec *execbuf = ZALLOC(struct bfs_exec); if (!execbuf) { - bfs_perror(ctx, "malloc()"); + bfs_perror(ctx, "zalloc()"); goto fail; } execbuf->flags = flags; execbuf->ctx = ctx; execbuf->tmpl_argv = argv + 1; - execbuf->tmpl_argc = 0; - execbuf->argv = NULL; - execbuf->argc = 0; - execbuf->argv_cap = 0; - execbuf->arg_size = 0; - execbuf->arg_max = 0; - execbuf->arg_min = 0; execbuf->wd_fd = -1; - execbuf->wd_path = NULL; - execbuf->wd_len = 0; - execbuf->ret = 0; while (true) { const char *arg = execbuf->tmpl_argv[execbuf->tmpl_argc]; @@ -176,9 +167,9 @@ struct bfs_exec *bfs_exec_parse(const struct bfs_ctx *ctx, char **argv, enum bfs } execbuf->argv_cap = execbuf->tmpl_argc + 1; - execbuf->argv = malloc(execbuf->argv_cap*sizeof(*execbuf->argv)); + execbuf->argv = ALLOC_ARRAY(char *, execbuf->argv_cap); if (!execbuf->argv) { - bfs_perror(ctx, "malloc()"); + bfs_perror(ctx, "alloc()"); goto fail; } @@ -224,9 +215,8 @@ static char *bfs_exec_format_path(const struct bfs_exec *execbuf, const struct B return NULL; } - strcpy(path, "./"); - strcpy(path + 2, name); - + char *cur = stpcpy(path, "./"); + cur = stpcpy(cur, name); return path; } @@ -612,7 +602,7 @@ static int bfs_exec_push(struct bfs_exec *execbuf, char *arg) { if (execbuf->argc + 1 >= execbuf->argv_cap) { size_t cap = 2*execbuf->argv_cap; - char **argv = realloc(execbuf->argv, cap*sizeof(*argv)); + char **argv = realloc(execbuf->argv, sizeof_array(char *, cap)); if (!argv) { return -1; } diff --git a/src/ioq.c b/src/ioq.c index 5550c91..3e304ce 100644 --- a/src/ioq.c +++ b/src/ioq.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "ioq.h" +#include "alloc.h" #include "atomic.h" #include "bfstd.h" #include "bit.h" @@ -114,7 +115,7 @@ static struct ioqq *ioqq_create(size_t size) { // Circular buffer size must be a power of two size = bit_ceil(size); - struct ioqq *ioqq = xmemalign(alignof(struct ioqq), flex_sizeof(struct ioqq, slots, size)); + struct ioqq *ioqq = ALLOC_FLEX(struct ioqq, slots, size); if (!ioqq) { return NULL; } @@ -124,7 +125,7 @@ static struct ioqq *ioqq_create(size_t size) { // Use a pool of monitors size_t nmonitors = size < 64 ? size : 64; - ioqq->monitors = xmemalign(alignof(struct ioq_monitor), nmonitors * sizeof(struct ioq_monitor)); + ioqq->monitors = ALLOC_ARRAY(struct ioq_monitor, nmonitors); if (!ioqq->monitors) { ioqq_destroy(ioqq); return NULL; @@ -273,7 +274,7 @@ struct ioq { /** The number of background threads. */ size_t nthreads; /** The background threads themselves. */ - pthread_t *threads; + pthread_t threads[]; }; /** Background thread entry point. */ @@ -303,18 +304,13 @@ static void *ioq_work(void *ptr) { return NULL; } -struct ioq *ioq_create(size_t depth, size_t threads) { - struct ioq *ioq = malloc(sizeof(*ioq)); +struct ioq *ioq_create(size_t depth, size_t nthreads) { + struct ioq *ioq = ZALLOC_FLEX(struct ioq, threads, nthreads); if (!ioq) { goto fail; } ioq->depth = depth; - ioq->size = 0; - - ioq->pending = NULL; - ioq->ready = NULL; - ioq->nthreads = 0; ioq->pending = ioqq_create(depth); if (!ioq->pending) { @@ -326,12 +322,7 @@ struct ioq *ioq_create(size_t depth, size_t threads) { goto fail; } - ioq->threads = malloc(threads * sizeof(ioq->threads[0])); - if (!ioq->threads) { - goto fail; - } - - for (size_t i = 0; i < threads; ++i) { + for (size_t i = 0; i < nthreads; ++i) { errno = pthread_create(&ioq->threads[i], NULL, ioq_work, ioq); if (errno != 0) { goto fail; @@ -354,7 +345,7 @@ int ioq_opendir(struct ioq *ioq, int dfd, const char *path, void *ptr) { return -1; } - union ioq_cmd *cmd = malloc(sizeof(*cmd)); + union ioq_cmd *cmd = ALLOC(union ioq_cmd); if (!cmd) { return -1; } @@ -412,7 +403,6 @@ void ioq_destroy(struct ioq *ioq) { abort(); } } - free(ioq->threads); ioqq_destroy(ioq->ready); ioqq_destroy(ioq->pending); diff --git a/src/ioq.h b/src/ioq.h index 9492034..0af5779 100644 --- a/src/ioq.h +++ b/src/ioq.h @@ -33,12 +33,12 @@ struct ioq_res { * * @param depth * The maximum depth of the queue. - * @param threads + * @param nthreads * The maximum number of background threads. * @return * The new I/O queue, or NULL on failure. */ -struct ioq *ioq_create(size_t depth, size_t threads); +struct ioq *ioq_create(size_t depth, size_t nthreads); /** * Asynchronous bfs_opendir(). diff --git a/src/main.c b/src/main.c index 76dde86..b7a08c1 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,7 @@ * - bftw.[ch] (an extended version of nftw(3)) * * - Utilities: + * - alloc.[ch] (memory allocation) * - atomic.h (atomic operations) * - bar.[ch] (a terminal status bar) * - bit.h (bit manipulation) diff --git a/src/mtab.c b/src/mtab.c index 1d1ad94..e5c25ba 100644 --- a/src/mtab.c +++ b/src/mtab.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "mtab.h" +#include "alloc.h" #include "bfstd.h" #include "config.h" #include "darray.h" @@ -87,15 +88,13 @@ fail: } struct bfs_mtab *bfs_mtab_parse(void) { - struct bfs_mtab *mtab = malloc(sizeof(*mtab)); + struct bfs_mtab *mtab = ZALLOC(struct bfs_mtab); if (!mtab) { return NULL; } - mtab->entries = NULL; trie_init(&mtab->names); trie_init(&mtab->types); - mtab->types_filled = false; int error = 0; diff --git a/src/parse.c b/src/parse.c index 64e08cd..cf4f696 100644 --- a/src/parse.c +++ b/src/parse.c @@ -9,6 +9,7 @@ */ #include "parse.h" +#include "alloc.h" #include "bfstd.h" #include "bftw.h" #include "color.h" @@ -55,39 +56,16 @@ static char *fake_print_arg = "-print"; static char *fake_true_arg = "-true"; struct bfs_expr *bfs_expr_new(bfs_eval_fn *eval_fn, size_t argc, char **argv) { - struct bfs_expr *expr = malloc(sizeof(*expr)); + struct bfs_expr *expr = ZALLOC(struct bfs_expr); if (!expr) { - perror("malloc()"); + perror("zalloc()"); return NULL; } expr->eval_fn = eval_fn; expr->argc = argc; expr->argv = argv; - expr->persistent_fds = 0; - expr->ephemeral_fds = 0; - expr->pure = false; - expr->always_true = false; - expr->always_false = false; - expr->cost = 0.0; expr->probability = 0.5; - expr->evaluations = 0; - expr->successes = 0; - expr->elapsed.tv_sec = 0; - expr->elapsed.tv_nsec = 0; - - // Prevent bfs_expr_free() from freeing uninitialized pointers on error paths - if (bfs_expr_is_parent(expr)) { - expr->lhs = NULL; - expr->rhs = NULL; - } else if (eval_fn == eval_exec) { - expr->exec = NULL; - } else if (eval_fn == eval_fprintf) { - expr->printf = NULL; - } else if (eval_fn == eval_regex) { - expr->regex = NULL; - } - return expr; } diff --git a/src/pwcache.c b/src/pwcache.c index f52e4e1..9f32eb0 100644 --- a/src/pwcache.c +++ b/src/pwcache.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "pwcache.h" +#include "alloc.h" #include "config.h" #include "darray.h" #include "trie.h" @@ -71,7 +72,7 @@ struct bfs_users { }; struct bfs_users *bfs_users_new(void) { - struct bfs_users *users = malloc(sizeof(*users)); + struct bfs_users *users = ALLOC(struct bfs_users); if (!users) { return NULL; } @@ -144,7 +145,7 @@ struct bfs_groups { }; struct bfs_groups *bfs_groups_new(void) { - struct bfs_groups *groups = malloc(sizeof(*groups)); + struct bfs_groups *groups = ALLOC(struct bfs_groups); if (!groups) { return NULL; } diff --git a/src/trie.c b/src/trie.c index 8543eb1..19423cf 100644 --- a/src/trie.c +++ b/src/trie.c @@ -82,6 +82,7 @@ */ #include "trie.h" +#include "alloc.h" #include "bit.h" #include "config.h" #include "diag.h" @@ -317,7 +318,7 @@ struct trie_leaf *trie_find_prefix(const struct trie *trie, const char *key) { /** Create a new leaf, holding a copy of the given key. */ static struct trie_leaf *trie_leaf_alloc(struct trie *trie, const void *key, size_t length) { - struct trie_leaf *leaf = malloc(flex_sizeof(struct trie_leaf, key, length)); + struct trie_leaf *leaf = ALLOC_FLEX(struct trie_leaf, key, length); if (!leaf) { return NULL; } @@ -339,12 +340,10 @@ static void trie_leaf_free(struct trie *trie, struct trie_leaf *leaf) { /** Compute the size of a trie node with a certain number of children. */ static size_t trie_node_size(unsigned int size) { - // Empty nodes aren't supported - bfs_assert(size > 0); // Node size must be a power of two bfs_assert(has_single_bit(size)); - return flex_sizeof(struct trie_node, children, size); + return sizeof_flex(struct trie_node, children, size); } #if ENDIAN_NATIVE == ENDIAN_LITTLE diff --git a/src/xregex.c b/src/xregex.c index 89c2e90..ab5f793 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "xregex.h" +#include "alloc.h" #include "config.h" #include "diag.h" #include "sanity.h" @@ -115,7 +116,7 @@ static int bfs_onig_initialize(OnigEncoding *enc) { #endif int bfs_regcomp(struct bfs_regex **preg, const char *pattern, enum bfs_regex_type type, enum bfs_regcomp_flags flags) { - struct bfs_regex *regex = *preg = malloc(sizeof(*regex)); + struct bfs_regex *regex = *preg = ALLOC(struct bfs_regex); if (!regex) { return -1; } diff --git a/src/xspawn.c b/src/xspawn.c index 740e38e..2cabdcc 100644 --- a/src/xspawn.c +++ b/src/xspawn.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #include "xspawn.h" +#include "alloc.h" #include "bfstd.h" #include "config.h" #include "list.h" @@ -62,7 +63,7 @@ int bfs_spawn_setflags(struct bfs_spawn *ctx, enum bfs_spawn_flags flags) { /** Add a spawn action to the chain. */ static struct bfs_spawn_action *bfs_spawn_add(struct bfs_spawn *ctx, enum bfs_spawn_op op) { - struct bfs_spawn_action *action = malloc(sizeof(*action)); + struct bfs_spawn_action *action = ALLOC(struct bfs_spawn_action); if (!action) { return NULL; } diff --git a/tests/alloc.c b/tests/alloc.c new file mode 100644 index 0000000..91b1b43 --- /dev/null +++ b/tests/alloc.c @@ -0,0 +1,24 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +#include "../src/alloc.h" +#include "../src/diag.h" +#include + +int main(void) { + // Check sizeof_flex() + struct flexible { + alignas(64) int foo; + 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); + bfs_verify(sizeof_flex(struct flexible, bar, SIZE_MAX / sizeof(int) + 1) + == 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); + + return EXIT_SUCCESS; +} diff --git a/tests/bfstd.c b/tests/bfstd.c index 7fea9b5..fa854a8 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -24,17 +24,6 @@ static void check_base_dir(const char *path, const char *dir, const char *base) } int main(void) { - // Check flex_sizeof() - struct flexible { - alignas(64) int foo; - int bar[]; - }; - bfs_verify(flex_sizeof(struct flexible, bar, 0) >= sizeof(struct flexible)); - bfs_verify(flex_sizeof(struct flexible, bar, 16) % alignof(struct flexible) == 0); - bfs_verify(flex_sizeof(struct flexible, bar, SIZE_MAX / sizeof(int) + 1) - == align_floor(alignof(struct flexible), SIZE_MAX)); - bfs_verify(flex_sizeof_impl(8, 16, 4, 4, 1) == 16); - // From man 3p basename check_base_dir("usr", ".", "usr"); check_base_dir("usr/", ".", "usr"); @@ -46,4 +35,6 @@ int main(void) { check_base_dir("/usr/lib", "/usr", "lib"); check_base_dir("//usr//lib//", "//usr", "lib"); check_base_dir("/home//dwc//test", "/home//dwc", "test"); + + return EXIT_SUCCESS; } -- cgit v1.2.3 From 5c3572dc323527a5c168cc12a31b730e0749002d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 24 Jun 2023 12:00:22 -0400 Subject: Unify macro naming conventions In particular, macros that decide whether to use a particular API/ dependency should be spelled BFS_USE_*, and should be configurable. --- Makefile | 20 ++++++++++---------- docs/BUILDING.md | 18 +++++++++--------- src/config.h | 6 ++++-- src/diag.h | 6 ++---- src/dir.c | 28 ++++++++++++++-------------- src/mtab.c | 28 ++++++++++++++-------------- src/parse.c | 4 ++-- src/stat.c | 16 +++++++++------- src/trie.c | 2 +- src/xregex.c | 14 +++++++------- 10 files changed, 72 insertions(+), 70 deletions(-) (limited to 'src/xregex.c') diff --git a/Makefile b/Makefile index d38f581..f7af9cc 100644 --- a/Makefile +++ b/Makefile @@ -104,11 +104,11 @@ LOCAL_CFLAGS += -fno-sanitize-recover=all endif ifndef NOLIBS -WITH_ONIGURUMA := y +USE_ONIGURUMA := y endif -ifdef WITH_ONIGURUMA -LOCAL_CPPFLAGS += -DBFS_WITH_ONIGURUMA=1 +ifdef USE_ONIGURUMA +LOCAL_CPPFLAGS += -DBFS_USE_ONIGURUMA=1 ONIG_CONFIG := $(shell command -v onig-config 2>/dev/null) ifdef ONIG_CONFIG @@ -120,28 +120,28 @@ endif LOCAL_CFLAGS += $(ONIG_CFLAGS) LOCAL_LDLIBS += $(ONIG_LDLIBS) -endif # WITH_ONIGURUMA +endif # USE_ONIGURUMA ifeq ($(OS),Linux) ifndef NOLIBS -WITH_ACL := y -WITH_ATTR := y -WITH_LIBCAP := y +USE_ACL := y +USE_ATTR := y +USE_LIBCAP := y endif -ifdef WITH_ACL +ifdef USE_ACL LOCAL_LDLIBS += -lacl else LOCAL_CPPFLAGS += -DBFS_USE_SYS_ACL_H=0 endif -ifdef WITH_ATTR +ifdef USE_ATTR LOCAL_LDLIBS += -lattr else LOCAL_CPPFLAGS += -DBFS_USE_SYS_XATTR_H=0 endif -ifdef WITH_LIBCAP +ifdef USE_LIBCAP LOCAL_LDLIBS += -lcap else LOCAL_CPPFLAGS += -DBFS_USE_SYS_CAPABILITY_H=0 diff --git a/docs/BUILDING.md b/docs/BUILDING.md index 5219160..d0cb1fc 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -56,7 +56,7 @@ Here are some of the common ones; check the [`Makefile`](/Makefile) for more. | `CC` | The C compiler to use, e.g. `make CC=clang` | | `CFLAGS`
`EXTRA_CFLAGS` | Override/add to the default compiler flags | | `LDFLAGS`
`EXTRA_LDFLAGS` | Override/add to the linker flags | -| `WITH_ACL`
`WITH_ATTR`
... | Enable/disable [optional dependencies] | +| `USE_ACL`
`USE_ATTR`
... | Enable/disable [optional dependencies] | | `TEST_FLAGS` | `tests.sh` flags for `make check` | | `BUILDDIR` | The build output directory (default: `.`) | | `DESTDIR` | The root directory for `make install` | @@ -68,14 +68,14 @@ Here are some of the common ones; check the [`Makefile`](/Makefile) for more. ### Dependencies `bfs` depends on some system libraries for some of its features. -These dependencies are optional, and can be turned off at build time if necessary by setting the appropriate variable to the empty string (e.g. `make WITH_ONIGURUMA=`). - -| Dependency | Platforms | `make` flag | -|-------------|------------|------------------| -| [acl] | Linux only | `WITH_ACL` | -| [attr] | Linux only | `WITH_ATTR` | -| [libcap] | Linux only | `WITH_LIBCAP` | -| [Oniguruma] | All | `WITH_ONIGURUMA` | +These dependencies are optional, and can be turned off at build time if necessary by setting the appropriate variable to the empty string (e.g. `make USE_ONIGURUMA=`). + +| Dependency | Platforms | `make` flag | +|-------------|------------|-----------------| +| [acl] | Linux only | `USE_ACL` | +| [attr] | Linux only | `USE_ATTR` | +| [libcap] | Linux only | `USE_LIBCAP` | +| [Oniguruma] | All | `USE_ONIGURUMA` | [acl]: https://savannah.nongnu.org/projects/acl [attr]: https://savannah.nongnu.org/projects/attr diff --git a/src/config.h b/src/config.h index 1671a0d..79bd931 100644 --- a/src/config.h +++ b/src/config.h @@ -189,8 +189,10 @@ /** * Check if function multiversioning via GNU indirect functions (ifunc) is supported. */ -#if !defined(BFS_TARGET_CLONES) && __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__ || __NetBSD__) -# define BFS_TARGET_CLONES true +#ifndef BFS_USE_TARGET_CLONES +# if __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__ || __NetBSD__) +# define BFS_USE_TARGET_CLONES true +# endif #endif /** diff --git a/src/diag.h b/src/diag.h index 8d02da6..c909da5 100644 --- a/src/diag.h +++ b/src/diag.h @@ -18,8 +18,8 @@ #if __STDC_VERSION__ >= 202311L # define bfs_static_assert static_assert #else -# define bfs_static_assert(...) BFS_STATIC_ASSERT(__VA_ARGS__, #__VA_ARGS__, ) -# define BFS_STATIC_ASSERT(expr, msg, ...) _Static_assert(expr, msg) +# define bfs_static_assert(...) bfs_static_assert_(__VA_ARGS__, #__VA_ARGS__, ) +# define bfs_static_assert_(expr, msg, ...) _Static_assert(expr, msg) #endif /** @@ -62,8 +62,6 @@ noreturn void bfs_abortf(const struct bfs_loc *loc, const char *format, ...); # define bfs_bug bfs_abort #endif - - /** * Unconditional assert. */ diff --git a/src/dir.c b/src/dir.c index a24b572..685bac5 100644 --- a/src/dir.c +++ b/src/dir.c @@ -15,11 +15,11 @@ #include #include -#ifndef BFS_GETDENTS -# define BFS_GETDENTS (__linux__ || __FreeBSD__) +#ifndef BFS_USE_GETDENTS +# define BFS_USE_GETDENTS (__linux__ || __FreeBSD__) #endif -#if BFS_GETDENTS +#if BFS_USE_GETDENTS # if __linux__ # include # endif @@ -43,9 +43,9 @@ static ssize_t bfs_getdents(int fd, void *buf, size_t size) { return ret; } -#endif // BFS_GETDENTS +#endif // BFS_USE_GETDENTS -#if BFS_GETDENTS && __linux__ +#if BFS_USE_GETDENTS && __linux__ /** Directory entry type for bfs_getdents() */ typedef struct dirent64 sys_dirent; #else @@ -101,7 +101,7 @@ enum bfs_type bfs_mode_to_type(mode_t mode) { } struct bfs_dir { -#if BFS_GETDENTS +#if BFS_USE_GETDENTS alignas(sys_dirent) int fd; unsigned short pos; unsigned short size; @@ -114,7 +114,7 @@ struct bfs_dir { bool eof; }; -#if BFS_GETDENTS +#if BFS_USE_GETDENTS # define DIR_SIZE (64 << 10) # define BUF_SIZE (DIR_SIZE - sizeof(struct bfs_dir)) #else @@ -143,7 +143,7 @@ int bfs_opendir(struct bfs_dir *dir, int at_fd, const char *at_path) { return -1; } -#if BFS_GETDENTS +#if BFS_USE_GETDENTS dir->fd = fd; dir->pos = 0; dir->size = 0; @@ -163,7 +163,7 @@ int bfs_opendir(struct bfs_dir *dir, int at_fd, const char *at_path) { } int bfs_dirfd(const struct bfs_dir *dir) { -#if BFS_GETDENTS +#if BFS_USE_GETDENTS return dir->fd; #else return dirfd(dir->dir); @@ -171,7 +171,7 @@ int bfs_dirfd(const struct bfs_dir *dir) { } int bfs_polldir(struct bfs_dir *dir) { -#if BFS_GETDENTS +#if BFS_USE_GETDENTS if (dir->pos < dir->size) { return 1; } else if (dir->eof) { @@ -203,7 +203,7 @@ int bfs_polldir(struct bfs_dir *dir) { } return 1; -#else // !BFS_GETDENTS +#else // !BFS_USE_GETDENTS if (dir->de) { return 1; } else if (dir->eof) { @@ -227,7 +227,7 @@ int bfs_polldir(struct bfs_dir *dir) { static int bfs_getdent(struct bfs_dir *dir, const sys_dirent **de) { int ret = bfs_polldir(dir); if (ret > 0) { -#if BFS_GETDENTS +#if BFS_USE_GETDENTS char *buf = (char *)(dir + 1); *de = (const sys_dirent *)(buf + dir->pos); dir->pos += (*de)->d_reclen; @@ -283,7 +283,7 @@ int bfs_readdir(struct bfs_dir *dir, struct bfs_dirent *de) { } int bfs_closedir(struct bfs_dir *dir) { -#if BFS_GETDENTS +#if BFS_USE_GETDENTS int ret = xclose(dir->fd); #else int ret = closedir(dir->dir); @@ -297,7 +297,7 @@ int bfs_closedir(struct bfs_dir *dir) { } int bfs_fdclosedir(struct bfs_dir *dir, bool same_fd) { -#if BFS_GETDENTS +#if BFS_USE_GETDENTS int ret = dir->fd; #elif __FreeBSD__ int ret = fdclosedir(dir->dir); diff --git a/src/mtab.c b/src/mtab.c index e5c25ba..384fdfc 100644 --- a/src/mtab.c +++ b/src/mtab.c @@ -14,22 +14,22 @@ #include #include -#if BFS_USE_MNTENT_H -# define BFS_MNTENT 1 -#elif BSD -# define BFS_MNTINFO 1 -#elif __SVR4 -# define BFS_MNTTAB 1 +#if !defined(BFS_USE_MNTENT) && BFS_USE_MNTENT_H +# define BFS_USE_MNTENT true +#elif !defined(BFS_USE_MNTINFO) && BSD +# define BFS_USE_MNTINFO true +#elif !defined(BFS_USE_MNTTAB) && __SVR4 +# define BFS_USE_MNTTAB true #endif -#if BFS_MNTENT +#if BFS_USE_MNTENT # include # include # include -#elif BFS_MNTINFO +#elif BFS_USE_MNTINFO # include # include -#elif BFS_MNTTAB +#elif BFS_USE_MNTTAB # include # include #endif @@ -45,7 +45,7 @@ struct bfs_mtab_entry { }; struct bfs_mtab { - /** The list of mount points. */ + /** The array of mount points. */ struct bfs_mtab_entry *entries; /** The basenames of every mount point. */ struct trie names; @@ -59,7 +59,7 @@ struct bfs_mtab { /** * Add an entry to the mount table. */ -static int bfs_mtab_add(struct bfs_mtab *mtab, const char *path, const char *type) { +static inline int bfs_mtab_add(struct bfs_mtab *mtab, const char *path, const char *type) { struct bfs_mtab_entry entry = { .path = strdup(path), .type = strdup(type), @@ -98,7 +98,7 @@ struct bfs_mtab *bfs_mtab_parse(void) { int error = 0; -#if BFS_MNTENT +#if BFS_USE_MNTENT FILE *file = setmntent(_PATH_MOUNTED, "r"); if (!file) { @@ -121,7 +121,7 @@ struct bfs_mtab *bfs_mtab_parse(void) { endmntent(file); -#elif BFS_MNTINFO +#elif BFS_USE_MNTINFO #if __NetBSD__ typedef struct statvfs bfs_statfs; @@ -143,7 +143,7 @@ struct bfs_mtab *bfs_mtab_parse(void) { } } -#elif BFS_MNTTAB +#elif BFS_USE_MNTTAB FILE *file = xfopen(MNTTAB, O_RDONLY | O_CLOEXEC); if (!file) { diff --git a/src/parse.c b/src/parse.c index cf4f696..1321270 100644 --- a/src/parse.c +++ b/src/parse.c @@ -2296,7 +2296,7 @@ static struct bfs_expr *parse_regextype(struct parser_state *state, int arg1, in state->regex_type = BFS_REGEX_POSIX_BASIC; } else if (strcmp(type, "posix-extended") == 0) { state->regex_type = BFS_REGEX_POSIX_EXTENDED; -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA } else if (strcmp(type, "emacs") == 0) { state->regex_type = BFS_REGEX_EMACS; } else if (strcmp(type, "grep") == 0) { @@ -2318,7 +2318,7 @@ list_types: cfprintf(cfile, " ${bld}posix-basic${rs}: POSIX basic regular expressions (BRE)\n"); cfprintf(cfile, " ${bld}posix-extended${rs}: POSIX extended regular expressions (ERE)\n"); cfprintf(cfile, " ${bld}ed${rs}: Like ${grn}ed${rs} (same as ${bld}posix-basic${rs})\n"); -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA cfprintf(cfile, " ${bld}emacs${rs}: Like ${grn}emacs${rs}\n"); cfprintf(cfile, " ${bld}grep${rs}: Like ${grn}grep${rs}\n"); #endif diff --git a/src/stat.c b/src/stat.c index e3e5aaa..7a413cd 100644 --- a/src/stat.c +++ b/src/stat.c @@ -14,15 +14,17 @@ #include #if defined(STATX_BASIC_STATS) && (!__ANDROID__ || __ANDROID_API__ >= 30) -# define BFS_LIBC_STATX true +# define BFS_HAS_LIBC_STATX true #elif __linux__ # include # include # include #endif -#if BFS_LIBC_STATX || defined(SYS_statx) -# define BFS_STATX true +#ifndef BFS_USE_STATX +# if BFS_HAS_LIBC_STATX || defined(SYS_statx) +# define BFS_USE_STATX true +# endif #endif const char *bfs_stat_field_name(enum bfs_stat_field field) { @@ -128,13 +130,13 @@ static int bfs_stat_impl(int at_fd, const char *at_path, int at_flags, struct bf return ret; } -#if BFS_STATX +#if BFS_USE_STATX /** * Wrapper for the statx() system call, which had no glibc wrapper prior to 2.28. */ static int bfs_statx(int at_fd, const char *at_path, int at_flags, unsigned int mask, struct statx *buf) { -#if BFS_LIBC_STATX +#if BFS_HAS_LIBC_STATX int ret = statx(at_fd, at_path, at_flags, mask, buf); #else int ret = syscall(SYS_statx, at_fd, at_path, at_flags, mask, buf); @@ -242,13 +244,13 @@ static int bfs_statx_impl(int at_fd, const char *at_path, int at_flags, struct b return ret; } -#endif // BFS_STATX +#endif // BFS_USE_STATX /** * Calls the stat() implementation with explicit flags. */ static int bfs_stat_explicit(int at_fd, const char *at_path, int at_flags, int x_flags, struct bfs_stat *buf) { -#if BFS_STATX +#if BFS_USE_STATX static atomic bool has_statx = true; if (load(&has_statx, relaxed)) { diff --git a/src/trie.c b/src/trie.c index 992d42b..0206509 100644 --- a/src/trie.c +++ b/src/trie.c @@ -94,7 +94,7 @@ bfs_static_assert(CHAR_WIDTH == 8); -#if BFS_TARGET_CLONES && (__i386__ || __x86_64__) +#if BFS_USE_TARGET_CLONES && (__i386__ || __x86_64__) # define TARGET_CLONES_POPCNT __attribute__((target_clones("popcnt", "default"))) #else # define TARGET_CLONES_POPCNT diff --git a/src/xregex.c b/src/xregex.c index ab5f793..88df082 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -11,7 +11,7 @@ #include #include -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA # include # include #else @@ -19,7 +19,7 @@ #endif struct bfs_regex { -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA unsigned char *pattern; OnigRegex impl; int err; @@ -30,7 +30,7 @@ struct bfs_regex { #endif }; -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA static int bfs_onig_status; static OnigEncoding bfs_onig_enc; @@ -121,7 +121,7 @@ int bfs_regcomp(struct bfs_regex **preg, const char *pattern, enum bfs_regex_typ return -1; } -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA // onig_error_code_to_str() says // // don't call this after the pattern argument of onig_new() is freed @@ -204,7 +204,7 @@ fail: int bfs_regexec(struct bfs_regex *regex, const char *str, enum bfs_regexec_flags flags) { size_t len = strlen(str); -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA const unsigned char *ustr = (const unsigned char *)str; const unsigned char *end = ustr + len; @@ -263,7 +263,7 @@ int bfs_regexec(struct bfs_regex *regex, const char *str, enum bfs_regexec_flags void bfs_regfree(struct bfs_regex *regex) { if (regex) { -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA onig_free(regex->impl); free(regex->pattern); #else @@ -278,7 +278,7 @@ char *bfs_regerror(const struct bfs_regex *regex) { return strdup(strerror(ENOMEM)); } -#if BFS_WITH_ONIGURUMA +#if BFS_USE_ONIGURUMA unsigned char *str = malloc(ONIG_MAX_ERROR_MESSAGE_LEN); if (str) { onig_error_code_to_str(str, regex->err, ®ex->einfo); -- cgit v1.2.3 From 1313875b02c690ca5a40e585d24fdec240bb419d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 26 Jun 2023 15:04:13 -0400 Subject: thread: Wrap more pthread APIs --- src/ioq.c | 9 ++---- src/lock.h | 85 ------------------------------------------------ src/main.c | 2 +- src/thread.h | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/xregex.c | 5 ++- 5 files changed, 109 insertions(+), 95 deletions(-) delete mode 100644 src/lock.h create mode 100644 src/thread.h (limited to 'src/xregex.c') diff --git a/src/ioq.c b/src/ioq.c index 457ead7..1160b34 100644 --- a/src/ioq.c +++ b/src/ioq.c @@ -9,7 +9,7 @@ #include "config.h" #include "diag.h" #include "dir.h" -#include "lock.h" +#include "thread.h" #include "sanity.h" #include #include @@ -335,8 +335,7 @@ struct ioq *ioq_create(size_t depth, size_t nthreads) { } for (size_t i = 0; i < nthreads; ++i) { - errno = pthread_create(&ioq->threads[i], NULL, ioq_work, ioq); - if (errno != 0) { + if (thread_create(&ioq->threads[i], NULL, ioq_work, ioq) != 0) { goto fail; } ++ioq->nthreads; @@ -417,9 +416,7 @@ void ioq_destroy(struct ioq *ioq) { ioq_cancel(ioq); for (size_t i = 0; i < ioq->nthreads; ++i) { - if (pthread_join(ioq->threads[i], NULL) != 0) { - abort(); - } + thread_join(ioq->threads[i], NULL); } ioqq_destroy(ioq->ready); diff --git a/src/lock.h b/src/lock.h deleted file mode 100644 index 2b5f951..0000000 --- a/src/lock.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright © Tavian Barnes -// SPDX-License-Identifier: 0BSD - -/** - * Wrappers for POSIX synchronization primitives. - */ - -#ifndef BFS_LOCK_H -#define BFS_LOCK_H - -#include "diag.h" -#include -#include -#include - -#define lock_verify(expr, cond) \ - bfs_verify((errno = (expr), (cond)), "%s: %s", #expr, strerror(errno)) - -/** - * Wrapper for pthread_mutex_init(). - * - * @return - * 0 on success, -1 on error. - */ -#define mutex_init(mutex, attr) \ - ((errno = pthread_mutex_init(mutex, attr)) ? -1 : 0) - -/** - * Wrapper for pthread_mutex_lock(). - */ -#define mutex_lock(mutex) \ - lock_verify(pthread_mutex_lock(mutex), errno == 0) - -/** - * Wrapper for pthread_mutex_trylock(). - * - * @return - * Whether the mutex was locked. - */ -#define mutex_trylock(mutex) \ - (lock_verify(pthread_mutex_trylock(mutex), errno == 0 || errno == EBUSY), errno == 0) - -/** - * Wrapper for pthread_mutex_unlock(). - */ -#define mutex_unlock(mutex) \ - lock_verify(pthread_mutex_unlock(mutex), errno == 0) - -/** - * Wrapper for pthread_mutex_destroy(). - */ -#define mutex_destroy(mutex) \ - lock_verify(pthread_mutex_destroy(mutex), errno == 0) - -/** - * Wrapper for pthread_cond_init(). - */ -#define cond_init(cond, attr) \ - ((errno = pthread_cond_init(cond, attr)) ? -1 : 0) - -/** - * Wrapper for pthread_cond_wait(). - */ -#define cond_wait(cond, mutex) \ - lock_verify(pthread_cond_wait(cond, mutex), errno == 0) - -/** - * Wrapper for pthread_cond_signal(). - */ -#define cond_signal(cond) \ - lock_verify(pthread_cond_signal(cond), errno == 0) - -/** - * Wrapper for pthread_cond_broadcast(). - */ -#define cond_broadcast(cond) \ - lock_verify(pthread_cond_broadcast(cond), errno == 0) - -/** - * Wrapper for pthread_cond_destroy(). - */ -#define cond_destroy(cond) \ - lock_verify(pthread_cond_destroy(cond), errno == 0) - -#endif // BFS_LOCK_H diff --git a/src/main.c b/src/main.c index b7a08c1..b26be85 100644 --- a/src/main.c +++ b/src/main.c @@ -34,11 +34,11 @@ * - fsade.[ch] (a facade over non-standard filesystem features) * - ioq.[ch] (an async I/O queue) * - list.h (linked list macros) - * - lock.h (mutexes, condition variables, etc.) * - mtab.[ch] (parses the system's mount table) * - pwcache.[ch] (a cache for the user/group tables) * - sanity.h (sanitizer interfaces) * - stat.[ch] (wraps stat(), or statx() on Linux) + * - thread.h (multi-threading) * - trie.[ch] (a trie set/map implementation) * - typo.[ch] (fuzzy matching for typos) * - xregex.[ch] (regular expression support) diff --git a/src/thread.h b/src/thread.h new file mode 100644 index 0000000..b2edf17 --- /dev/null +++ b/src/thread.h @@ -0,0 +1,103 @@ +// Copyright © Tavian Barnes +// SPDX-License-Identifier: 0BSD + +/** + * Wrappers for POSIX threading APIs. + */ + +#ifndef BFS_THREAD_H +#define BFS_THREAD_H + +#include "diag.h" +#include +#include +#include + +#define thread_verify(expr, cond) \ + bfs_verify((errno = (expr), (cond)), "%s: %s", #expr, strerror(errno)) + +/** + * Wrapper for pthread_create(). + * + * @return + * 0 on success, -1 on error. + */ +#define thread_create(thread, attr, fn, arg) \ + ((errno = pthread_create(thread, attr, fn, arg)) ? -1 : 0) + +/** + * Wrapper for pthread_join(). + */ +#define thread_join(thread, ret) \ + thread_verify(pthread_join(thread, ret), errno == 0) + +/** + * Wrapper for pthread_mutex_init(). + */ +#define mutex_init(mutex, attr) \ + ((errno = pthread_mutex_init(mutex, attr)) ? -1 : 0) + +/** + * Wrapper for pthread_mutex_lock(). + */ +#define mutex_lock(mutex) \ + thread_verify(pthread_mutex_lock(mutex), errno == 0) + +/** + * Wrapper for pthread_mutex_trylock(). + * + * @return + * Whether the mutex was locked. + */ +#define mutex_trylock(mutex) \ + (thread_verify(pthread_mutex_trylock(mutex), errno == 0 || errno == EBUSY), errno == 0) + +/** + * Wrapper for pthread_mutex_unlock(). + */ +#define mutex_unlock(mutex) \ + thread_verify(pthread_mutex_unlock(mutex), errno == 0) + +/** + * Wrapper for pthread_mutex_destroy(). + */ +#define mutex_destroy(mutex) \ + thread_verify(pthread_mutex_destroy(mutex), errno == 0) + +/** + * Wrapper for pthread_cond_init(). + */ +#define cond_init(cond, attr) \ + ((errno = pthread_cond_init(cond, attr)) ? -1 : 0) + +/** + * Wrapper for pthread_cond_wait(). + */ +#define cond_wait(cond, mutex) \ + thread_verify(pthread_cond_wait(cond, mutex), errno == 0) + +/** + * Wrapper for pthread_cond_signal(). + */ +#define cond_signal(cond) \ + thread_verify(pthread_cond_signal(cond), errno == 0) + +/** + * Wrapper for pthread_cond_broadcast(). + */ +#define cond_broadcast(cond) \ + thread_verify(pthread_cond_broadcast(cond), errno == 0) + +/** + * Wrapper for pthread_cond_destroy(). + */ +#define cond_destroy(cond) \ + thread_verify(pthread_cond_destroy(cond), errno == 0) + +/** + * Wrapper for pthread_once(). + */ +#define call_once(once, fn) \ + thread_verify(pthread_once(once, fn), errno == 0) + +#endif // BFS_THREAD_H diff --git a/src/xregex.c b/src/xregex.c index 88df082..beb6676 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -5,6 +5,7 @@ #include "alloc.h" #include "config.h" #include "diag.h" +#include "thread.h" #include "sanity.h" #include #include @@ -106,9 +107,7 @@ static void bfs_onig_once(void) { /** Initialize Oniguruma. */ static int bfs_onig_initialize(OnigEncoding *enc) { static pthread_once_t once = PTHREAD_ONCE_INIT; - if (pthread_once(&once, bfs_onig_once) != 0) { - return ONIGERR_FAIL_TO_INITIALIZE; - } + call_once(&once, bfs_onig_once); *enc = bfs_onig_enc; return bfs_onig_status; -- cgit v1.2.3 From 52de184ba28551734e1cb13233588504ab5f62ec Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 27 Sep 2023 12:11:15 -0400 Subject: Formatting fixes --- src/color.c | 6 +++--- src/ctx.c | 1 - src/darray.c | 4 ++-- src/diag.c | 8 ++++---- src/diag.h | 2 +- src/dstring.c | 4 ++-- src/eval.c | 15 +++++++-------- src/exec.c | 16 ++++++++-------- src/fsade.c | 6 +++--- src/ioq.c | 2 +- src/opt.c | 11 +++++------ src/opt.h | 1 - src/parse.c | 45 ++++++++++++++++++++++----------------------- src/printf.c | 46 +++++++++++++++++++++++----------------------- src/pwcache.c | 1 - src/stat.c | 2 +- src/trie.c | 2 +- src/trie.h | 4 ++-- src/xregex.c | 2 +- src/xspawn.c | 2 +- src/xtime.c | 12 ++++++------ tests/bfstd.c | 2 +- tests/mksock.c | 2 +- tests/trie.c | 4 ++-- tests/xtimegm.c | 6 +++--- 25 files changed, 100 insertions(+), 106 deletions(-) (limited to 'src/xregex.c') diff --git a/src/color.c b/src/color.c index 8d0b995..788d35d 100644 --- a/src/color.c +++ b/src/color.c @@ -1143,11 +1143,11 @@ static int print_expr(CFILE *cfile, const struct bfs_expr *expr, bool verbose) { if (verbose) { double rate = 0.0, time = 0.0; if (expr->evaluations) { - rate = 100.0*expr->successes/expr->evaluations; - time = (1.0e9*expr->elapsed.tv_sec + expr->elapsed.tv_nsec)/expr->evaluations; + rate = 100.0 * expr->successes / expr->evaluations; + time = (1.0e9 * expr->elapsed.tv_sec + expr->elapsed.tv_nsec) / expr->evaluations; } if (cbuff(cfile, " [${ylw}%zu${rs}/${ylw}%zu${rs}=${ylw}%g%%${rs}; ${ylw}%gns${rs}]", - expr->successes, expr->evaluations, rate, time)) { + expr->successes, expr->evaluations, rate, time)) { return -1; } } diff --git a/src/ctx.c b/src/ctx.c index 3a44e68..9a24a33 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -168,7 +168,6 @@ void bfs_ctx_flush(const struct bfs_ctx *ctx) { } else if (cfile == ctx->cout) { bfs_error(ctx, "(standard output): %m.\n"); } - } // Flush the user/group caches, in case the executed command edits the diff --git a/src/darray.c b/src/darray.c index 42b8397..3e66a55 100644 --- a/src/darray.c +++ b/src/darray.c @@ -55,7 +55,7 @@ void *darray_push(void *da, const void *item, size_t size) { size_t i = header->length++; if (i >= capacity) { capacity *= 2; - header = realloc(header, sizeof(*header) + capacity*size); + header = realloc(header, sizeof(*header) + capacity * size); if (!header) { // This failure will be detected by darray_check() return da; @@ -64,7 +64,7 @@ void *darray_push(void *da, const void *item, size_t size) { } char *data = darray_data(header); - memcpy(data + i*size, item, size); + memcpy(data + i * size, item, size); return data; } diff --git a/src/diag.c b/src/diag.c index fa9db39..fa66525 100644 --- a/src/diag.c +++ b/src/diag.c @@ -4,9 +4,9 @@ #include "diag.h" #include "alloc.h" #include "bfstd.h" -#include "ctx.h" #include "color.h" #include "config.h" +#include "ctx.h" #include "dstring.h" #include "expr.h" #include @@ -31,14 +31,14 @@ void bfs_perror(const struct bfs_ctx *ctx, const char *str) { bfs_error(ctx, "%s: %m.\n", str); } -void bfs_error(const struct bfs_ctx *ctx, const char *format, ...) { +void bfs_error(const struct bfs_ctx *ctx, const char *format, ...) { va_list args; va_start(args, format); bfs_verror(ctx, format, args); va_end(args); } -bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...) { +bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...) { va_list args; va_start(args, format); bool ret = bfs_vwarning(ctx, format, args); @@ -46,7 +46,7 @@ bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...) { return ret; } -bool bfs_debug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *format, ...) { +bool bfs_debug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *format, ...) { va_list args; va_start(args, format); bool ret = bfs_vdebug(ctx, flag, format, args); diff --git a/src/diag.h b/src/diag.h index e019db0..fea8847 100644 --- a/src/diag.h +++ b/src/diag.h @@ -8,8 +8,8 @@ #ifndef BFS_DIAG_H #define BFS_DIAG_H -#include "ctx.h" #include "config.h" +#include "ctx.h" #include /** diff --git a/src/dstring.c b/src/dstring.c index ef4e733..f947741 100644 --- a/src/dstring.c +++ b/src/dstring.c @@ -169,7 +169,7 @@ char *dstrprintf(const char *format, ...) { char *dstrvprintf(const char *format, va_list args) { // Guess a capacity to try to avoid reallocating - dchar *str = dstralloc(2*strlen(format)); + dchar *str = dstralloc(2 * strlen(format)); if (!str) { return NULL; } @@ -195,7 +195,7 @@ int dstrcatf(dchar **str, const char *format, ...) { int dstrvcatf(dchar **str, const char *format, va_list args) { // Guess a capacity to try to avoid calling vsnprintf() twice size_t len = dstrlen(*str); - dstreserve(str, len + 2*strlen(format)); + dstreserve(str, len + 2 * strlen(format)); size_t cap = dstrheader(*str)->capacity; va_list copy; diff --git a/src/eval.c b/src/eval.c index 3550751..9f4896a 100644 --- a/src/eval.c +++ b/src/eval.c @@ -239,7 +239,7 @@ bool eval_time(const struct bfs_expr *expr, struct bfs_eval *state) { time_t diff = timespec_diff(&expr->reftime, time); switch (expr->time_unit) { case BFS_DAYS: - diff /= 60*24; + diff /= 60 * 24; fallthru; case BFS_MINUTES: diff /= 60; @@ -271,7 +271,7 @@ bool eval_used(const struct bfs_expr *expr, struct bfs_eval *state) { return false; } - long long day_seconds = 60*60*24; + long long day_seconds = 60 * 60 * 24; diff = (diff + day_seconds - 1) / day_seconds; return bfs_expr_cmp(expr, diff); } @@ -685,7 +685,7 @@ bool eval_fls(const struct bfs_expr *expr, struct bfs_eval *state) { uintmax_t ino = statbuf->ino; uintmax_t block_size = ctx->posixly_correct ? 512 : 1024; - uintmax_t blocks = ((uintmax_t)statbuf->blocks*BFS_STAT_BLKSIZE + block_size - 1)/block_size; + uintmax_t blocks = ((uintmax_t)statbuf->blocks * BFS_STAT_BLKSIZE + block_size - 1) / block_size; char mode[11]; xstrmode(statbuf->mode, mode); char acl = bfs_check_acl(ftwbuf) > 0 ? '+' : ' '; @@ -721,8 +721,8 @@ bool eval_fls(const struct bfs_expr *expr, struct bfs_eval *state) { time_t time = statbuf->mtime.tv_sec; time_t now = ctx->now.tv_sec; - time_t six_months_ago = now - 6*30*24*60*60; - time_t tomorrow = now + 24*60*60; + time_t six_months_ago = now - 6 * 30 * 24 * 60 * 60; + time_t tomorrow = now + 24 * 60 * 60; struct tm tm; if (xlocaltime(&time, &tm) != 0) { goto error; @@ -823,7 +823,6 @@ bool eval_fprintx(const struct bfs_expr *expr, struct bfs_eval *state) { ++path; } - if (fputc('\n', file) == EOF) { goto error; } @@ -905,7 +904,7 @@ bool eval_size(const struct bfs_expr *expr, struct bfs_eval *state) { }; off_t scale = scales[expr->size_unit]; - off_t size = (statbuf->size + scale - 1)/scale; // Round up + off_t size = (statbuf->size + scale - 1) / scale; // Round up return bfs_expr_cmp(expr, size); } @@ -918,7 +917,7 @@ bool eval_sparse(const struct bfs_expr *expr, struct bfs_eval *state) { return false; } - blkcnt_t expected = (statbuf->size + BFS_STAT_BLKSIZE - 1)/BFS_STAT_BLKSIZE; + blkcnt_t expected = (statbuf->size + BFS_STAT_BLKSIZE - 1) / BFS_STAT_BLKSIZE; return statbuf->blocks < expected; } diff --git a/src/exec.c b/src/exec.c index 7b55522..0e0d585 100644 --- a/src/exec.c +++ b/src/exec.c @@ -5,9 +5,9 @@ #include "alloc.h" #include "bfstd.h" #include "bftw.h" -#include "ctx.h" #include "color.h" #include "config.h" +#include "ctx.h" #include "diag.h" #include "dstring.h" #include "xspawn.h" @@ -348,7 +348,7 @@ static int bfs_exec_spawn(const struct bfs_exec *execbuf) { if (execbuf->flags & BFS_EXEC_MULTI) { bfs_exec_debug(execbuf, "Executing '%s' ... [%zu arguments] (size %zu)\n", - execbuf->argv[0], execbuf->argc - 1, execbuf->arg_size); + execbuf->argv[0], execbuf->argc - 1, execbuf->arg_size); } else { bfs_exec_debug(execbuf, "Executing '%s' ... [%zu arguments]\n", execbuf->argv[0], execbuf->argc - 1); } @@ -471,7 +471,7 @@ static bool bfs_exec_args_remain(const struct bfs_exec *execbuf) { static size_t bfs_exec_estimate_max(const struct bfs_exec *execbuf) { size_t min = execbuf->arg_min; size_t max = execbuf->arg_max; - return min + (max - min)/2; + return min + (max - min) / 2; } /** Update the ARG_MAX lower bound from a successful execution. */ @@ -486,7 +486,7 @@ static void bfs_exec_update_min(struct bfs_exec *execbuf) { size_t estimate = bfs_exec_estimate_max(execbuf); bfs_exec_debug(execbuf, "ARG_MAX between [%zu, %zu], trying %zu\n", - execbuf->arg_min, execbuf->arg_max, estimate); + execbuf->arg_min, execbuf->arg_max, estimate); } } @@ -502,7 +502,7 @@ static size_t bfs_exec_update_max(struct bfs_exec *execbuf) { // Trim a fraction off the max size to avoid repeated failures near the // top end of the working range - size -= size/16; + size -= size / 16; if (size < execbuf->arg_max) { execbuf->arg_max = size; @@ -515,7 +515,7 @@ static size_t bfs_exec_update_max(struct bfs_exec *execbuf) { // Binary search for a more precise bound size_t estimate = bfs_exec_estimate_max(execbuf); bfs_exec_debug(execbuf, "ARG_MAX between [%zu, %zu], trying %zu\n", - execbuf->arg_min, execbuf->arg_max, estimate); + execbuf->arg_min, execbuf->arg_max, estimate); return estimate; } @@ -589,7 +589,7 @@ static bool bfs_exec_would_overflow(const struct bfs_exec *execbuf, const char * size_t next_size = execbuf->arg_size + bfs_exec_arg_size(arg); if (next_size > arg_max) { bfs_exec_debug(execbuf, "Command size (%zu) would exceed maximum (%zu), executing buffered command\n", - next_size, arg_max); + next_size, arg_max); return true; } @@ -601,7 +601,7 @@ static int bfs_exec_push(struct bfs_exec *execbuf, char *arg) { execbuf->argv[execbuf->argc] = arg; if (execbuf->argc + 1 >= execbuf->argv_cap) { - size_t cap = 2*execbuf->argv_cap; + size_t cap = 2 * execbuf->argv_cap; char **argv = realloc(execbuf->argv, sizeof_array(char *, cap)); if (!argv) { return -1; diff --git a/src/fsade.c b/src/fsade.c index 8dec5a8..cbff47b 100644 --- a/src/fsade.c +++ b/src/fsade.c @@ -3,9 +3,9 @@ #include "fsade.h" #include "atomic.h" -#include "config.h" #include "bfstd.h" #include "bftw.h" +#include "config.h" #include "dir.h" #include "dstring.h" #include "sanity.h" @@ -292,7 +292,7 @@ int bfs_check_xattrs(const struct BFTW *ftwbuf) { ssize_t len; #if BFS_USE_SYS_EXTATTR_H - ssize_t (*extattr_list)(const char *, int, void*, size_t) = + ssize_t (*extattr_list)(const char *, int, void *, size_t) = ftwbuf->type == BFS_LNK ? extattr_list_link : extattr_list_file; len = extattr_list(path, EXTATTR_NAMESPACE_SYSTEM, NULL, 0); @@ -331,7 +331,7 @@ int bfs_check_xattr_named(const struct BFTW *ftwbuf, const char *name) { ssize_t len; #if BFS_USE_SYS_EXTATTR_H - ssize_t (*extattr_get)(const char *, int, const char *, void*, size_t) = + ssize_t (*extattr_get)(const char *, int, const char *, void *, size_t) = ftwbuf->type == BFS_LNK ? extattr_get_link : extattr_get_file; len = extattr_get(path, EXTATTR_NAMESPACE_SYSTEM, name, NULL, 0); diff --git a/src/ioq.c b/src/ioq.c index f7ca8c6..d3ba2de 100644 --- a/src/ioq.c +++ b/src/ioq.c @@ -9,8 +9,8 @@ #include "config.h" #include "diag.h" #include "dir.h" -#include "thread.h" #include "sanity.h" +#include "thread.h" #include #include #include diff --git a/src/opt.c b/src/opt.c index 14de081..77c2798 100644 --- a/src/opt.c +++ b/src/opt.c @@ -535,8 +535,8 @@ static struct bfs_expr *optimize_and_expr(const struct opt_state *state, struct expr->pure = lhs->pure && rhs->pure; expr->always_true = lhs->always_true && rhs->always_true; expr->always_false = lhs->always_false || rhs->always_false; - expr->cost = lhs->cost + lhs->probability*rhs->cost; - expr->probability = lhs->probability*rhs->probability; + expr->cost = lhs->cost + lhs->probability * rhs->cost; + expr->probability = lhs->probability * rhs->probability; return expr; } @@ -606,8 +606,8 @@ static struct bfs_expr *optimize_or_expr(const struct opt_state *state, struct b expr->pure = lhs->pure && rhs->pure; expr->always_true = lhs->always_true || rhs->always_true; expr->always_false = lhs->always_false && rhs->always_false; - expr->cost = lhs->cost + (1 - lhs->probability)*rhs->cost; - expr->probability = lhs->probability + rhs->probability - lhs->probability*rhs->probability; + expr->cost = lhs->cost + (1 - lhs->probability) * rhs->cost; + expr->probability = lhs->probability + rhs->probability - lhs->probability * rhs->probability; return expr; } @@ -1078,7 +1078,6 @@ static const struct { {eval_xattrname, 0.01}, }; - /** * Table of simple predicates. */ @@ -1331,7 +1330,7 @@ static bool reorder_expr_recursive(const struct opt_state *state, struct bfs_exp if (expr->eval_fn == eval_and || expr->eval_fn == eval_or) { if (lhs->pure && rhs->pure) { float rhs_prob = expr->eval_fn == eval_and ? rhs->probability : 1.0 - rhs->probability; - float swapped_cost = rhs->cost + rhs_prob*lhs->cost; + float swapped_cost = rhs->cost + rhs_prob * lhs->cost; ret |= reorder_expr(state, expr, swapped_cost); } } diff --git a/src/opt.h b/src/opt.h index 28cadb9..4aac129 100644 --- a/src/opt.h +++ b/src/opt.h @@ -21,4 +21,3 @@ struct bfs_ctx; int bfs_optimize(struct bfs_ctx *ctx); #endif // BFS_OPT_H - diff --git a/src/parse.c b/src/parse.c index 3416d9e..7766a7b 100644 --- a/src/parse.c +++ b/src/parse.c @@ -41,8 +41,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -1797,10 +1797,10 @@ static int parse_reftime(const struct parser_state *state, struct bfs_expr *expr #else int gmtoff = -timezone; #endif - int tz_hour = gmtoff/3600; - int tz_min = (labs(gmtoff)/60)%60; + int tz_hour = gmtoff / 3600; + int tz_min = (labs(gmtoff) / 60) % 60; fprintf(stderr, " - %04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d\n", - year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tz_hour, tz_min); + year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tz_hour, tz_min); if (xgmtime(&state->now.tv_sec, &tm) != 0) { parse_perror(state, "xgmtime()"); @@ -1832,8 +1832,8 @@ static struct bfs_expr *parse_newerxy(struct parser_state *state, int arg1, int expr->stat_field = parse_newerxy_field(arg[6]); if (!expr->stat_field) { parse_expr_error(state, expr, - "For ${blu}-newer${bld}XY${rs}, ${bld}X${rs} should be ${bld}a${rs}, ${bld}c${rs}, ${bld}m${rs}, or ${bld}B${rs}, not ${err}%c${rs}.\n", - arg[6]); + "For ${blu}-newer${bld}XY${rs}, ${bld}X${rs} should be ${bld}a${rs}, ${bld}c${rs}, ${bld}m${rs}, or ${bld}B${rs}, not ${err}%c${rs}.\n", + arg[6]); goto fail; } @@ -1845,8 +1845,8 @@ static struct bfs_expr *parse_newerxy(struct parser_state *state, int arg1, int enum bfs_stat_field field = parse_newerxy_field(arg[7]); if (!field) { parse_expr_error(state, expr, - "For ${blu}-newer${bld}XY${rs}, ${bld}Y${rs} should be ${bld}a${rs}, ${bld}c${rs}, ${bld}m${rs}, ${bld}B${rs}, or ${bld}t${rs}, not ${err}%c${rs}.\n", - arg[7]); + "For ${blu}-newer${bld}XY${rs}, ${bld}Y${rs} should be ${bld}a${rs}, ${bld}c${rs}, ${bld}m${rs}, ${bld}B${rs}, or ${bld}t${rs}, not ${err}%c${rs}.\n", + arg[7]); goto fail; } @@ -1855,7 +1855,6 @@ static struct bfs_expr *parse_newerxy(struct parser_state *state, int arg1, int goto fail; } - const struct timespec *reftime = bfs_stat_time(&sb, field); if (!reftime) { parse_expr_error(state, expr, "Couldn't get file %s.\n", bfs_stat_field_name(field)); @@ -1905,7 +1904,7 @@ static struct bfs_expr *parse_nohidden(struct parser_state *state, int arg1, int */ static struct bfs_expr *parse_noleaf(struct parser_state *state, int arg1, int arg2) { parse_warning(state, "${ex}%s${rs} does not apply the optimization that ${blu}%s${rs} inhibits.\n\n", - BFS_COMMAND, state->argv[0]); + BFS_COMMAND, state->argv[0]); return parse_nullary_option(state); } @@ -2730,12 +2729,12 @@ static struct bfs_expr *parse_help(struct parser_state *state, int arg1, int arg } cfprintf(cout, "Usage: ${ex}%s${rs} [${cyn}flags${rs}...] [${mag}paths${rs}...] [${blu}expression${rs}...]\n\n", - state->command); + state->command); cfprintf(cout, "${ex}%s${rs} is compatible with ${ex}find${rs}, with some extensions. " - "${cyn}Flags${rs} (${cyn}-H${rs}/${cyn}-L${rs}/${cyn}-P${rs} etc.), ${mag}paths${rs},\n" - "and ${blu}expressions${rs} may be freely mixed in any order.\n\n", - BFS_COMMAND); + "${cyn}Flags${rs} (${cyn}-H${rs}/${cyn}-L${rs}/${cyn}-P${rs} etc.), ${mag}paths${rs},\n" + "and ${blu}expressions${rs} may be freely mixed in any order.\n\n", + BFS_COMMAND); cfprintf(cout, "${bld}Flags:${rs}\n\n"); @@ -2807,7 +2806,7 @@ static struct bfs_expr *parse_help(struct parser_state *state, int arg1, int arg cfprintf(cout, " ${blu}-ignore_readdir_race${rs}\n"); cfprintf(cout, " ${blu}-noignore_readdir_race${rs}\n"); cfprintf(cout, " Whether to report an error if ${ex}%s${rs} detects that the file tree is modified\n", - BFS_COMMAND); + BFS_COMMAND); cfprintf(cout, " during the search (default: ${blu}-noignore_readdir_race${rs})\n"); cfprintf(cout, " ${blu}-maxdepth${rs} ${bld}N${rs}\n"); cfprintf(cout, " ${blu}-mindepth${rs} ${bld}N${rs}\n"); @@ -3462,14 +3461,14 @@ static struct bfs_expr *parse_whole_expr(struct parser_state *state) { if (state->mount_arg && state->xdev_arg) { parse_conflict_warning(state, state->mount_arg, 1, state->xdev_arg, 1, - "${blu}%s${rs} is redundant in the presence of ${blu}%s${rs}.\n\n", - state->xdev_arg[0], state->mount_arg[0]); + "${blu}%s${rs} is redundant in the presence of ${blu}%s${rs}.\n\n", + state->xdev_arg[0], state->mount_arg[0]); } if (state->ctx->warn && state->depth_arg && state->prune_arg) { parse_conflict_warning(state, state->depth_arg, 1, state->prune_arg, 1, - "${blu}%s${rs} does not work in the presence of ${blu}%s${rs}.\n", - state->prune_arg[0], state->depth_arg[0]); + "${blu}%s${rs} does not work in the presence of ${blu}%s${rs}.\n", + state->prune_arg[0], state->depth_arg[0]); if (state->interactive) { bfs_warning(state->ctx, "Do you want to continue? "); @@ -3483,8 +3482,8 @@ static struct bfs_expr *parse_whole_expr(struct parser_state *state) { if (state->ok_expr && state->files0_stdin_arg) { parse_conflict_error(state, state->ok_expr->argv, state->ok_expr->argc, state->files0_stdin_arg, 2, - "${blu}%s${rs} conflicts with ${blu}%s${rs} ${bld}%s${rs}.\n", - state->ok_expr->argv[0], state->files0_stdin_arg[0], state->files0_stdin_arg[1]); + "${blu}%s${rs} conflicts with ${blu}%s${rs} ${bld}%s${rs}.\n", + state->ok_expr->argv[0], state->files0_stdin_arg[0], state->files0_stdin_arg[1]); goto fail; } @@ -3644,7 +3643,7 @@ void bfs_ctx_dump(const struct bfs_ctx *ctx, enum debug_flags flag) { static void dump_costs(const struct bfs_ctx *ctx) { const struct bfs_expr *expr = ctx->expr; bfs_debug(ctx, DEBUG_COST, " Cost: ~${ylw}%g${rs}\n", expr->cost); - bfs_debug(ctx, DEBUG_COST, "Probability: ~${ylw}%g%%${rs}\n", 100.0*expr->probability); + bfs_debug(ctx, DEBUG_COST, "Probability: ~${ylw}%g%%${rs}\n", 100.0 * expr->probability); } struct bfs_ctx *bfs_parse_cmdline(int argc, char *argv[]) { @@ -3654,7 +3653,7 @@ struct bfs_ctx *bfs_parse_cmdline(int argc, char *argv[]) { goto fail; } - static char* default_argv[] = {BFS_COMMAND, NULL}; + static char *default_argv[] = {BFS_COMMAND, NULL}; if (argc < 1) { argc = 1; argv = default_argv; diff --git a/src/printf.c b/src/printf.c index 5de5a28..98bcb0f 100644 --- a/src/printf.c +++ b/src/printf.c @@ -113,14 +113,14 @@ static int bfs_printf_ctime(CFILE *cfile, const struct bfs_printf *directive, co } BFS_PRINTF_BUF(buf, "%s %s %2d %.2d:%.2d:%.2d.%09ld0 %4d", - days[tm.tm_wday], - months[tm.tm_mon], - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec, - (long)ts->tv_nsec, - 1900 + tm.tm_year); + days[tm.tm_wday], + months[tm.tm_mon], + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec, + (long)ts->tv_nsec, + 1900 + tm.tm_year); return dyn_fprintf(cfile->file, directive, buf); } @@ -152,19 +152,19 @@ static int bfs_printf_strftime(CFILE *cfile, const struct bfs_printf *directive, break; case '+': ret = snprintf(buf, sizeof(buf), "%4d-%.2d-%.2d+%.2d:%.2d:%.2d.%09ld0", - 1900 + tm.tm_year, - tm.tm_mon + 1, - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec, - (long)ts->tv_nsec); + 1900 + tm.tm_year, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec, + (long)ts->tv_nsec); break; case 'k': ret = snprintf(buf, sizeof(buf), "%2d", tm.tm_hour); break; case 'l': - ret = snprintf(buf, sizeof(buf), "%2d", (tm.tm_hour + 11)%12 + 1); + ret = snprintf(buf, sizeof(buf), "%2d", (tm.tm_hour + 11) % 12 + 1); break; case 's': ret = snprintf(buf, sizeof(buf), "%lld", (long long)ts->tv_sec); @@ -174,10 +174,10 @@ static int bfs_printf_strftime(CFILE *cfile, const struct bfs_printf *directive, break; case 'T': ret = snprintf(buf, sizeof(buf), "%.2d:%.2d:%.2d.%09ld0", - tm.tm_hour, - tm.tm_min, - tm.tm_sec, - (long)ts->tv_nsec); + tm.tm_hour, + tm.tm_min, + tm.tm_sec, + (long)ts->tv_nsec); break; // POSIX strftime() features @@ -202,7 +202,7 @@ static int bfs_printf_b(CFILE *cfile, const struct bfs_printf *directive, const return -1; } - uintmax_t blocks = ((uintmax_t)statbuf->blocks*BFS_STAT_BLKSIZE + 511)/512; + uintmax_t blocks = ((uintmax_t)statbuf->blocks * BFS_STAT_BLKSIZE + 511) / 512; BFS_PRINTF_BUF(buf, "%ju", blocks); return dyn_fprintf(cfile->file, directive, buf); } @@ -338,7 +338,7 @@ static int bfs_printf_k(CFILE *cfile, const struct bfs_printf *directive, const return -1; } - uintmax_t blocks = ((uintmax_t)statbuf->blocks*BFS_STAT_BLKSIZE + 1023)/1024; + uintmax_t blocks = ((uintmax_t)statbuf->blocks * BFS_STAT_BLKSIZE + 1023) / 1024; BFS_PRINTF_BUF(buf, "%ju", blocks); return dyn_fprintf(cfile->file, directive, buf); } @@ -452,7 +452,7 @@ static int bfs_printf_S(CFILE *cfile, const struct bfs_printf *directive, const if (statbuf->size == 0 && statbuf->blocks == 0) { sparsity = 1.0; } else { - sparsity = (double)BFS_STAT_BLKSIZE*statbuf->blocks/statbuf->size; + sparsity = (double)BFS_STAT_BLKSIZE * statbuf->blocks / statbuf->size; } return dyn_fprintf(cfile->file, directive, sparsity); } diff --git a/src/pwcache.c b/src/pwcache.c index 0e2f5c1..c728ba9 100644 --- a/src/pwcache.c +++ b/src/pwcache.c @@ -4,7 +4,6 @@ #include "pwcache.h" #include "alloc.h" #include "config.h" -#include "darray.h" #include "trie.h" #include #include diff --git a/src/stat.c b/src/stat.c index e8f48ee..d7387c6 100644 --- a/src/stat.c +++ b/src/stat.c @@ -10,8 +10,8 @@ #include #include #include -#include #include +#include #if defined(STATX_BASIC_STATS) && (!__ANDROID__ || __ANDROID_API__ >= 30) # define BFS_HAS_LIBC_STATX true diff --git a/src/trie.c b/src/trie.c index 77aa2d0..55544e6 100644 --- a/src/trie.c +++ b/src/trie.c @@ -700,7 +700,7 @@ static void trie_remove_impl(struct trie *trie, struct trie_leaf *leaf) { } if (child_index < parent_size) { - memmove(child, child + 1, (parent_size - child_index)*sizeof(*child)); + memmove(child, child + 1, (parent_size - child_index) * sizeof(*child)); } if (has_single_bit(parent_size)) { diff --git a/src/trie.h b/src/trie.h index 2f51db5..02088f1 100644 --- a/src/trie.h +++ b/src/trie.h @@ -4,8 +4,8 @@ #ifndef BFS_TRIE_H #define BFS_TRIE_H -#include "config.h" #include "alloc.h" +#include "config.h" #include "list.h" #include #include @@ -143,6 +143,6 @@ void trie_destroy(struct trie *trie); * Iterate over the leaves of a trie. */ #define for_trie(leaf, trie) \ - for_list(struct trie_leaf, leaf, trie) + for_list (struct trie_leaf, leaf, trie) #endif // BFS_TRIE_H diff --git a/src/xregex.c b/src/xregex.c index beb6676..b9c04bf 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -5,8 +5,8 @@ #include "alloc.h" #include "config.h" #include "diag.h" -#include "thread.h" #include "sanity.h" +#include "thread.h" #include #include #include diff --git a/src/xspawn.c b/src/xspawn.c index 80bafef..7fb63e0 100644 --- a/src/xspawn.c +++ b/src/xspawn.c @@ -187,7 +187,7 @@ fail: // In case of a write error, the parent will still see that we exited // unsuccessfully, but won't know why - (void) xwrite(pipefd[1], &error, sizeof(error)); + (void)xwrite(pipefd[1], &error, sizeof(error)); xclose(pipefd[1]); _Exit(127); diff --git a/src/xtime.c b/src/xtime.c index 79dafad..e90bdb1 100644 --- a/src/xtime.c +++ b/src/xtime.c @@ -81,7 +81,7 @@ static int safe_add(int *value, int delta) { static int floor_div(int n, int d) { int a = n < 0; - return (n + a)/d - a; + return (n + a) / d - a; } static int wrap(int *value, int max, int *next) { @@ -93,7 +93,7 @@ static int wrap(int *value, int max, int *next) { static int month_length(int year, int month) { static const int month_lengths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int ret = month_lengths[month]; - if (month == 1 && year%4 == 0 && (year%100 != 0 || (year + 300)%400 == 0)) { + if (month == 1 && year % 4 == 0 && (year % 100 != 0 || (year + 300) % 400 == 0)) { ++ret; } return ret; @@ -156,13 +156,13 @@ int xtimegm(struct tm *tm, time_t *timep) { leap_days = floor_div(tm->tm_year + 3, 4) - floor_div(tm->tm_year + 99, 100) + floor_div(tm->tm_year + 299, 400) - 17; } - long long epoch_days = 365LL*(tm->tm_year - 70) + leap_days + tm->tm_yday; - tm->tm_wday = (epoch_days + 4)%7; + long long epoch_days = 365LL * (tm->tm_year - 70) + leap_days + tm->tm_yday; + tm->tm_wday = (epoch_days + 4) % 7; if (tm->tm_wday < 0) { tm->tm_wday += 7; } - long long epoch_time = tm->tm_sec + 60*(tm->tm_min + 60*(tm->tm_hour + 24*epoch_days)); + long long epoch_time = tm->tm_sec + 60 * (tm->tm_min + 60 * (tm->tm_hour + 24 * epoch_days)); *timep = (time_t)epoch_time; if ((long long)*timep != epoch_time) { goto overflow; @@ -296,7 +296,7 @@ end: goto error; } - int offset = 60*tz_hour + tz_min; + int offset = 60 * tz_hour + tz_min; if (tz_negative) { result->tv_sec -= offset; } else { diff --git a/tests/bfstd.c b/tests/bfstd.c index 83964e5..33b3792 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/tests/mksock.c b/tests/mksock.c index 42ef322..7023b4f 100644 --- a/tests/mksock.c +++ b/tests/mksock.c @@ -9,8 +9,8 @@ #include "../src/bfstd.h" #include #include -#include #include +#include #include #include #include diff --git a/tests/trie.c b/tests/trie.c index 6ea94a2..656fd85 100644 --- a/tests/trie.c +++ b/tests/trie.c @@ -120,11 +120,11 @@ int main(void) { bfs_verify(!trie_find_mem(&trie, longstr, longsize)); bfs_verify(trie_insert_mem(&trie, longstr, longsize)); - memset(longstr + longsize/2, 0xAB, longsize/2); + memset(longstr + longsize / 2, 0xAB, longsize / 2); bfs_verify(!trie_find_mem(&trie, longstr, longsize)); bfs_verify(trie_insert_mem(&trie, longstr, longsize)); - memset(longstr, 0xAA, longsize/2); + memset(longstr, 0xAA, longsize / 2); bfs_verify(!trie_find_mem(&trie, longstr, longsize)); bfs_verify(trie_insert_mem(&trie, longstr, longsize)); diff --git a/tests/xtimegm.c b/tests/xtimegm.c index b2479b7..973b2eb 100644 --- a/tests/xtimegm.c +++ b/tests/xtimegm.c @@ -42,9 +42,9 @@ static bool tm_equal(const struct tm *tma, const struct tm *tmb) { 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_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)") : ""); } -- cgit v1.2.3 From a96ddeb7dc528d29d05f52a9b8857b2f8924fddc Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 3 Oct 2023 13:07:21 -0400 Subject: thread: s/call_once/invoke_once/ call_once() is a reserved identifier from C11. --- src/bfstd.c | 2 +- src/thread.h | 2 +- src/xregex.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/xregex.c') diff --git a/src/bfstd.c b/src/bfstd.c index 1a5a67d..fcf4a6d 100644 --- a/src/bfstd.c +++ b/src/bfstd.c @@ -651,7 +651,7 @@ static bool xiswprint(wchar_t c, enum wesc_flags flags) { /** Get the length of the longest printable prefix of a string. */ static size_t printable_len(const char *str, size_t len, enum wesc_flags flags) { static pthread_once_t once = PTHREAD_ONCE_INIT; - call_once(&once, char_cache_init); + invoke_once(&once, char_cache_init); // Fast path: avoid multibyte checks size_t i, word; diff --git a/src/thread.h b/src/thread.h index b2edf17..45b5e1f 100644 --- a/src/thread.h +++ b/src/thread.h @@ -97,7 +97,7 @@ /** * Wrapper for pthread_once(). */ -#define call_once(once, fn) \ +#define invoke_once(once, fn) \ thread_verify(pthread_once(once, fn), errno == 0) #endif // BFS_THREAD_H diff --git a/src/xregex.c b/src/xregex.c index b9c04bf..87b692e 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -107,7 +107,7 @@ static void bfs_onig_once(void) { /** Initialize Oniguruma. */ static int bfs_onig_initialize(OnigEncoding *enc) { static pthread_once_t once = PTHREAD_ONCE_INIT; - call_once(&once, bfs_onig_once); + invoke_once(&once, bfs_onig_once); *enc = bfs_onig_enc; return bfs_onig_status; -- cgit v1.2.3 From 428cf9c206beee3407ea3c5480b00f4cfbea95f5 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 5 Oct 2023 12:56:36 -0400 Subject: bfstd: Add a thread-safe wrapper for strerror() --- src/bfstd.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/bfstd.h | 11 +++++++++++ src/color.c | 2 +- src/eval.c | 2 +- src/parse.c | 4 ++-- src/printf.c | 2 +- src/thread.h | 3 ++- src/xregex.c | 3 ++- tests/bfstd.c | 4 ++-- tests/mksock.c | 2 +- tests/xtouch.c | 6 +++--- 11 files changed, 69 insertions(+), 13 deletions(-) (limited to 'src/xregex.c') diff --git a/src/bfstd.c b/src/bfstd.c index fcf4a6d..e9214d4 100644 --- a/src/bfstd.c +++ b/src/bfstd.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -276,6 +277,48 @@ char *xstpencpy(char *dest, char *end, const char *src, size_t n) { } } +const char *xstrerror(int errnum) { + int saved = errno; + const char *ret = NULL; + static thread_local char buf[256]; + +#if __APPLE__ + // No strerror_l() on macOS + if (strerror_r(errnum, buf, sizeof(buf)) == 0) { + ret = buf; + } +#else +# if __NetBSD__ + // NetBSD has no thread-specific locales + locale_t loc = LC_GLOBAL_LOCALE; +# else + locale_t loc = uselocale((locale_t)0); +# endif + + locale_t copy = loc; + if (copy == LC_GLOBAL_LOCALE) { + copy = duplocale(copy); + } + + if (copy != (locale_t)0) { + ret = strerror_l(errnum, loc); + } + + if (loc == LC_GLOBAL_LOCALE) { + freelocale(copy); + } +#endif + + if (!ret) { + // Fallback for strerror_[lr]() or duplocale() failures + snprintf(buf, sizeof(buf), "Unknown error %d", errnum); + ret = buf; + } + + errno = saved; + return ret; +} + void xstrmode(mode_t mode, char str[11]) { strcpy(str, "----------"); diff --git a/src/bfstd.h b/src/bfstd.h index fb77399..abde24e 100644 --- a/src/bfstd.h +++ b/src/bfstd.h @@ -166,6 +166,17 @@ char *xstpecpy(char *dest, char *end, const char *src); */ char *xstpencpy(char *dest, char *end, const char *src, size_t n); +/** + * Thread-safe strerror(). + * + * @param errnum + * An error number. + * @return + * A string describing that error, which remains valid until the next + * xstrerror() call in the same thread. + */ +const char *xstrerror(int errnum); + /** * Format a mode like ls -l (e.g. -rw-r--r--). * diff --git a/src/color.c b/src/color.c index 788d35d..fbb5edf 100644 --- a/src/color.c +++ b/src/color.c @@ -1239,7 +1239,7 @@ static int cvbuff(CFILE *cfile, const char *format, va_list args) { break; case 'm': - if (dstrcat(&cfile->buffer, strerror(error)) != 0) { + if (dstrcat(&cfile->buffer, xstrerror(error)) != 0) { return -1; } break; diff --git a/src/eval.c b/src/eval.c index 9f4896a..e0dd97b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1376,7 +1376,7 @@ static enum bftw_action eval_callback(const struct BFTW *ftwbuf, void *ptr) { if (ftwbuf->type == BFS_ERROR) { if (!eval_should_ignore(&state, ftwbuf->error)) { - eval_error(&state, "%s.\n", strerror(ftwbuf->error)); + eval_error(&state, "%s.\n", xstrerror(ftwbuf->error)); } state.action = BFTW_PRUNE; goto done; diff --git a/src/parse.c b/src/parse.c index 7766a7b..976f7cb 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1127,7 +1127,7 @@ static struct bfs_expr *parse_color(struct parser_state *state, int color, int a if (color) { if (!colors) { - parse_expr_error(state, expr, "Error parsing $$LS_COLORS: %s.\n", strerror(ctx->colors_error)); + parse_expr_error(state, expr, "Error parsing $$LS_COLORS: %s.\n", xstrerror(ctx->colors_error)); bfs_expr_free(expr); return NULL; } @@ -3741,7 +3741,7 @@ struct bfs_ctx *bfs_parse_cmdline(int argc, char *argv[]) { } if (state.use_color == COLOR_AUTO && !ctx->colors) { - bfs_warning(ctx, "Error parsing $$LS_COLORS: %s.\n\n", strerror(ctx->colors_error)); + bfs_warning(ctx, "Error parsing $$LS_COLORS: %s.\n\n", xstrerror(ctx->colors_error)); } if (bfs_optimize(ctx) != 0) { diff --git a/src/printf.c b/src/printf.c index 98bcb0f..704e26d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -744,7 +744,7 @@ int bfs_printf_parse(const struct bfs_ctx *ctx, struct bfs_expr *expr, const cha if (!directive.ptr) { int error = errno; bfs_expr_error(ctx, expr); - bfs_error(ctx, "Couldn't parse the mount table: %s.\n", strerror(error)); + bfs_error(ctx, "Couldn't parse the mount table: %s.\n", xstrerror(error)); goto directive_error; } break; diff --git a/src/thread.h b/src/thread.h index ab95a79..a59033c 100644 --- a/src/thread.h +++ b/src/thread.h @@ -8,6 +8,7 @@ #ifndef BFS_THREAD_H #define BFS_THREAD_H +#include "bfstd.h" #include "config.h" #include "diag.h" #include @@ -23,7 +24,7 @@ #endif #define thread_verify(expr, cond) \ - bfs_verify((errno = (expr), (cond)), "%s: %s", #expr, strerror(errno)) + bfs_verify((errno = (expr), (cond)), "%s: %s", #expr, xstrerror(errno)) /** * Wrapper for pthread_create(). diff --git a/src/xregex.c b/src/xregex.c index 87b692e..3df27f0 100644 --- a/src/xregex.c +++ b/src/xregex.c @@ -3,6 +3,7 @@ #include "xregex.h" #include "alloc.h" +#include "bfstd.h" #include "config.h" #include "diag.h" #include "sanity.h" @@ -274,7 +275,7 @@ void bfs_regfree(struct bfs_regex *regex) { char *bfs_regerror(const struct bfs_regex *regex) { if (!regex) { - return strdup(strerror(ENOMEM)); + return strdup(xstrerror(ENOMEM)); } #if BFS_USE_ONIGURUMA diff --git a/tests/bfstd.c b/tests/bfstd.c index 33b3792..c386279 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -15,12 +15,12 @@ /** Check the result of xdirname()/xbasename(). */ static void check_base_dir(const char *path, const char *dir, const char *base) { char *xdir = xdirname(path); - bfs_verify(xdir, "xdirname(): %s", strerror(errno)); + bfs_verify(xdir, "xdirname(): %s", xstrerror(errno)); bfs_verify(strcmp(xdir, dir) == 0, "xdirname('%s') == '%s' (!= '%s')", path, xdir, dir); free(xdir); char *xbase = xbasename(path); - bfs_verify(xbase, "xbasename(): %s", strerror(errno)); + bfs_verify(xbase, "xbasename(): %s", xstrerror(errno)); bfs_verify(strcmp(xbase, base) == 0, "xbasename('%s') == '%s' (!= '%s')", path, xbase, base); free(xbase); } diff --git a/tests/mksock.c b/tests/mksock.c index 7023b4f..f3b61da 100644 --- a/tests/mksock.c +++ b/tests/mksock.c @@ -19,7 +19,7 @@ * Print an error message. */ static void errmsg(const char *cmd, const char *path) { - fprintf(stderr, "%s: '%s': %s.\n", cmd, path, strerror(errno)); + fprintf(stderr, "%s: '%s': %s.\n", cmd, path, xstrerror(errno)); } /** diff --git a/tests/xtouch.c b/tests/xtouch.c index 80fad8d..a4c4d40 100644 --- a/tests/xtouch.c +++ b/tests/xtouch.c @@ -197,14 +197,14 @@ int main(int argc, char *argv[]) { if (rarg) { struct stat buf; if (fstatat(AT_FDCWD, rarg, &buf, at_flags(&args)) != 0) { - fprintf(stderr, "%s: '%s': %s\n", cmd, rarg, strerror(errno)); + fprintf(stderr, "%s: '%s': %s\n", cmd, rarg, xstrerror(errno)); return EXIT_FAILURE; } times[0] = buf.st_atim; times[1] = buf.st_mtim; } else if (darg) { if (xgetdate(darg, ×[0]) != 0) { - fprintf(stderr, "%s: Parsing time '%s' failed: %s\n", cmd, darg, strerror(errno)); + fprintf(stderr, "%s: Parsing time '%s' failed: %s\n", cmd, darg, xstrerror(errno)); return EXIT_FAILURE; } times[1] = times[0]; @@ -237,7 +237,7 @@ int main(int argc, char *argv[]) { for (; optind < argc; ++optind) { const char *path = argv[optind]; if (xtouch(&args, path) != 0) { - fprintf(stderr, "%s: '%s': %s\n", cmd, path, strerror(errno)); + fprintf(stderr, "%s: '%s': %s\n", cmd, path, xstrerror(errno)); ret = EXIT_FAILURE; } } -- 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 'src/xregex.c') 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