summaryrefslogtreecommitdiffstats
path: root/src/dstring.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/dstring.h')
-rw-r--r--src/dstring.h322
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