summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bar.c2
-rw-r--r--src/bftw.c2
-rw-r--r--src/color.c6
-rw-r--r--src/color.h3
-rw-r--r--src/diag.c2
-rw-r--r--src/dstring.c55
-rw-r--r--src/dstring.h63
-rw-r--r--src/eval.c4
-rw-r--r--src/exec.c4
-rw-r--r--src/fsade.c4
-rw-r--r--src/printf.c4
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 <stdarg.h>
#include <stdio.h>
@@ -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 <stdarg.h>
#include <stdio.h>
@@ -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 <stdarg.h>
#include <stddef.h>
+/** 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;