From 174a2027ff0db579e18d5efacb17c3addf6473f6 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 29 Jun 2023 13:53:03 -0400 Subject: dstring: Add some exact-size utility functions --- src/dstring.c | 57 ++++++++++++++++++++++++---------- src/dstring.h | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 135 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/dstring.c b/src/dstring.c index f019ba9..dada70b 100644 --- a/src/dstring.c +++ b/src/dstring.c @@ -54,12 +54,18 @@ char *dstralloc(size_t capacity) { } char *dstrdup(const char *str) { - size_t len = strlen(str); - return dstralloc_impl(len, len, str); + return dstrxdup(str, strlen(str)); } char *dstrndup(const char *str, size_t n) { - size_t len = strnlen(str, n); + return dstrxdup(str, strnlen(str, n)); +} + +char *dstrddup(const char *dstr) { + return dstrxdup(dstr, dstrlen(dstr)); +} + +char *dstrxdup(const char *str, size_t len) { return dstralloc_impl(len, len, str); } @@ -98,37 +104,56 @@ int dstresize(char **dstr, size_t length) { struct dstring *header = dstrheader(*dstr); header->length = length; header->data[length] = '\0'; - return 0; } -/** Common implementation of dstr{cat,ncat,app}. */ -static int dstrcat_impl(char **dest, const char *src, size_t srclen) { +int dstrcat(char **dest, const char *src) { + return dstrxcat(dest, src, strlen(src)); +} + +int dstrncat(char **dest, const char *src, size_t n) { + return dstrxcat(dest, src, strnlen(src, n)); +} + +int dstrdcat(char **dest, const char *src) { + return dstrxcat(dest, src, dstrlen(src)); +} + +int dstrxcat(char **dest, const char *src, size_t len) { size_t oldlen = dstrlen(*dest); - size_t newlen = oldlen + srclen; + size_t newlen = oldlen + len; if (dstresize(dest, newlen) != 0) { return -1; } - memcpy(*dest + oldlen, src, srclen); + memcpy(*dest + oldlen, src, len); return 0; } -int dstrcat(char **dest, const char *src) { - return dstrcat_impl(dest, src, strlen(src)); +int dstrapp(char **str, char c) { + return dstrxcat(str, &c, 1); } -int dstrncat(char **dest, const char *src, size_t n) { - return dstrcat_impl(dest, src, strnlen(src, n)); +int dstrcpy(char **dest, const char *src) { + return dstrxcpy(dest, src, strlen(src)); } -int dstrdcat(char **dest, const char *src) { - return dstrcat_impl(dest, src, dstrlen(src)); +int dstrncpy(char **dest, const char *src, size_t n) { + return dstrxcpy(dest, src, strnlen(src, n)); } -int dstrapp(char **str, char c) { - return dstrcat_impl(str, &c, 1); +int dstrdcpy(char **dest, const char *src) { + return dstrxcpy(dest, src, dstrlen(src)); +} + +int dstrxcpy(char **dest, const char *src, size_t len) { + if (dstresize(dest, len) != 0) { + return -1; + } + + memcpy(*dest, src, len); + return 0; } char *dstrprintf(const char *format, ...) { diff --git a/src/dstring.h b/src/dstring.h index ee3b345..2673f1b 100644 --- a/src/dstring.h +++ b/src/dstring.h @@ -38,12 +38,31 @@ char *dstrdup(const char *str); */ char *dstrndup(const char *str, size_t n); +/** + * Create a dynamic copy of a dynamic string. + * + * @param dstr + * The dynamic string to copy. + */ +char *dstrddup(const char *dstr); + +/** + * Create an exact-sized dynamic copy of a string. + * + * @param str + * The string to copy. + * @param len + * The length of the string, which may include internal NUL bytes. + */ +char *dstrxdup(const char *str, size_t len); + /** * Get a dynamic string's length. * * @param dstr * The string to measure. - * @return The length of dstr. + * @return + * The length of dstr. */ size_t dstrlen(const char *dstr); @@ -54,7 +73,8 @@ size_t dstrlen(const char *dstr); * The dynamic string to preallocate. * @param capacity * The new capacity for the string. - * @return 0 on success, -1 on failure. + * @return + * 0 on success, -1 on failure. */ int dstreserve(char **dstr, size_t capacity); @@ -65,7 +85,8 @@ int dstreserve(char **dstr, size_t capacity); * The dynamic string to resize. * @param length * The new length for the dynamic string. - * @return 0 on success, -1 on failure. + * @return + * 0 on success, -1 on failure. */ int dstresize(char **dstr, size_t length); @@ -89,7 +110,8 @@ int dstrcat(char **dest, const char *src); * The string to append. * @param n * The maximum number of characters to take from src. - * @return 0 on success, -1 on failure. + * @return + * 0 on success, -1 on failure. */ int dstrncat(char **dest, const char *src, size_t n); @@ -105,6 +127,20 @@ int dstrncat(char **dest, const char *src, size_t n); */ int dstrdcat(char **dest, const char *src); +/** + * Append to a dynamic string. + * + * @param dest + * The destination dynamic string. + * @param src + * The string to append. + * @param len + * The exact number of characters to take from src. + * @return + * 0 on success, -1 on failure. + */ +int dstrxcat(char **dest, const char *src, size_t len); + /** * Append a single character to a dynamic string. * @@ -112,10 +148,63 @@ int dstrdcat(char **dest, const char *src); * The string to append to. * @param c * The character to append. - * @return 0 on success, -1 on failure. + * @return + * 0 on success, -1 on failure. */ int dstrapp(char **str, char c); +/** + * Copy a string into a dynamic string. + * + * @param dest + * The destination dynamic string. + * @param src + * The string to copy. + * @returns + * 0 on success, -1 on failure. + */ +int dstrcpy(char **dest, const char *str); + +/** + * Copy a dynamic string into another one. + * + * @param dest + * The destination dynamic string. + * @param src + * The dynamic string to copy. + * @returns + * 0 on success, -1 on failure. + */ +int dstrdcpy(char **dest, const char *str); + +/** + * Copy a string into a dynamic string. + * + * @param dest + * The destination dynamic string. + * @param src + * The dynamic string to copy. + * @param n + * The maximum number of characters to take from src. + * @returns + * 0 on success, -1 on failure. + */ +int dstrncpy(char **dest, const char *str, size_t n); + +/** + * Copy a string into a dynamic string. + * + * @param dest + * The destination dynamic string. + * @param src + * The dynamic string to copy. + * @param len + * The exact number of characters to take from src. + * @returns + * 0 on success, -1 on failure. + */ +int dstrxcpy(char **dest, const char *str, size_t len); + /** * Create a dynamic string from a format string. * -- cgit v1.2.3