From efb24a431007012a31641b25ea2c1857d5d8d803 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 17 Oct 2024 12:23:03 -0400 Subject: dstring: Add an infallible dstrshrink() function And mark the fallible ones with _nodiscard. --- src/color.c | 4 ++-- src/dstring.c | 21 ++++++++++++++++----- src/dstring.h | 27 +++++++++++++++++++++++++++ src/eval.c | 4 ++-- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/color.c b/src/color.c index 9ac7b85..036dda5 100644 --- a/src/color.c +++ b/src/color.c @@ -920,7 +920,7 @@ static int cpath_init(struct cpath *cpath, const char *path, const struct BFTW * } cpath_retreat(cpath); - dstresize(&at_path, at_off + cpath->valid); + dstrshrink(at_path, at_off + cpath->valid); } dstrfree(at_path); @@ -1518,7 +1518,7 @@ int cvfprintf(CFILE *cfile, const char *format, va_list args) { } } - dstresize(&cfile->buffer, 0); + dstrshrink(cfile->buffer, 0); return ret; } diff --git a/src/dstring.c b/src/dstring.c index af499fd..0f08679 100644 --- a/src/dstring.c +++ b/src/dstring.c @@ -46,6 +46,13 @@ static dchar *dstrdata(struct dstring *header) { return (char *)header + DSTR_OFFSET; } +/** Set the length of a dynamic string. */ +static void dstrsetlen(struct dstring *header, size_t len) { + bfs_assert(len < header->cap); + header->len = len; + header->str[len] = '\0'; +} + /** Allocate a dstring with the given contents. */ static dchar *dstralloc_impl(size_t cap, size_t len, const char *str) { // Avoid reallocations for small strings @@ -59,11 +66,10 @@ static dchar *dstralloc_impl(size_t cap, size_t len, const char *str) { } header->cap = cap; - header->len = len; + dstrsetlen(header, len); - char *ret = dstrdata(header); + dchar *ret = dstrdata(header); memcpy(ret, str, len); - ret[len] = '\0'; return ret; } @@ -121,11 +127,16 @@ int dstresize(dchar **dstr, size_t len) { } struct dstring *header = dstrheader(*dstr); - header->len = len; - header->str[len] = '\0'; + dstrsetlen(header, len); return 0; } +void dstrshrink(dchar *dstr, size_t len) { + struct dstring *header = dstrheader(dstr); + bfs_assert(len <= header->len); + dstrsetlen(header, len); +} + int dstrcat(dchar **dest, const char *src) { return dstrxcat(dest, src, strlen(src)); } diff --git a/src/dstring.h b/src/dstring.h index f7afcf7..ce7ef86 100644 --- a/src/dstring.h +++ b/src/dstring.h @@ -117,8 +117,19 @@ int dstreserve(dchar **dstr, size_t cap); * @return * 0 on success, -1 on failure. */ +_nodiscard int dstresize(dchar **dstr, size_t len); +/** + * Shrink a dynamic string. + * + * @dstr + * The dynamic string to shrink. + * @len + * The new length. Must not be greater than the current length. + */ +void dstrshrink(dchar *dstr, size_t len); + /** * Append to a dynamic string. * @@ -128,6 +139,7 @@ int dstresize(dchar **dstr, size_t len); * The string to append. * @return 0 on success, -1 on failure. */ +_nodiscard int dstrcat(dchar **dest, const char *src); /** @@ -142,6 +154,7 @@ int dstrcat(dchar **dest, const char *src); * @return * 0 on success, -1 on failure. */ +_nodiscard int dstrncat(dchar **dest, const char *src, size_t n); /** @@ -154,6 +167,7 @@ int dstrncat(dchar **dest, const char *src, size_t n); * @return * 0 on success, -1 on failure. */ +_nodiscard int dstrdcat(dchar **dest, const dchar *src); /** @@ -168,6 +182,7 @@ int dstrdcat(dchar **dest, const dchar *src); * @return * 0 on success, -1 on failure. */ +_nodiscard int dstrxcat(dchar **dest, const char *src, size_t len); /** @@ -180,6 +195,7 @@ int dstrxcat(dchar **dest, const char *src, size_t len); * @return * 0 on success, -1 on failure. */ +_nodiscard int dstrapp(dchar **str, char c); /** @@ -192,6 +208,7 @@ int dstrapp(dchar **str, char c); * @returns * 0 on success, -1 on failure. */ +_nodiscard int dstrcpy(dchar **dest, const char *str); /** @@ -204,6 +221,7 @@ int dstrcpy(dchar **dest, const char *str); * @returns * 0 on success, -1 on failure. */ +_nodiscard int dstrdcpy(dchar **dest, const dchar *str); /** @@ -218,6 +236,7 @@ int dstrdcpy(dchar **dest, const dchar *str); * @returns * 0 on success, -1 on failure. */ +_nodiscard int dstrncpy(dchar **dest, const char *str, size_t n); /** @@ -232,6 +251,7 @@ int dstrncpy(dchar **dest, const char *str, size_t n); * @returns * 0 on success, -1 on failure. */ +_nodiscard int dstrxcpy(dchar **dest, const char *str, size_t len); /** @@ -244,6 +264,7 @@ int dstrxcpy(dchar **dest, const char *str, size_t len); * @return * The created string, or NULL on failure. */ +_nodiscard _printf(1, 2) dchar *dstrprintf(const char *format, ...); @@ -257,6 +278,7 @@ dchar *dstrprintf(const char *format, ...); * @return * The created string, or NULL on failure. */ +_nodiscard _printf(1, 0) dchar *dstrvprintf(const char *format, va_list args); @@ -272,6 +294,7 @@ dchar *dstrvprintf(const char *format, va_list args); * @return * 0 on success, -1 on failure. */ +_nodiscard _printf(2, 3) int dstrcatf(dchar **str, const char *format, ...); @@ -287,6 +310,7 @@ int dstrcatf(dchar **str, const char *format, ...); * @return * 0 on success, -1 on failure. */ +_nodiscard _printf(2, 0) int dstrvcatf(dchar **str, const char *format, va_list args); @@ -302,6 +326,7 @@ int dstrvcatf(dchar **str, const char *format, va_list args); * @return * 0 on success, -1 on failure. */ +_nodiscard int dstrescat(dchar **dest, const char *str, enum wesc_flags flags); /** @@ -318,11 +343,13 @@ int dstrescat(dchar **dest, const char *str, enum wesc_flags flags); * @return * 0 on success, -1 on failure. */ +_nodiscard int dstrnescat(dchar **dest, const char *str, size_t n, enum wesc_flags flags); /** * Repeat a string n times. */ +_nodiscard dchar *dstrepeat(const char *str, size_t n); #endif // BFS_DSTRING_H diff --git a/src/eval.c b/src/eval.c index 57b4bd1..6e9fffd 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1164,7 +1164,7 @@ static void eval_status(struct bfs_eval *state, struct bfs_bar *bar, size_t coun size_t rhslen = xstrwidth(rhs); if (3 + rhslen > width) { - dstresize(&rhs, 0); + dstrshrink(rhs, 0); rhslen = 0; } @@ -1208,7 +1208,7 @@ static void eval_status(struct bfs_eval *state, struct bfs_bar *bar, size_t coun } pathwidth += cwidth; } - dstresize(&status, lhslen); + dstrshrink(status, lhslen); if (dstrcat(&status, "...") != 0) { goto out; -- cgit v1.2.3