summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2025-06-25 13:59:15 -0400
committerTavian Barnes <tavianator@tavianator.com>2025-07-26 14:19:51 -0400
commit2cd69d3ee34a6d2c21aa64aedf262827eb83826f (patch)
tree9e98b40ac2a7fc6809f7e2bb3ac0c42eecad735a
parent1b1e5a4707d681e4b38df56e83db1be9c07723b8 (diff)
downloadbfs-2cd69d3ee34a6d2c21aa64aedf262827eb83826f.tar.xz
Use C23 [[attribute]] syntax
-rw-r--r--src/alloc.c2
-rw-r--r--src/alloc.h22
-rw-r--r--src/bar.c2
-rw-r--r--src/bfs.h78
-rw-r--r--src/bftw.c5
-rw-r--r--src/color.c10
-rw-r--r--src/color.h4
-rw-r--r--src/diag.c2
-rw-r--r--src/diag.h48
-rw-r--r--src/dstring.c3
-rw-r--r--src/dstring.h56
-rw-r--r--src/eval.c6
-rw-r--r--src/exec.c2
-rw-r--r--src/fsade.c8
-rw-r--r--src/ioq.c10
-rw-r--r--src/mtab.c2
-rw-r--r--src/opt.c12
-rw-r--r--src/parse.c32
-rw-r--r--src/prelude.h11
-rw-r--r--src/printf.c8
-rw-r--r--src/sighook.c2
-rw-r--r--src/trie.c19
-rw-r--r--src/trie.h3
-rw-r--r--src/xspawn.c4
24 files changed, 174 insertions, 177 deletions
diff --git a/src/alloc.c b/src/alloc.c
index f505eda..3cf9026 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -173,7 +173,7 @@ void arena_init(struct arena *arena, size_t align, size_t size) {
}
/** Allocate a new slab. */
-_cold
+[[_cold]]
static int slab_alloc(struct arena *arena) {
// Make the initial allocation size ~4K
size_t size = 4096;
diff --git a/src/alloc.h b/src/alloc.h
index 1fafbab..4f21ed0 100644
--- a/src/alloc.h
+++ b/src/alloc.h
@@ -131,8 +131,8 @@ static inline size_t flex_size(size_t align, size_t offset, size_t size, size_t
* @return
* The allocated memory, or NULL on failure.
*/
-_malloc(free, 1)
-_aligned_alloc(1, 2)
+[[_malloc(free, 1)]]
+[[_aligned_alloc(1, 2)]]
void *alloc(size_t align, size_t size);
/**
@@ -145,8 +145,8 @@ void *alloc(size_t align, size_t size);
* @return
* The allocated memory, or NULL on failure.
*/
-_malloc(free, 1)
-_aligned_alloc(1, 2)
+[[_malloc(free, 1)]]
+[[_aligned_alloc(1, 2)]]
void *zalloc(size_t align, size_t size);
/** Allocate memory for the given type. */
@@ -187,8 +187,8 @@ void *zalloc(size_t align, size_t size);
* @return
* The reallocated memory, or NULL on failure.
*/
-_aligned_alloc(2, 4)
-_nodiscard
+[[_nodiscard]]
+[[_aligned_alloc(2, 4)]]
void *xrealloc(void *ptr, size_t align, size_t old_size, size_t new_size);
/** Reallocate memory for an array. */
@@ -214,7 +214,7 @@ void *xrealloc(void *ptr, size_t align, size_t old_size, size_t new_size);
* for (count + 1) elements. On failure, errno will be non-zero, and
* ptr will returned unchanged.
*/
-_nodiscard
+[[_nodiscard]]
void *reserve(void *ptr, size_t align, size_t size, size_t count);
/**
@@ -272,7 +272,7 @@ void arena_free(struct arena *arena, void *ptr);
/**
* Allocate an object out of the arena.
*/
-_malloc(arena_free, 2)
+[[_malloc(arena_free, 2)]]
void *arena_alloc(struct arena *arena);
/**
@@ -353,7 +353,7 @@ void varena_free(struct varena *varena, void *ptr, size_t count);
* @return
* The allocated struct, or NULL on failure.
*/
-_malloc(varena_free, 2)
+[[_malloc(varena_free, 2)]]
void *varena_alloc(struct varena *varena, size_t count);
/**
@@ -370,7 +370,7 @@ void *varena_alloc(struct varena *varena, size_t count);
* @return
* The resized struct, or NULL on failure.
*/
-_nodiscard
+[[_nodiscard]]
void *varena_realloc(struct varena *varena, void *ptr, size_t old_count, size_t new_count);
/**
@@ -385,7 +385,7 @@ void *varena_realloc(struct varena *varena, void *ptr, size_t old_count, size_t
* @return
* The resized struct, or NULL on failure.
*/
-_nodiscard
+[[_nodiscard]]
void *varena_grow(struct varena *varena, void *ptr, size_t *count);
/**
diff --git a/src/bar.c b/src/bar.c
index 1b0691a..1f66a37 100644
--- a/src/bar.c
+++ b/src/bar.c
@@ -127,7 +127,7 @@ static void bfs_bar_sigexit(int sig, siginfo_t *info, void *arg) {
}
/** printf() to the status bar with a single write(). */
-_printf(2, 3)
+[[_printf(2, 3)]]
static int bfs_bar_printf(struct bfs_bar *bar, const char *format, ...) {
va_list args;
va_start(args, format);
diff --git a/src/bfs.h b/src/bfs.h
index ab96bf5..d88f49f 100644
--- a/src/bfs.h
+++ b/src/bfs.h
@@ -84,19 +84,12 @@ extern const char bfs_ldlibs[];
// Wrappers for attributes
/**
- * Silence warnings about switch/case fall-throughs.
- */
-#if __has_attribute(fallthrough)
-# define _fallthrough __attribute__((fallthrough))
-#else
-# define _fallthrough ((void)0)
-#endif
-
-/**
* Silence warnings about unused declarations.
*/
-#if __has_attribute(unused)
-# define _maybe_unused __attribute__((unused))
+#if __has_c_attribute(maybe_unused)
+# define _maybe_unused maybe_unused
+#elif __has_c_attribute(gnu::unused)
+# define _maybe_unused gnu::unused
#else
# define _maybe_unused
#endif
@@ -104,8 +97,10 @@ extern const char bfs_ldlibs[];
/**
* Warn if a value is unused.
*/
-#if __has_attribute(warn_unused_result)
-# define _nodiscard __attribute__((warn_unused_result))
+#if __has_c_attribute(nodiscard)
+# define _nodiscard nodiscard
+#elif __has_c_attribute(gnu::warn_unused_result)
+# define _nodiscard gnu::warn_unused_result
#else
# define _nodiscard
#endif
@@ -113,35 +108,38 @@ extern const char bfs_ldlibs[];
/**
* Hint to avoid inlining a function.
*/
-#if __has_attribute(noinline)
-# define _noinline __attribute__((noinline))
+#if __has_c_attribute(gnu::noinline)
+# define _noinline gnu::noinline
#else
# define _noinline
#endif
/**
- * Marks a non-returning function.
+ * Hint that a function is unlikely to be called.
*/
-#if __STDC_VERSION__ >= C23
-# define _noreturn [[noreturn]]
+#if __has_c_attribute(gnu::cold)
+# define _cold _noinline, gnu::cold
#else
-# define _noreturn _Noreturn
+# define _cold _noinline
#endif
/**
- * Hint that a function is unlikely to be called.
+ * Marks a non-returning function.
*/
-#if __has_attribute(cold)
-# define _cold _noinline __attribute__((cold))
+#if __has_c_attribute(noreturn)
+# define _noreturn noreturn
+#elif __has_c_attribute(gnu::noreturn)
+# define _noreturn gnu::noreturn
#else
-# define _cold _noinline
+# define _noreturn
#endif
+
/**
* Adds compiler warnings for bad printf()-style function calls, if supported.
*/
-#if __has_attribute(format)
-# define _printf(fmt, args) __attribute__((format(printf, fmt, args)))
+#if __has_c_attribute(gnu::format)
+# define _printf(fmt, args) gnu::format(printf, fmt, args)
#else
# define _printf(fmt, args)
#endif
@@ -149,8 +147,8 @@ extern const char bfs_ldlibs[];
/**
* Annotates functions that potentially modify and return format strings.
*/
-#if __has_attribute(format_arg)
-# define _format_arg(arg) __attribute__((format_arg(arg)))
+#if __has_c_attribute(gnu::format_arg)
+# define _format_arg(arg) gnu::format_arg(arg)
#else
# define _format_arg(arg)
#endif
@@ -158,11 +156,11 @@ extern const char bfs_ldlibs[];
/**
* Annotates allocator-like functions.
*/
-#if __has_attribute(malloc)
+#if __has_c_attribute(gnu::malloc)
# if __GNUC__ >= 11 && !__OPTIMIZE__ // malloc(deallocator) disables inlining on GCC
-# define _malloc(...) _nodiscard __attribute__((malloc(__VA_ARGS__)))
+# define _malloc(...) _nodiscard, gnu::malloc(__VA_ARGS__)
# else
-# define _malloc(...) _nodiscard __attribute__((malloc))
+# define _malloc(...) _nodiscard, gnu::malloc
# endif
#else
# define _malloc(...) _nodiscard
@@ -171,8 +169,8 @@ extern const char bfs_ldlibs[];
/**
* Specifies that a function returns allocations with a given alignment.
*/
-#if __has_attribute(alloc_align)
-# define _alloc_align(param) __attribute__((alloc_align(param)))
+#if __has_c_attribute(gnu::alloc_align)
+# define _alloc_align(param) gnu::alloc_align(param)
#else
# define _alloc_align(param)
#endif
@@ -180,8 +178,8 @@ extern const char bfs_ldlibs[];
/**
* Specifies that a function returns allocations with a given size.
*/
-#if __has_attribute(alloc_size)
-# define _alloc_size(...) __attribute__((alloc_size(__VA_ARGS__)))
+#if __has_c_attribute(gnu::alloc_size)
+# define _alloc_size(...) gnu::alloc_size(__VA_ARGS__)
#else
# define _alloc_size(...)
#endif
@@ -189,7 +187,7 @@ extern const char bfs_ldlibs[];
/**
* Shorthand for _alloc_align() and _alloc_size().
*/
-#define _aligned_alloc(align, ...) _alloc_align(align) _alloc_size(__VA_ARGS__)
+#define _aligned_alloc(align, ...) _alloc_align(align), _alloc_size(__VA_ARGS__)
/**
* Check if function multiversioning via GNU indirect functions (ifunc) is supported.
@@ -197,7 +195,7 @@ extern const char bfs_ldlibs[];
* Disabled on TSan due to https://github.com/google/sanitizers/issues/342.
*/
#ifndef BFS_USE_TARGET_CLONES
-# if __has_attribute(target_clones) \
+# if __has_c_attribute(gnu::target_clones) \
&& (__GLIBC__ || __FreeBSD__) \
&& !__SANITIZE_THREAD__ \
&& !__SANITIZE_TYPE__
@@ -211,7 +209,7 @@ extern const char bfs_ldlibs[];
* Apply the target_clones attribute, if available.
*/
#if BFS_USE_TARGET_CLONES
-# define _target_clones(...) __attribute__((target_clones(__VA_ARGS__)))
+# define _target_clones(...) gnu::target_clones(__VA_ARGS__)
#else
# define _target_clones(...)
#endif
@@ -219,8 +217,10 @@ extern const char bfs_ldlibs[];
/**
* Mark the size of a flexible array member.
*/
-#if __has_attribute(counted_by)
-# define _counted_by(...) __attribute__((counted_by(__VA_ARGS__)))
+#if __has_c_attribute(clang::counted_by)
+# define _counted_by(...) clang::counted_by(__VA_ARGS__)
+#elif __has_c_attribute(gnu::counted_by)
+# define _counted_by(...) gnu::counted_by(__VA_ARGS__)
#else
# define _counted_by(...)
#endif
diff --git a/src/bftw.c b/src/bftw.c
index 0ca6f34..a884e92 100644
--- a/src/bftw.c
+++ b/src/bftw.c
@@ -253,7 +253,8 @@ struct bftw_file {
/** The length of the file's name. */
size_t namelen;
/** The file's name. */
- char name[]; // _counted_by(namelen + 1)
+ // [[_counted_by(namelen + 1)]]
+ char name[];
};
/**
@@ -1439,7 +1440,7 @@ static bool bftw_must_stat(const struct bftw_state *state, size_t depth, enum bf
if (!(bftw_stat_flags(state, depth) & BFS_STAT_NOFOLLOW)) {
return true;
}
- _fallthrough;
+ [[fallthrough]];
default:
#if __linux__
diff --git a/src/color.c b/src/color.c
index 926cf2b..2d0fc9c 100644
--- a/src/color.c
+++ b/src/color.c
@@ -32,7 +32,8 @@ struct esc_seq {
/** The length of the escape sequence. */
size_t len;
/** The escape sequence itself, without a terminating NUL. */
- char seq[] _counted_by(len);
+ [[_counted_by(len)]]
+ char seq[];
};
/**
@@ -48,7 +49,8 @@ struct ext_color {
/** Whether the comparison should be case-sensitive. */
bool case_sensitive;
/** The extension to match (NUL-terminated). */
- char ext[]; // _counted_by(len + 1);
+ // [[_counted_by(len + 1)]]
+ char ext[];
};
struct colors {
@@ -1387,7 +1389,7 @@ static int print_link_target(CFILE *cfile, const struct BFTW *ftwbuf) {
}
/** Format some colored output to the buffer. */
-_printf(2, 3)
+[[_printf(2, 3)]]
static int cbuff(CFILE *cfile, const char *format, ...);
/** Print an expression's name, for diagnostics. */
@@ -1471,7 +1473,7 @@ static int print_expr(CFILE *cfile, const struct bfs_expr *expr, bool verbose, i
return 0;
}
-_printf(2, 0)
+[[_printf(2, 0)]]
static int cvbuff(CFILE *cfile, const char *format, va_list args) {
const struct colors *colors = cfile->colors;
diff --git a/src/color.h b/src/color.h
index aac8b33..d5e437c 100644
--- a/src/color.h
+++ b/src/color.h
@@ -103,13 +103,13 @@ int cfclose(CFILE *cfile);
* @return
* 0 on success, -1 on failure.
*/
-_printf(2, 3)
+[[_printf(2, 3)]]
int cfprintf(CFILE *cfile, const char *format, ...);
/**
* cfprintf() variant that takes a va_list.
*/
-_printf(2, 0)
+[[_printf(2, 0)]]
int cvfprintf(CFILE *cfile, const char *format, va_list args);
/**
diff --git a/src/diag.c b/src/diag.c
index a86b060..e0db4d2 100644
--- a/src/diag.c
+++ b/src/diag.c
@@ -33,7 +33,7 @@ void bfs_diagf(const char *format, ...) {
va_end(args);
}
-_noreturn
+[[_noreturn]]
void bfs_abortf(const char *format, ...) {
va_list args;
va_start(args, format);
diff --git a/src/diag.h b/src/diag.h
index 9f3e8e1..844e846 100644
--- a/src/diag.h
+++ b/src/diag.h
@@ -31,7 +31,7 @@
/**
* Print a low-level diagnostic message to standard error.
*/
-_printf(1, 2)
+[[_printf(1, 2)]]
void bfs_diagf(const char *format, ...);
/**
@@ -55,9 +55,9 @@ void bfs_diagf(const char *format, ...);
/**
* Print a message to standard error and abort.
*/
-_noreturn
-_cold
-_printf(1, 2)
+[[_cold]]
+[[_printf(1, 2)]]
+[[_noreturn]]
void bfs_abortf(const char *format, ...);
/**
@@ -171,14 +171,14 @@ const char *debug_flag_name(enum debug_flags flag);
/**
* Like perror(), but decorated like bfs_error().
*/
-_cold
+[[_cold]]
void bfs_perror(const struct bfs_ctx *ctx, const char *str);
/**
* Shorthand for printing error messages.
*/
-_cold
-_printf(2, 3)
+[[_cold]]
+[[_printf(2, 3)]]
void bfs_error(const struct bfs_ctx *ctx, const char *format, ...);
/**
@@ -186,8 +186,8 @@ void bfs_error(const struct bfs_ctx *ctx, const char *format, ...);
*
* @return Whether a warning was printed.
*/
-_cold
-_printf(2, 3)
+[[_cold]]
+[[_printf(2, 3)]]
bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...);
/**
@@ -195,71 +195,71 @@ bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...);
*
* @return Whether a debug message was printed.
*/
-_cold
-_printf(3, 4)
+[[_cold]]
+[[_printf(3, 4)]]
bool bfs_debug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *format, ...);
/**
* bfs_error() variant that takes a va_list.
*/
-_cold
-_printf(2, 0)
+[[_cold]]
+[[_printf(2, 0)]]
void bfs_verror(const struct bfs_ctx *ctx, const char *format, va_list args);
/**
* bfs_warning() variant that takes a va_list.
*/
-_cold
-_printf(2, 0)
+[[_cold]]
+[[_printf(2, 0)]]
bool bfs_vwarning(const struct bfs_ctx *ctx, const char *format, va_list args);
/**
* bfs_debug() variant that takes a va_list.
*/
-_cold
-_printf(3, 0)
+[[_cold]]
+[[_printf(3, 0)]]
bool bfs_vdebug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *format, va_list args);
/**
* Print the error message prefix.
*/
-_cold
+[[_cold]]
void bfs_error_prefix(const struct bfs_ctx *ctx);
/**
* Print the warning message prefix.
*/
-_cold
+[[_cold]]
bool bfs_warning_prefix(const struct bfs_ctx *ctx);
/**
* Print the debug message prefix.
*/
-_cold
+[[_cold]]
bool bfs_debug_prefix(const struct bfs_ctx *ctx, enum debug_flags flag);
/**
* Highlight parts of the command line in an error message.
*/
-_cold
+[[_cold]]
void bfs_argv_error(const struct bfs_ctx *ctx, const bool args[]);
/**
* Highlight parts of an expression in an error message.
*/
-_cold
+[[_cold]]
void bfs_expr_error(const struct bfs_ctx *ctx, const struct bfs_expr *expr);
/**
* Highlight parts of the command line in a warning message.
*/
-_cold
+[[_cold]]
bool bfs_argv_warning(const struct bfs_ctx *ctx, const bool args[]);
/**
* Highlight parts of an expression in a warning message.
*/
-_cold
+[[_cold]]
bool bfs_expr_warning(const struct bfs_ctx *ctx, const struct bfs_expr *expr);
#endif // BFS_DIAG_H
diff --git a/src/dstring.c b/src/dstring.c
index 678d685..5addb77 100644
--- a/src/dstring.c
+++ b/src/dstring.c
@@ -23,7 +23,8 @@ struct dstring {
/** Length of the string, *excluding* the terminating NUL. */
size_t len;
/** The string itself. */
- alignas(dchar) char str[] _counted_by(cap);
+ [[_counted_by(cap)]]
+ alignas(dchar) char str[];
};
#define DSTR_OFFSET offsetof(struct dstring, str)
diff --git a/src/dstring.h b/src/dstring.h
index ce7ef86..8765f6e 100644
--- a/src/dstring.h
+++ b/src/dstring.h
@@ -16,14 +16,14 @@
/** Marker type for dynamic strings. */
#if BFS_LINT && __clang__
-// Abuse __attribute__(aligned) to make a type that allows
+// Abuse [[gnu::aligned]] to make a type that allows
//
// dchar * -> char *
//
// conversions, but warns (with Clang's -Walign-mismatch) on
//
// char * -> dchar *
-typedef __attribute__((aligned(alignof(size_t)))) char dchar;
+typedef char dchar [[gnu::aligned(alignof(size_t))]];
#else
typedef char dchar;
#endif
@@ -42,7 +42,7 @@ void dstrfree(dchar *dstr);
* @cap
* The initial capacity of the string.
*/
-_malloc(dstrfree, 1)
+[[_malloc(dstrfree, 1)]]
dchar *dstralloc(size_t cap);
/**
@@ -51,7 +51,7 @@ dchar *dstralloc(size_t cap);
* @str
* The NUL-terminated string to copy.
*/
-_malloc(dstrfree, 1)
+[[_malloc(dstrfree, 1)]]
dchar *dstrdup(const char *str);
/**
@@ -62,7 +62,7 @@ dchar *dstrdup(const char *str);
* @n
* The maximum number of characters to copy from str.
*/
-_malloc(dstrfree, 1)
+[[_malloc(dstrfree, 1)]]
dchar *dstrndup(const char *str, size_t n);
/**
@@ -71,7 +71,7 @@ dchar *dstrndup(const char *str, size_t n);
* @dstr
* The dynamic string to copy.
*/
-_malloc(dstrfree, 1)
+[[_malloc(dstrfree, 1)]]
dchar *dstrddup(const dchar *dstr);
/**
@@ -82,7 +82,7 @@ dchar *dstrddup(const dchar *dstr);
* @len
* The length of the string, which may include internal NUL bytes.
*/
-_malloc(dstrfree, 1)
+[[_malloc(dstrfree, 1)]]
dchar *dstrxdup(const char *str, size_t len);
/**
@@ -117,7 +117,7 @@ int dstreserve(dchar **dstr, size_t cap);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstresize(dchar **dstr, size_t len);
/**
@@ -139,7 +139,7 @@ void dstrshrink(dchar *dstr, size_t len);
* The string to append.
* @return 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrcat(dchar **dest, const char *src);
/**
@@ -154,7 +154,7 @@ int dstrcat(dchar **dest, const char *src);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrncat(dchar **dest, const char *src, size_t n);
/**
@@ -167,7 +167,7 @@ int dstrncat(dchar **dest, const char *src, size_t n);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrdcat(dchar **dest, const dchar *src);
/**
@@ -182,7 +182,7 @@ int dstrdcat(dchar **dest, const dchar *src);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrxcat(dchar **dest, const char *src, size_t len);
/**
@@ -195,7 +195,7 @@ int dstrxcat(dchar **dest, const char *src, size_t len);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrapp(dchar **str, char c);
/**
@@ -208,7 +208,7 @@ int dstrapp(dchar **str, char c);
* @returns
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrcpy(dchar **dest, const char *str);
/**
@@ -221,7 +221,7 @@ int dstrcpy(dchar **dest, const char *str);
* @returns
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrdcpy(dchar **dest, const dchar *str);
/**
@@ -236,7 +236,7 @@ int dstrdcpy(dchar **dest, const dchar *str);
* @returns
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrncpy(dchar **dest, const char *str, size_t n);
/**
@@ -251,7 +251,7 @@ int dstrncpy(dchar **dest, const char *str, size_t n);
* @returns
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrxcpy(dchar **dest, const char *str, size_t len);
/**
@@ -264,8 +264,8 @@ int dstrxcpy(dchar **dest, const char *str, size_t len);
* @return
* The created string, or NULL on failure.
*/
-_nodiscard
-_printf(1, 2)
+[[_nodiscard]]
+[[_printf(1, 2)]]
dchar *dstrprintf(const char *format, ...);
/**
@@ -278,8 +278,8 @@ dchar *dstrprintf(const char *format, ...);
* @return
* The created string, or NULL on failure.
*/
-_nodiscard
-_printf(1, 0)
+[[_nodiscard]]
+[[_printf(1, 0)]]
dchar *dstrvprintf(const char *format, va_list args);
/**
@@ -294,8 +294,8 @@ dchar *dstrvprintf(const char *format, va_list args);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
-_printf(2, 3)
+[[_nodiscard]]
+[[_printf(2, 3)]]
int dstrcatf(dchar **str, const char *format, ...);
/**
@@ -310,8 +310,8 @@ int dstrcatf(dchar **str, const char *format, ...);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
-_printf(2, 0)
+[[_nodiscard]]
+[[_printf(2, 0)]]
int dstrvcatf(dchar **str, const char *format, va_list args);
/**
@@ -326,7 +326,7 @@ int dstrvcatf(dchar **str, const char *format, va_list args);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrescat(dchar **dest, const char *str, enum wesc_flags flags);
/**
@@ -343,13 +343,13 @@ int dstrescat(dchar **dest, const char *str, enum wesc_flags flags);
* @return
* 0 on success, -1 on failure.
*/
-_nodiscard
+[[_nodiscard]]
int dstrnescat(dchar **dest, const char *str, size_t n, enum wesc_flags flags);
/**
* Repeat a string n times.
*/
-_nodiscard
+[[_nodiscard]]
dchar *dstrepeat(const char *str, size_t n);
#endif // BFS_DSTRING_H
diff --git a/src/eval.c b/src/eval.c
index 0d1bf68..8b62419 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -67,7 +67,7 @@ struct bfs_eval {
/**
* Print an error message.
*/
-_printf(2, 3)
+[[_printf(2, 3)]]
static void eval_error(struct bfs_eval *state, const char *format, ...) {
const struct bfs_ctx *ctx = state->ctx;
@@ -279,10 +279,10 @@ bool eval_time(const struct bfs_expr *expr, struct bfs_eval *state) {
switch (expr->time_unit) {
case BFS_DAYS:
diff /= 60 * 24;
- _fallthrough;
+ [[fallthrough]];
case BFS_MINUTES:
diff /= 60;
- _fallthrough;
+ [[fallthrough]];
case BFS_SECONDS:
break;
}
diff --git a/src/exec.c b/src/exec.c
index 45c9f1d..f57b28f 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -24,7 +24,7 @@
#include <unistd.h>
/** Print some debugging info. */
-_printf(2, 3)
+[[_printf(2, 3)]]
static void bfs_exec_debug(const struct bfs_exec *execbuf, const char *format, ...) {
const struct bfs_ctx *ctx = execbuf->ctx;
diff --git a/src/fsade.c b/src/fsade.c
index dfdf125..3d4c8ba 100644
--- a/src/fsade.c
+++ b/src/fsade.c
@@ -47,7 +47,7 @@
* Many of the APIs used here don't have *at() variants, but we can try to
* emulate something similar if /proc/self/fd is available.
*/
-_maybe_unused
+[[_maybe_unused]]
static const char *fake_at(const struct BFTW *ftwbuf) {
static atomic int proc_works = -1;
@@ -81,7 +81,7 @@ fail:
return ftwbuf->path;
}
-_maybe_unused
+[[_maybe_unused]]
static void free_fake_at(const struct BFTW *ftwbuf, const char *path) {
if (path != ftwbuf->path) {
dstrfree((dchar *)path);
@@ -91,7 +91,7 @@ static void free_fake_at(const struct BFTW *ftwbuf, const char *path) {
/**
* Check if an error was caused by the absence of support or data for a feature.
*/
-_maybe_unused
+[[_maybe_unused]]
static bool is_absence_error(int error) {
// If the OS doesn't support the feature, it's obviously not enabled for
// any files
@@ -171,7 +171,7 @@ static int bfs_acl_entry(acl_t acl, int which, acl_entry_t *entry) {
}
/** Unified interface for acl_get_tag_type(). */
-_maybe_unused
+[[_maybe_unused]]
static int bfs_acl_tag_type(acl_entry_t entry, acl_tag_t *tag) {
#if BFS_HAS_ACL_GET_TAG_TYPE
return acl_get_tag_type(entry, tag);
diff --git a/src/ioq.c b/src/ioq.c
index 57eb4a5..5621e21 100644
--- a/src/ioq.c
+++ b/src/ioq.c
@@ -203,7 +203,8 @@ struct ioqq {
cache_align atomic size_t tail;
/** The circular buffer itself. */
- cache_align ioq_slot slots[]; // _counted_by(slot_mask + 1)
+ // [[_counted_by(slot_mask + 1)]]
+ cache_align ioq_slot slots[];
};
/** Destroy an I/O command queue. */
@@ -275,7 +276,7 @@ static struct ioq_monitor *ioq_slot_monitor(struct ioqq *ioqq, ioq_slot *slot) {
}
/** Atomically wait for a slot to change. */
-_noinline
+[[_noinline]]
static uintptr_t ioq_slot_wait(struct ioqq *ioqq, ioq_slot *slot, uintptr_t value) {
uintptr_t ret;
@@ -323,7 +324,7 @@ done:
}
/** Wake up any threads waiting on a slot. */
-_noinline
+[[_noinline]]
static void ioq_slot_wake(struct ioqq *ioqq, ioq_slot *slot) {
struct ioq_monitor *monitor = ioq_slot_monitor(ioqq, slot);
@@ -593,7 +594,8 @@ struct ioq {
/** The number of background threads. */
size_t nthreads;
/** The background threads themselves. */
- struct ioq_thread threads[] _counted_by(nthreads);
+ [[_counted_by(nthreads)]]
+ struct ioq_thread threads[];
};
/** Cancel a request if we need to. */
diff --git a/src/mtab.c b/src/mtab.c
index 40a9885..04edfbd 100644
--- a/src/mtab.c
+++ b/src/mtab.c
@@ -69,7 +69,7 @@ struct bfs_mtab {
/**
* Add an entry to the mount table.
*/
-_maybe_unused
+[[_maybe_unused]]
static int bfs_mtab_add(struct bfs_mtab *mtab, const char *path, const char *type) {
size_t path_size = strlen(path) + 1;
size_t type_size = strlen(type) + 1;
diff --git a/src/opt.c b/src/opt.c
index 9094794..0b2837f 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -374,7 +374,7 @@ struct bfs_opt {
};
/** Log an optimization. */
-_printf(2, 3)
+[[_printf(2, 3)]]
static bool opt_debug(struct bfs_opt *opt, const char *format, ...) {
if (bfs_debug_prefix(opt->ctx, DEBUG_OPT)) {
for (int i = 0; i < opt->depth; ++i) {
@@ -392,7 +392,7 @@ static bool opt_debug(struct bfs_opt *opt, const char *format, ...) {
}
/** Log a recursive call. */
-_printf(2, 3)
+[[_printf(2, 3)]]
static bool opt_enter(struct bfs_opt *opt, const char *format, ...) {
int depth = opt->depth;
if (depth > 0) {
@@ -412,7 +412,7 @@ static bool opt_enter(struct bfs_opt *opt, const char *format, ...) {
}
/** Log a recursive return. */
-_printf(2, 3)
+[[_printf(2, 3)]]
static bool opt_leave(struct bfs_opt *opt, const char *format, ...) {
bool debug = false;
int depth = opt->depth;
@@ -436,7 +436,7 @@ static bool opt_leave(struct bfs_opt *opt, const char *format, ...) {
}
/** Log a shallow visit. */
-_printf(2, 3)
+[[_printf(2, 3)]]
static bool opt_visit(struct bfs_opt *opt, const char *format, ...) {
int depth = opt->depth;
if (depth > 0) {
@@ -456,7 +456,7 @@ static bool opt_visit(struct bfs_opt *opt, const char *format, ...) {
}
/** Log the deletion of an expression. */
-_printf(2, 3)
+[[_printf(2, 3)]]
static bool opt_delete(struct bfs_opt *opt, const char *format, ...) {
int depth = opt->depth;
@@ -618,7 +618,7 @@ static bool is_const(const struct bfs_expr *expr) {
}
/** Warn about an expression. */
-_printf(3, 4)
+[[_printf(3, 4)]]
static bool opt_warning(const struct bfs_opt *opt, const struct bfs_expr *expr, const char *format, ...) {
if (!opt->warn) {
return false;
diff --git a/src/parse.c b/src/parse.c
index 5ec4c0e..febab7f 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -138,7 +138,7 @@ static void highlight_args(const struct bfs_ctx *ctx, char **argv, size_t argc,
/**
* Print an error message during parsing.
*/
-_printf(2, 3)
+[[_printf(2, 3)]]
static void parse_error(const struct bfs_parser *parser, const char *format, ...) {
const struct bfs_ctx *ctx = parser->ctx;
@@ -156,7 +156,7 @@ static void parse_error(const struct bfs_parser *parser, const char *format, ...
/**
* Print an error about some command line arguments.
*/
-_printf(4, 5)
+[[_printf(4, 5)]]
static void parse_argv_error(const struct bfs_parser *parser, char **argv, size_t argc, const char *format, ...) {
const struct bfs_ctx *ctx = parser->ctx;
@@ -174,7 +174,7 @@ static void parse_argv_error(const struct bfs_parser *parser, char **argv, size_
/**
* Print an error about conflicting command line arguments.
*/
-_printf(4, 5)
+[[_printf(4, 5)]]
static void parse_conflict_error(const struct bfs_parser *parser, const struct bfs_expr *expr1, const struct bfs_expr *expr2, const char *format, ...) {
const struct bfs_ctx *ctx = parser->ctx;
@@ -193,7 +193,7 @@ static void parse_conflict_error(const struct bfs_parser *parser, const struct b
/**
* Print an error about an expression.
*/
-_printf(3, 4)
+[[_printf(3, 4)]]
static void parse_expr_error(const struct bfs_parser *parser, const struct bfs_expr *expr, const char *format, ...) {
const struct bfs_ctx *ctx = parser->ctx;
@@ -208,7 +208,7 @@ static void parse_expr_error(const struct bfs_parser *parser, const struct bfs_e
/**
* Print a warning message during parsing.
*/
-_printf(2, 3)
+[[_printf(2, 3)]]
static bool parse_warning(const struct bfs_parser *parser, const char *format, ...) {
const struct bfs_ctx *ctx = parser->ctx;
@@ -229,7 +229,7 @@ static bool parse_warning(const struct bfs_parser *parser, const char *format, .
/**
* Print a warning about conflicting command line arguments.
*/
-_printf(4, 5)
+[[_printf(4, 5)]]
static bool parse_conflict_warning(const struct bfs_parser *parser, const struct bfs_expr *expr1, const struct bfs_expr *expr2, const char *format, ...) {
const struct bfs_ctx *ctx = parser->ctx;
@@ -251,7 +251,7 @@ static bool parse_conflict_warning(const struct bfs_parser *parser, const struct
/**
* Print a warning about an expression.
*/
-_printf(3, 4)
+[[_printf(3, 4)]]
static bool parse_expr_warning(const struct bfs_parser *parser, const struct bfs_expr *expr, const char *format, ...) {
const struct bfs_ctx *ctx = parser->ctx;
@@ -995,16 +995,16 @@ static struct bfs_expr *parse_time(struct bfs_parser *parser, int field, int arg
switch (*tail) {
case 'w':
time *= 7;
- _fallthrough;
+ [[fallthrough]];
case 'd':
time *= 24;
- _fallthrough;
+ [[fallthrough]];
case 'h':
time *= 60;
- _fallthrough;
+ [[fallthrough]];
case 'm':
time *= 60;
- _fallthrough;
+ [[fallthrough]];
case 's':
break;
default:
@@ -1973,7 +1973,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
who = 0;
mask = 0777;
state = MODE_WHO;
- _fallthrough;
+ [[fallthrough]];
case MODE_WHO:
switch (*i) {
@@ -2000,7 +2000,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
case MODE_EQUALS:
expr->file_mode &= ~who;
expr->dir_mode &= ~who;
- _fallthrough;
+ [[fallthrough]];
case MODE_PLUS:
expr->file_mode |= file_change;
expr->dir_mode |= dir_change;
@@ -2010,7 +2010,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
expr->dir_mode &= ~dir_change;
break;
}
- _fallthrough;
+ [[fallthrough]];
case MODE_ACTION:
if (who == 0) {
@@ -2095,7 +2095,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
break;
case 'x':
file_change |= mask & 0111;
- _fallthrough;
+ [[fallthrough]];
case 'X':
dir_change |= mask & 0111;
break;
@@ -2158,7 +2158,7 @@ static struct bfs_expr *parse_perm(struct bfs_parser *parser, int field, int arg
++mode;
break;
}
- _fallthrough;
+ [[fallthrough]];
default:
expr->mode_cmp = BFS_MODE_EQUAL;
break;
diff --git a/src/prelude.h b/src/prelude.h
index 1663af6..f4ec40f 100644
--- a/src/prelude.h
+++ b/src/prelude.h
@@ -77,12 +77,6 @@
/** _Bool => bool, true, false */
#include <stdbool.h>
-/**
- * C23 deprecates `noreturn void` in favour of `[[noreturn]] void`, so we expose
- * _noreturn instead with the other attributes in "bfs.h".
- */
-// #include <stdnoreturn.h>
-
/** Part of <threads.h>, but we don't use anything else from it. */
#define thread_local _Thread_local
@@ -99,11 +93,6 @@
// Feature detection
-// https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
-#ifndef __has_attribute
-# define __has_attribute(attr) false
-#endif
-
// https://clang.llvm.org/docs/LanguageExtensions.html#has-builtin
#ifndef __has_builtin
# define __has_builtin(builtin) false
diff --git a/src/printf.c b/src/printf.c
index 30ec201..f9fca64 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -91,7 +91,7 @@ static bool should_color(CFILE *cfile, const struct bfs_fmt *fmt) {
(void)ret
/** Return a dynamic format string. */
-_format_arg(2)
+[[_format_arg(2)]]
static const char *dyn_fmt(const char *str, const char *fake) {
bfs_assert(strcmp(str + strlen(str) - strlen(fake) + 1, fake + 1) == 0,
"Mismatched format specifiers: '%s' vs. '%s'", str, fake);
@@ -99,7 +99,7 @@ static const char *dyn_fmt(const char *str, const char *fake) {
}
/** Wrapper for fprintf(). */
-_printf(3, 4)
+[[_printf(3, 4)]]
static int bfs_fprintf(CFILE *cfile, const struct bfs_fmt *fmt, const char *fake, ...) {
va_list args;
va_start(args, fake);
@@ -562,7 +562,7 @@ static int bfs_printf_Y(CFILE *cfile, const struct bfs_fmt *fmt, const struct BF
}
/** %Z: SELinux context */
-_maybe_unused
+[[_maybe_unused]]
static int bfs_printf_Z(CFILE *cfile, const struct bfs_fmt *fmt, const struct BFTW *ftwbuf) {
char *con = bfs_getfilecon(ftwbuf);
if (!con) {
@@ -708,7 +708,7 @@ int bfs_printf_parse(const struct bfs_ctx *ctx, struct bfs_expr *expr, const cha
case '+':
case ' ':
must_be_numeric = true;
- _fallthrough;
+ [[fallthrough]];
case '-':
if (strchr(fmt.str, c)) {
bfs_expr_error(ctx, expr);
diff --git a/src/sighook.c b/src/sighook.c
index a87bed5..42bd811 100644
--- a/src/sighook.c
+++ b/src/sighook.c
@@ -423,7 +423,7 @@ static bool is_fatal(int sig) {
}
/** Reraise a fatal signal. */
-_noreturn
+[[_noreturn]]
static void reraise(siginfo_t *info) {
int sig = info->si_signo;
diff --git a/src/trie.c b/src/trie.c
index 6aac17f..0a86b55 100644
--- a/src/trie.c
+++ b/src/trie.c
@@ -129,7 +129,8 @@ struct trie_node {
* tag to distinguish internal nodes from leaves. This is safe as long
* as all dynamic allocations are aligned to more than a single byte.
*/
- uintptr_t children[]; // _counted_by(count_ones(bitmap))
+ // [[_counted_by(count_ones(bitmap))]]
+ uintptr_t children[];
};
/** Check if an encoded pointer is to an internal node. */
@@ -192,7 +193,7 @@ static unsigned char trie_leaf_nibble(const struct trie_leaf *leaf, size_t offse
}
/** Get the number of children of an internal node. */
-_trie_clones
+[[_trie_clones]]
static unsigned int trie_node_size(const struct trie_node *node) {
return count_ones((unsigned int)node->bitmap);
}
@@ -204,7 +205,7 @@ static unsigned int trie_node_size(const struct trie_node *node) {
* that case, the first mismatch between the key and the representative will be
* the depth at which to make a new branch to insert the key.
*/
-_trie_clones
+[[_trie_clones]]
static struct trie_leaf *trie_representative(const struct trie *trie, const void *key, size_t length) {
uintptr_t ptr = trie->root;
@@ -233,7 +234,7 @@ struct trie_leaf *trie_find_str(const struct trie *trie, const char *key) {
return trie_find_mem(trie, key, strlen(key) + 1);
}
-_trie_clones
+[[_trie_clones]]
static struct trie_leaf *trie_find_mem_impl(const struct trie *trie, const void *key, size_t length) {
struct trie_leaf *rep = trie_representative(trie, key, length);
if (rep && rep->length == length && memcmp(rep->key, key, length) == 0) {
@@ -257,7 +258,7 @@ void *trie_get_mem(const struct trie *trie, const void *key, size_t length) {
return leaf ? leaf->value : NULL;
}
-_trie_clones
+[[_trie_clones]]
static struct trie_leaf *trie_find_postfix_impl(const struct trie *trie, const char *key) {
size_t length = strlen(key);
struct trie_leaf *rep = trie_representative(trie, key, length + 1);
@@ -302,7 +303,7 @@ static bool trie_check_prefix(struct trie_leaf *leaf, size_t skip, const char *k
}
}
-_trie_clones
+[[_trie_clones]]
static struct trie_leaf *trie_find_prefix_impl(const struct trie *trie, const char *key) {
uintptr_t ptr = trie->root;
if (!ptr) {
@@ -456,7 +457,7 @@ static size_t trie_mismatch(const struct trie_leaf *rep, const void *key, size_t
* | Z
* +--->...
*/
-_trie_clones
+[[_trie_clones]]
static struct trie_leaf *trie_node_insert(struct trie *trie, uintptr_t *ptr, struct trie_leaf *leaf, unsigned char nibble) {
struct trie_node *node = trie_decode_node(*ptr);
unsigned int size = trie_node_size(node);
@@ -579,7 +580,7 @@ struct trie_leaf *trie_insert_str(struct trie *trie, const char *key) {
return trie_insert_mem(trie, key, strlen(key) + 1);
}
-_trie_clones
+[[_trie_clones]]
static struct trie_leaf *trie_insert_mem_impl(struct trie *trie, const void *key, size_t length) {
struct trie_leaf *rep = trie_representative(trie, key, length);
size_t mismatch = trie_mismatch(rep, key, length);
@@ -707,7 +708,7 @@ static int trie_collapse_node(struct trie *trie, uintptr_t *parent, struct trie_
return 0;
}
-_trie_clones
+[[_trie_clones]]
static void trie_remove_impl(struct trie *trie, struct trie_leaf *leaf) {
uintptr_t *child = &trie->root;
uintptr_t *parent = NULL;
diff --git a/src/trie.h b/src/trie.h
index 19bd81d..fa10670 100644
--- a/src/trie.h
+++ b/src/trie.h
@@ -21,7 +21,8 @@ struct trie_leaf {
/** The length of the key in bytes. */
size_t length;
/** The key itself, stored inline. */
- char key[] _counted_by(length);
+ [[_counted_by(length)]]
+ char key[];
};
/**
diff --git a/src/xspawn.c b/src/xspawn.c
index ee62c05..efa2219 100644
--- a/src/xspawn.c
+++ b/src/xspawn.c
@@ -119,7 +119,7 @@ int bfs_spawn_destroy(struct bfs_spawn *ctx) {
#if BFS_POSIX_SPAWN >= 0
/** Set some posix_spawnattr flags. */
-_maybe_unused
+[[_maybe_unused]]
static int bfs_spawn_addflags(struct bfs_spawn *ctx, short flags) {
short prev;
errno = posix_spawnattr_getflags(&ctx->attr, &prev);
@@ -581,7 +581,7 @@ static bool bfs_use_posix_spawn(const struct bfs_resolver *res, const struct bfs
#endif // BFS_POSIX_SPAWN >= 0
/** Actually exec() the new process. */
-_noreturn
+[[_noreturn]]
static void bfs_spawn_exec(struct bfs_resolver *res, const struct bfs_spawn *ctx, char **argv, char **envp, const sigset_t *mask, int pipefd[2]) {
xclose(pipefd[0]);