diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2023-07-13 13:30:16 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2023-07-13 16:01:00 -0400 |
commit | 2c396fce53100cad4e472f29851f07030a80ee50 (patch) | |
tree | 4bbc7b2d313335600474b7370298a23b460ee356 /src/dstring.c | |
parent | e79f0d038d3ce916e744fd111b70d687f699c0bd (diff) | |
download | bfs-2c396fce53100cad4e472f29851f07030a80ee50.tar.xz |
bfstd: Support wordesc() without allocating
Diffstat (limited to 'src/dstring.c')
-rw-r--r-- | src/dstring.c | 22 |
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)); |