summaryrefslogtreecommitdiffstats
path: root/src/dstring.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-07-13 13:30:16 -0400
committerTavian Barnes <tavianator@tavianator.com>2023-07-13 16:01:00 -0400
commit2c396fce53100cad4e472f29851f07030a80ee50 (patch)
tree4bbc7b2d313335600474b7370298a23b460ee356 /src/dstring.c
parente79f0d038d3ce916e744fd111b70d687f699c0bd (diff)
downloadbfs-2c396fce53100cad4e472f29851f07030a80ee50.tar.xz
bfstd: Support wordesc() without allocating
Diffstat (limited to 'src/dstring.c')
-rw-r--r--src/dstring.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/dstring.c b/src/dstring.c
index dada70b..60a7df9 100644
--- a/src/dstring.c
+++ b/src/dstring.c
@@ -232,6 +232,28 @@ fail:
return -1;
}
+int dstrescat(char **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) {
+ size_t len = *dest ? dstrlen(*dest) : 0;
+
+ // Worst case growth is `ccc...` => $'\xCC\xCC\xCC...'
+ n = strnlen(str, n);
+ size_t cap = len + 4 * n + 3;
+ if (dstreserve(dest, cap) != 0) {
+ return -1;
+ }
+
+ char *cur = *dest + len;
+ char *end = *dest + cap + 1;
+ cur = wordnesc(cur, end, str, n, flags);
+ bfs_assert(cur != end, "wordesc() result truncated");
+
+ return dstresize(dest, cur - *dest);
+}
+
void dstrfree(char *dstr) {
if (dstr) {
free(dstrheader(dstr));