From dccb52556730ff060bcccbe764cef4b13b3d5712 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 26 Sep 2023 12:48:21 -0400 Subject: dstring: New dchar typedef for dynamic strings --- src/bar.c | 2 +- src/bftw.c | 2 +- src/color.c | 6 +++--- src/color.h | 3 ++- src/diag.c | 2 +- src/dstring.c | 55 ++++++++++++++++++++++++++------------------------- src/dstring.h | 63 ++++++++++++++++++++++++++++++++++++++--------------------- src/eval.c | 4 ++-- src/exec.c | 4 ++-- src/fsade.c | 4 ++-- src/printf.c | 4 ++-- 11 files changed, 85 insertions(+), 64 deletions(-) diff --git a/src/bar.c b/src/bar.c index d2c663c..e0b9393 100644 --- a/src/bar.c +++ b/src/bar.c @@ -129,7 +129,7 @@ BFS_FORMATTER(2, 3) static int bfs_bar_printf(struct bfs_bar *bar, const char *format, ...) { va_list args; va_start(args, format); - char *str = dstrvprintf(format, args); + dchar *str = dstrvprintf(format, args); va_end(args); if (!str) { diff --git a/src/bftw.c b/src/bftw.c index f3060ce..5e5f4a5 100644 --- a/src/bftw.c +++ b/src/bftw.c @@ -435,7 +435,7 @@ struct bftw_state { struct bftw_list batch; /** The current path. */ - char *path; + dchar *path; /** The current file. */ struct bftw_file *file; /** The previous file. */ diff --git a/src/color.c b/src/color.c index 5e78c6c..8d0b995 100644 --- a/src/color.c +++ b/src/color.c @@ -558,8 +558,8 @@ static int unescape(char **str, const char *value, char end, const char **next) /** Parse the GNU $LS_COLORS format. */ static int parse_gnu_ls_colors(struct colors *colors, const char *ls_colors) { int ret = -1; - char *key = NULL; - char *value = NULL; + dchar *key = NULL; + dchar *value = NULL; for (const char *chunk = ls_colors, *next; chunk; chunk = next) { if (chunk[0] == '*') { @@ -943,7 +943,7 @@ static ssize_t first_broken_offset(const char *path, const struct BFTW *ftwbuf, goto out; } - char *at_path; + dchar *at_path; int at_fd; if (path == ftwbuf->path) { if (ftwbuf->depth == 0) { diff --git a/src/color.h b/src/color.h index 0d46c33..b118f77 100644 --- a/src/color.h +++ b/src/color.h @@ -9,6 +9,7 @@ #define BFS_COLOR_H #include "config.h" +#include "dstring.h" #include #include @@ -41,7 +42,7 @@ typedef struct CFILE { /** The color table to use, if any. */ const struct colors *colors; /** A buffer for colored formatting. */ - char *buffer; + dchar *buffer; /** Whether the next ${rs} is actually necessary. */ bool need_reset; /** Whether to close the underlying stream. */ diff --git a/src/diag.c b/src/diag.c index 0590847..fa9db39 100644 --- a/src/diag.c +++ b/src/diag.c @@ -158,7 +158,7 @@ static void bfs_argv_diag(const struct bfs_ctx *ctx, const bool args[], bool war bfs_error_prefix(ctx); } - char **argv = ZALLOC_ARRAY(char *, ctx->argc); + dchar **argv = ZALLOC_ARRAY(dchar *, ctx->argc); if (!argv) { return; } diff --git a/src/dstring.c b/src/dstring.c index 60a7df9..ef4e733 100644 --- a/src/dstring.c +++ b/src/dstring.c @@ -4,6 +4,7 @@ #include "dstring.h" #include "alloc.h" #include "bit.h" +#include "config.h" #include "diag.h" #include #include @@ -16,11 +17,11 @@ struct dstring { size_t capacity; size_t length; - char data[]; + alignas(dchar) char data[]; }; /** Get the string header from the string data pointer. */ -static struct dstring *dstrheader(const char *dstr) { +static struct dstring *dstrheader(const dchar *dstr) { return (struct dstring *)(dstr - offsetof(struct dstring, data)); } @@ -30,7 +31,7 @@ static size_t dstrsize(size_t capacity) { } /** Allocate a dstring with the given contents. */ -static char *dstralloc_impl(size_t capacity, size_t length, const char *data) { +static dchar *dstralloc_impl(size_t capacity, size_t length, const char *data) { // Avoid reallocations for small strings if (capacity < 7) { capacity = 7; @@ -49,31 +50,31 @@ static char *dstralloc_impl(size_t capacity, size_t length, const char *data) { return header->data; } -char *dstralloc(size_t capacity) { +dchar *dstralloc(size_t capacity) { return dstralloc_impl(capacity, 0, ""); } -char *dstrdup(const char *str) { +dchar *dstrdup(const char *str) { return dstrxdup(str, strlen(str)); } -char *dstrndup(const char *str, size_t n) { +dchar *dstrndup(const char *str, size_t n) { return dstrxdup(str, strnlen(str, n)); } -char *dstrddup(const char *dstr) { +dchar *dstrddup(const dchar *dstr) { return dstrxdup(dstr, dstrlen(dstr)); } -char *dstrxdup(const char *str, size_t len) { +dchar *dstrxdup(const char *str, size_t len) { return dstralloc_impl(len, len, str); } -size_t dstrlen(const char *dstr) { +size_t dstrlen(const dchar *dstr) { return dstrheader(dstr)->length; } -int dstreserve(char **dstr, size_t capacity) { +int dstreserve(dchar **dstr, size_t capacity) { if (!*dstr) { *dstr = dstralloc(capacity); return *dstr ? 0 : -1; @@ -96,7 +97,7 @@ int dstreserve(char **dstr, size_t capacity) { return 0; } -int dstresize(char **dstr, size_t length) { +int dstresize(dchar **dstr, size_t length) { if (dstreserve(dstr, length) != 0) { return -1; } @@ -107,19 +108,19 @@ int dstresize(char **dstr, size_t length) { return 0; } -int dstrcat(char **dest, const char *src) { +int dstrcat(dchar **dest, const char *src) { return dstrxcat(dest, src, strlen(src)); } -int dstrncat(char **dest, const char *src, size_t n) { +int dstrncat(dchar **dest, const char *src, size_t n) { return dstrxcat(dest, src, strnlen(src, n)); } -int dstrdcat(char **dest, const char *src) { +int dstrdcat(dchar **dest, const dchar *src) { return dstrxcat(dest, src, dstrlen(src)); } -int dstrxcat(char **dest, const char *src, size_t len) { +int dstrxcat(dchar **dest, const char *src, size_t len) { size_t oldlen = dstrlen(*dest); size_t newlen = oldlen + len; @@ -131,23 +132,23 @@ int dstrxcat(char **dest, const char *src, size_t len) { return 0; } -int dstrapp(char **str, char c) { +int dstrapp(dchar **str, char c) { return dstrxcat(str, &c, 1); } -int dstrcpy(char **dest, const char *src) { +int dstrcpy(dchar **dest, const char *src) { return dstrxcpy(dest, src, strlen(src)); } -int dstrncpy(char **dest, const char *src, size_t n) { +int dstrncpy(dchar **dest, const char *src, size_t n) { return dstrxcpy(dest, src, strnlen(src, n)); } -int dstrdcpy(char **dest, const char *src) { +int dstrdcpy(dchar **dest, const dchar *src) { return dstrxcpy(dest, src, dstrlen(src)); } -int dstrxcpy(char **dest, const char *src, size_t len) { +int dstrxcpy(dchar **dest, const char *src, size_t len) { if (dstresize(dest, len) != 0) { return -1; } @@ -160,7 +161,7 @@ char *dstrprintf(const char *format, ...) { va_list args; va_start(args, format); - char *str = dstrvprintf(format, args); + dchar *str = dstrvprintf(format, args); va_end(args); return str; @@ -168,7 +169,7 @@ char *dstrprintf(const char *format, ...) { char *dstrvprintf(const char *format, va_list args) { // Guess a capacity to try to avoid reallocating - char *str = dstralloc(2*strlen(format)); + dchar *str = dstralloc(2*strlen(format)); if (!str) { return NULL; } @@ -181,7 +182,7 @@ char *dstrvprintf(const char *format, va_list args) { return str; } -int dstrcatf(char **str, const char *format, ...) { +int dstrcatf(dchar **str, const char *format, ...) { va_list args; va_start(args, format); @@ -191,7 +192,7 @@ int dstrcatf(char **str, const char *format, ...) { return ret; } -int dstrvcatf(char **str, const char *format, va_list args) { +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)); @@ -232,11 +233,11 @@ fail: return -1; } -int dstrescat(char **dest, const char *str, enum wesc_flags flags) { +int dstrescat(dchar **dest, const char *str, enum wesc_flags flags) { return dstrnescat(dest, str, SIZE_MAX, flags); } -int dstrnescat(char **dest, const char *str, size_t n, enum wesc_flags flags) { +int dstrnescat(dchar **dest, const char *str, size_t n, enum wesc_flags flags) { size_t len = *dest ? dstrlen(*dest) : 0; // Worst case growth is `ccc...` => $'\xCC\xCC\xCC...' @@ -254,7 +255,7 @@ int dstrnescat(char **dest, const char *str, size_t n, enum wesc_flags flags) { return dstresize(dest, cur - *dest); } -void dstrfree(char *dstr) { +void dstrfree(dchar *dstr) { if (dstr) { free(dstrheader(dstr)); } diff --git a/src/dstring.h b/src/dstring.h index 88ca79f..91a600c 100644 --- a/src/dstring.h +++ b/src/dstring.h @@ -13,13 +13,32 @@ #include #include +/** Marker type for dynamic strings. */ +#if __clang__ +// Abuse __attribute__(aligned) to make a type that allows +// +// dchar * -> char * +// +// conversions, but warns on +// +// char * -> dchar * +// +// (with Clang's -Walign-mismatch). The alignment is not a lie, due to the +// layout of struct dstring, but we only enable this on Clang because GCC +// tracks alignment through array accesses, reporting UBSan errors on (and +// maybe even miscompiling) dstr[1]. +typedef __attribute__((aligned(alignof(size_t)))) char dchar; +#else +typedef char dchar; +#endif + /** * Allocate a dynamic string. * * @param capacity * The initial capacity of the string. */ -char *dstralloc(size_t capacity); +dchar *dstralloc(size_t capacity); /** * Create a dynamic copy of a string. @@ -27,7 +46,7 @@ char *dstralloc(size_t capacity); * @param str * The NUL-terminated string to copy. */ -char *dstrdup(const char *str); +dchar *dstrdup(const char *str); /** * Create a length-limited dynamic copy of a string. @@ -37,7 +56,7 @@ char *dstrdup(const char *str); * @param n * The maximum number of characters to copy from str. */ -char *dstrndup(const char *str, size_t n); +dchar *dstrndup(const char *str, size_t n); /** * Create a dynamic copy of a dynamic string. @@ -45,7 +64,7 @@ char *dstrndup(const char *str, size_t n); * @param dstr * The dynamic string to copy. */ -char *dstrddup(const char *dstr); +dchar *dstrddup(const dchar *dstr); /** * Create an exact-sized dynamic copy of a string. @@ -55,7 +74,7 @@ char *dstrddup(const char *dstr); * @param len * The length of the string, which may include internal NUL bytes. */ -char *dstrxdup(const char *str, size_t len); +dchar *dstrxdup(const char *str, size_t len); /** * Get a dynamic string's length. @@ -65,7 +84,7 @@ char *dstrxdup(const char *str, size_t len); * @return * The length of dstr. */ -size_t dstrlen(const char *dstr); +size_t dstrlen(const dchar *dstr); /** * Reserve some capacity in a dynamic string. @@ -77,7 +96,7 @@ size_t dstrlen(const char *dstr); * @return * 0 on success, -1 on failure. */ -int dstreserve(char **dstr, size_t capacity); +int dstreserve(dchar **dstr, size_t capacity); /** * Resize a dynamic string. @@ -89,7 +108,7 @@ int dstreserve(char **dstr, size_t capacity); * @return * 0 on success, -1 on failure. */ -int dstresize(char **dstr, size_t length); +int dstresize(dchar **dstr, size_t length); /** * Append to a dynamic string. @@ -100,7 +119,7 @@ int dstresize(char **dstr, size_t length); * The string to append. * @return 0 on success, -1 on failure. */ -int dstrcat(char **dest, const char *src); +int dstrcat(dchar **dest, const char *src); /** * Append to a dynamic string. @@ -114,7 +133,7 @@ int dstrcat(char **dest, const char *src); * @return * 0 on success, -1 on failure. */ -int dstrncat(char **dest, const char *src, size_t n); +int dstrncat(dchar **dest, const char *src, size_t n); /** * Append a dynamic string to another dynamic string. @@ -126,7 +145,7 @@ int dstrncat(char **dest, const char *src, size_t n); * @return * 0 on success, -1 on failure. */ -int dstrdcat(char **dest, const char *src); +int dstrdcat(dchar **dest, const dchar *src); /** * Append to a dynamic string. @@ -140,7 +159,7 @@ int dstrdcat(char **dest, const char *src); * @return * 0 on success, -1 on failure. */ -int dstrxcat(char **dest, const char *src, size_t len); +int dstrxcat(dchar **dest, const char *src, size_t len); /** * Append a single character to a dynamic string. @@ -152,7 +171,7 @@ int dstrxcat(char **dest, const char *src, size_t len); * @return * 0 on success, -1 on failure. */ -int dstrapp(char **str, char c); +int dstrapp(dchar **str, char c); /** * Copy a string into a dynamic string. @@ -164,7 +183,7 @@ int dstrapp(char **str, char c); * @returns * 0 on success, -1 on failure. */ -int dstrcpy(char **dest, const char *str); +int dstrcpy(dchar **dest, const char *str); /** * Copy a dynamic string into another one. @@ -176,7 +195,7 @@ int dstrcpy(char **dest, const char *str); * @returns * 0 on success, -1 on failure. */ -int dstrdcpy(char **dest, const char *str); +int dstrdcpy(dchar **dest, const dchar *str); /** * Copy a string into a dynamic string. @@ -190,7 +209,7 @@ int dstrdcpy(char **dest, const char *str); * @returns * 0 on success, -1 on failure. */ -int dstrncpy(char **dest, const char *str, size_t n); +int dstrncpy(dchar **dest, const char *str, size_t n); /** * Copy a string into a dynamic string. @@ -204,7 +223,7 @@ int dstrncpy(char **dest, const char *str, size_t n); * @returns * 0 on success, -1 on failure. */ -int dstrxcpy(char **dest, const char *str, size_t len); +int dstrxcpy(dchar **dest, const char *str, size_t len); /** * Create a dynamic string from a format string. @@ -245,7 +264,7 @@ char *dstrvprintf(const char *format, va_list args); * 0 on success, -1 on failure. */ BFS_FORMATTER(2, 3) -int dstrcatf(char **str, const char *format, ...); +int dstrcatf(dchar **str, const char *format, ...); /** * Format some text from a va_list onto the end of a dynamic string. @@ -260,7 +279,7 @@ int dstrcatf(char **str, const char *format, ...); * 0 on success, -1 on failure. */ BFS_FORMATTER(2, 0) -int dstrvcatf(char **str, const char *format, va_list args); +int dstrvcatf(dchar **str, const char *format, va_list args); /** * Concatenate while shell-escaping. @@ -274,7 +293,7 @@ int dstrvcatf(char **str, const char *format, va_list args); * @return * 0 on success, -1 on failure. */ -int dstrescat(char **dest, const char *str, enum wesc_flags flags); +int dstrescat(dchar **dest, const char *str, enum wesc_flags flags); /** * Concatenate while shell-escaping. @@ -290,7 +309,7 @@ int dstrescat(char **dest, const char *str, enum wesc_flags flags); * @return * 0 on success, -1 on failure. */ -int dstrnescat(char **dest, const char *str, size_t n, enum wesc_flags flags); +int dstrnescat(dchar **dest, const char *str, size_t n, enum wesc_flags flags); /** * Free a dynamic string. @@ -298,6 +317,6 @@ int dstrnescat(char **dest, const char *str, size_t n, enum wesc_flags flags); * @param dstr * The string to free. */ -void dstrfree(char *dstr); +void dstrfree(dchar *dstr); #endif // BFS_DSTRING_H diff --git a/src/eval.c b/src/eval.c index 0faf533..3550751 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1115,7 +1115,7 @@ static void eval_status(struct bfs_eval *state, struct bfs_bar *bar, struct time const struct BFTW *ftwbuf = state->ftwbuf; - char *rhs = dstrprintf(" (visited: %zu, depth: %2zu)", count, ftwbuf->depth); + dchar *rhs = dstrprintf(" (visited: %zu, depth: %2zu)", count, ftwbuf->depth); if (!rhs) { return; } @@ -1126,7 +1126,7 @@ static void eval_status(struct bfs_eval *state, struct bfs_bar *bar, struct time rhslen = 0; } - char *status = dstralloc(0); + dchar *status = dstralloc(0); if (!status) { goto out_rhs; } diff --git a/src/exec.c b/src/exec.c index ea7f897..7b55522 100644 --- a/src/exec.c +++ b/src/exec.c @@ -227,7 +227,7 @@ static char *bfs_exec_format_arg(char *arg, const char *path) { return arg; } - char *ret = dstralloc(0); + dchar *ret = dstralloc(0); if (!ret) { return NULL; } @@ -259,7 +259,7 @@ err: /** Free a formatted argument. */ static void bfs_exec_free_arg(char *arg, const char *tmpl) { if (arg != tmpl) { - dstrfree(arg); + dstrfree((dchar *)arg); } } diff --git a/src/fsade.c b/src/fsade.c index c401426..8dec5a8 100644 --- a/src/fsade.c +++ b/src/fsade.c @@ -37,7 +37,7 @@ static const char *fake_at(const struct BFTW *ftwbuf) { static atomic int proc_works = -1; - char *path = NULL; + dchar *path = NULL; if (ftwbuf->at_fd == AT_FDCWD || load(&proc_works, relaxed) == 0) { goto fail; } @@ -69,7 +69,7 @@ fail: static void free_fake_at(const struct BFTW *ftwbuf, const char *path) { if (path != ftwbuf->path) { - dstrfree((char *)path); + dstrfree((dchar *)path); } } diff --git a/src/printf.c b/src/printf.c index f0910fa..5de5a28 100644 --- a/src/printf.c +++ b/src/printf.c @@ -38,7 +38,7 @@ struct bfs_printf { /** The printing function to invoke. */ bfs_printf_fn *fn; /** String data associated with this directive. */ - char *str; + dchar *str; /** The stat field to print. */ enum bfs_stat_field stat_field; /** Character data associated with this directive. */ @@ -596,7 +596,7 @@ static int append_directive(const struct bfs_ctx *ctx, struct bfs_printf **forma int bfs_printf_parse(const struct bfs_ctx *ctx, struct bfs_expr *expr, const char *format) { expr->printf = NULL; - char *literal = dstralloc(0); + dchar *literal = dstralloc(0); if (!literal) { bfs_perror(ctx, "dstralloc()"); goto error; -- cgit v1.2.3