diff options
Diffstat (limited to 'src/dstring.h')
-rw-r--r-- | src/dstring.h | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/src/dstring.h b/src/dstring.h new file mode 100644 index 0000000..9ea7eb9 --- /dev/null +++ b/src/dstring.h @@ -0,0 +1,322 @@ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD + +/** + * A dynamic string library. + */ + +#ifndef BFS_DSTRING_H +#define BFS_DSTRING_H + +#include "prelude.h" +#include "bfstd.h" +#include <stdarg.h> +#include <stddef.h> + +/** Marker type for dynamic strings. */ +#if BFS_LINT && __clang__ +// Abuse __attribute__(aligned) to make a type that allows +// +// dchar * -> char * +// +// conversions, but warns (with Clang's -Walign-mismatch) on +// +// char * -> dchar * +typedef __attribute__((aligned(alignof(size_t)))) char dchar; +#else +typedef char dchar; +#endif + +/** + * Free a dynamic string. + * + * @param dstr + * The string to free. + */ +void dstrfree(dchar *dstr); + +/** + * Allocate a dynamic string. + * + * @param cap + * The initial capacity of the string. + */ +attr(malloc(dstrfree, 1)) +dchar *dstralloc(size_t cap); + +/** + * Create a dynamic copy of a string. + * + * @param str + * The NUL-terminated string to copy. + */ +attr(malloc(dstrfree, 1)) +dchar *dstrdup(const char *str); + +/** + * Create a length-limited dynamic copy of a string. + * + * @param str + * The string to copy. + * @param n + * The maximum number of characters to copy from str. + */ +attr(malloc(dstrfree, 1)) +dchar *dstrndup(const char *str, size_t n); + +/** + * Create a dynamic copy of a dynamic string. + * + * @param dstr + * The dynamic string to copy. + */ +attr(malloc(dstrfree, 1)) +dchar *dstrddup(const dchar *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. + */ +attr(malloc(dstrfree, 1)) +dchar *dstrxdup(const char *str, size_t len); + +/** + * Get a dynamic string's length. + * + * @param dstr + * The string to measure. + * @return + * The length of dstr. + */ +size_t dstrlen(const dchar *dstr); + +/** + * Reserve some capacity in a dynamic string. + * + * @param dstr + * The dynamic string to preallocate. + * @param cap + * The new capacity for the string. + * @return + * 0 on success, -1 on failure. + */ +int dstreserve(dchar **dstr, size_t cap); + +/** + * Resize a dynamic string. + * + * @param dstr + * The dynamic string to resize. + * @param len + * The new length for the dynamic string. + * @return + * 0 on success, -1 on failure. + */ +int dstresize(dchar **dstr, size_t len); + +/** + * Append to a dynamic string. + * + * @param dest + * The destination dynamic string. + * @param src + * The string to append. + * @return 0 on success, -1 on failure. + */ +int dstrcat(dchar **dest, const char *src); + +/** + * Append to a dynamic string. + * + * @param dest + * The destination dynamic string. + * @param src + * The string to append. + * @param n + * The maximum number of characters to take from src. + * @return + * 0 on success, -1 on failure. + */ +int dstrncat(dchar **dest, const char *src, size_t n); + +/** + * Append a dynamic string to another dynamic string. + * + * @param dest + * The destination dynamic string. + * @param src + * The dynamic string to append. + * @return + * 0 on success, -1 on failure. + */ +int dstrdcat(dchar **dest, const dchar *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(dchar **dest, const char *src, size_t len); + +/** + * Append a single character to a dynamic string. + * + * @param str + * The string to append to. + * @param c + * The character to append. + * @return + * 0 on success, -1 on failure. + */ +int dstrapp(dchar **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(dchar **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(dchar **dest, const dchar *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(dchar **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(dchar **dest, const char *str, size_t len); + +/** + * Create a dynamic string from a format string. + * + * @param format + * The format string to fill in. + * @param ... + * Any arguments for the format string. + * @return + * The created string, or NULL on failure. + */ +attr(printf(1, 2)) +char *dstrprintf(const char *format, ...); + +/** + * Create a dynamic string from a format string and a va_list. + * + * @param format + * The format string to fill in. + * @param args + * The arguments for the format string. + * @return + * The created string, or NULL on failure. + */ +attr(printf(1, 0)) +char *dstrvprintf(const char *format, va_list args); + +/** + * Format some text onto the end of a dynamic string. + * + * @param str + * The destination dynamic string. + * @param format + * The format string to fill in. + * @param ... + * Any arguments for the format string. + * @return + * 0 on success, -1 on failure. + */ +attr(printf(2, 3)) +int dstrcatf(dchar **str, const char *format, ...); + +/** + * Format some text from a va_list onto the end of a dynamic string. + * + * @param str + * The destination dynamic string. + * @param format + * The format string to fill in. + * @param args + * The arguments for the format string. + * @return + * 0 on success, -1 on failure. + */ +attr(printf(2, 0)) +int dstrvcatf(dchar **str, const char *format, va_list args); + +/** + * Concatenate while shell-escaping. + * + * @param dest + * The destination dynamic string. + * @param str + * The string to escape. + * @param flags + * Flags for wordesc(). + * @return + * 0 on success, -1 on failure. + */ +int dstrescat(dchar **dest, const char *str, enum wesc_flags flags); + +/** + * Concatenate while shell-escaping. + * + * @param dest + * The destination dynamic string. + * @param str + * The string to escape. + * @param n + * The maximum length of the string. + * @param flags + * Flags for wordesc(). + * @return + * 0 on success, -1 on failure. + */ +int dstrnescat(dchar **dest, const char *str, size_t n, enum wesc_flags flags); + +#endif // BFS_DSTRING_H |