Something went wrong. Try again.
A breadth-first version of the UNIX find command tavianator.com/projects/bfs.html
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356// Copyright © Tavian Barnes <tavianator@tavianator.com>// SPDX-License-Identifier: 0BSD
/** * A dynamic string library. */
#ifndef BFS_DSTRING_H#define BFS_DSTRING_H
#include "bfs.h"#include "bfstd.h"
#include <stdarg.h>#include <stddef.h>
/** Marker type for dynamic strings. */#if BFS_LINT && __clang__// Abuse [[gnu::aligned]] to make a type that allows//// dchar * -> char *//// conversions, but warns (with Clang's -Walign-mismatch) on//// char * -> dchar *typedef char dchar [[gnu::aligned(alignof(size_t))]];#elsetypedef char dchar;#endif
/** * Free a dynamic string. * * @dstr * The string to free. */void dstrfree(dchar *dstr);
/** * Allocate a dynamic string. * * @cap * The initial capacity of the string. */[[_malloc(dstrfree, 1)]]dchar *dstralloc(size_t cap);
/** * Create a dynamic copy of a string. * * @str * The NUL-terminated string to copy. */[[_malloc(dstrfree, 1)]]dchar *dstrdup(const char *str);
/** * Create a length-limited dynamic copy of a string. * * @str * The string to copy. * @n * The maximum number of characters to copy from str. */[[_malloc(dstrfree, 1)]]dchar *dstrndup(const char *str, size_t n);
/** * Create a dynamic copy of a dynamic string. * * @dstr * The dynamic string to copy. */[[_malloc(dstrfree, 1)]]dchar *dstrddup(const dchar *dstr);
/** * Create an exact-sized dynamic copy of a string. * * @str * The string to copy. * @len * The length of the string, which may include internal NUL bytes. */[[_malloc(dstrfree, 1)]]dchar *dstrxdup(const char *str, size_t len);
/** * Get a dynamic string's length. * * @dstr * The string to measure. * @return * The length of dstr. */size_t dstrlen(const dchar *dstr);
/** * Reserve some capacity in a dynamic string. * * @dstr * The dynamic string to preallocate. * @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. * * @dstr * The dynamic string to resize. * @len * The new length for the dynamic string. * @return * 0 on success, -1 on failure. */[[_nodiscard]]int dstresize(dchar **dstr, size_t len);
/** * Shrink a dynamic string. * * @dstr * The dynamic string to shrink. * @len * The new length. Must not be greater than the current length. */void dstrshrink(dchar *dstr, size_t len);
/** * Append to a dynamic string. * * @dest * The destination dynamic string. * @src * The string to append. * @return 0 on success, -1 on failure. */[[_nodiscard]]int dstrcat(dchar **dest, const char *src);
/** * Append to a dynamic string. * * @dest * The destination dynamic string. * @src * The string to append. * @n * The maximum number of characters to take from src. * @return * 0 on success, -1 on failure. */[[_nodiscard]]int dstrncat(dchar **dest, const char *src, size_t n);
/** * Append a dynamic string to another dynamic string. * * @dest * The destination dynamic string. * @src * The dynamic string to append. * @return * 0 on success, -1 on failure. */[[_nodiscard]]int dstrdcat(dchar **dest, const dchar *src);
/** * Append to a dynamic string. * * @dest * The destination dynamic string. * @src * The string to append. * @len * The exact number of characters to take from src. * @return * 0 on success, -1 on failure. */[[_nodiscard]]int dstrxcat(dchar **dest, const char *src, size_t len);
/** * Append a single character to a dynamic string. * * @str * The string to append to. * @c * The character to append. * @return * 0 on success, -1 on failure. */[[_nodiscard]]int dstrapp(dchar **str, char c);
/** * Copy a string into a dynamic string. * * @dest * The destination dynamic string. * @src * The string to copy. * @returns * 0 on success, -1 on failure. */[[_nodiscard]]int dstrcpy(dchar **dest, const char *str);
/** * Copy a dynamic string into another one. * * @dest * The destination dynamic string. * @src * The dynamic string to copy. * @returns * 0 on success, -1 on failure. */[[_nodiscard]]int dstrdcpy(dchar **dest, const dchar *str);
/** * Copy a string into a dynamic string. * * @dest * The destination dynamic string. * @src * The dynamic string to copy. * @n * The maximum number of characters to take from src. * @returns * 0 on success, -1 on failure. */[[_nodiscard]]int dstrncpy(dchar **dest, const char *str, size_t n);
/** * Copy a string into a dynamic string. * * @dest * The destination dynamic string. * @src * The dynamic string to copy. * @len * The exact number of characters to take from src. * @returns * 0 on success, -1 on failure. */[[_nodiscard]]int dstrxcpy(dchar **dest, const char *str, size_t len);
/** * Create a dynamic string from a format string. * * @format * The format string to fill in. * @... * Any arguments for the format string. * @return * The created string, or NULL on failure. */[[_nodiscard]][[_printf(1, 2)]]dchar *dstrprintf(const char *format, ...);
/** * Create a dynamic string from a format string and a va_list. * * @format * The format string to fill in. * @args * The arguments for the format string. * @return * The created string, or NULL on failure. */[[_nodiscard]][[_printf(1, 0)]]dchar *dstrvprintf(const char *format, va_list args);
/** * Format some text onto the end of a dynamic string. * * @str * The destination dynamic string. * @format * The format string to fill in. * @... * Any arguments for the format string. * @return * 0 on success, -1 on failure. */[[_nodiscard]][[_printf(2, 3)]]int dstrcatf(dchar **str, const char *format, ...);
/** * Format some text from a va_list onto the end of a dynamic string. * * @str * The destination dynamic string. * @format * The format string to fill in. * @args * The arguments for the format string. * @return * 0 on success, -1 on failure. */[[_nodiscard]][[_printf(2, 0)]]int dstrvcatf(dchar **str, const char *format, va_list args);
/** * Concatenate while shell-escaping. * * @dest * The destination dynamic string. * @str * The string to escape. * @flags * Flags for wordesc(). * @return * 0 on success, -1 on failure. */[[_nodiscard]]int dstrescat(dchar **dest, const char *str, enum wesc_flags flags);
/** * Concatenate while shell-escaping. * * @dest * The destination dynamic string. * @str * The string to escape. * @n * The maximum length of the string. * @flags * Flags for wordesc(). * @return * 0 on success, -1 on failure. */[[_nodiscard]]int dstrnescat(dchar **dest, const char *str, size_t n, enum wesc_flags flags);
/** * Repeat a string n times. */[[_nodiscard]]dchar *dstrepeat(const char *str, size_t n);
#endif // BFS_DSTRING_H