// vim:fileencoding=utf-8:foldmethod=marker #ifndef STR8_H #define STR8_H #include "../../../common/aliases/aliases.h" #include "../../../common/assert/assert.h" #include "../../../common/platform/platform.h" #include "../../array/array.h" #include "../../dbl_list/dbl_list.h" #include "../../mem/allocator/mem_allocator.h" #include #ifdef WP_PLATFORM_CPP BEGIN_C_LINKAGE #endif // !WP_PLATFORM_CPP typedef struct WpStr8 WpStr8; struct WpStr8 { u64 capacity; u64 size; c8 *buf; }; typedef const WpStr8 WpStr8RO; /** * Utilities to be used with printf functions */ #define WP_STR8_SPEC "%.*s" #define wpStr8Varg(STRING) (int)((STRING).size), (STRING).buf /** * WpStr8 stack buffers */ #ifdef WP_PLATFORM_CPP // Uses a lambda to achieve the same behaviour achieved by the C macro #define wpStr8Buf(CAPACITY) ([&](){ \ wp_persist c8 buf[CAPACITY] = {}; \ memset(buf, 0, CAPACITY); \ return WpStr8{CAPACITY, 0, buf}; \ }()) // Uses a lambda to achieve the same behaviour achieved by the C macro #define wpStr8Lit(STRING) ([&]() { \ wp_persist c8 buf[sizeof(STRING) * 2] = {}; \ memcpy(buf, STRING, sizeof(STRING)); \ return WpStr8{(sizeof(STRING) - 1) * 2, sizeof(STRING) - 1, buf}; \ }()) #define wpStr8LitRo(STRING) WpStr8RO{sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING} #define wpStr8LitRoInitialiserList(STRING) {sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING} #else #define wpStr8Buf(CAPACITY) ((WpStr8){.capacity = CAPACITY, .size = 0, .buf = (c8[CAPACITY]){0}}) // Utilises the fact that memcpy returns pointer to dest buffer and that getting // address of compound literals is valid in C to create a string on the stack #define wpStr8Lit(STRING) ((WpStr8){.capacity = (sizeof(STRING) - 1) * 2, \ .size = sizeof(STRING) - 1, \ .buf = memcpy(&((c8 [sizeof(STRING) * 2]){0}), \ STRING, \ sizeof(STRING))}) #define wpStr8LitRo(STRING) ((WpStr8RO){.capacity = sizeof(STRING) - 1, \ .size = sizeof(STRING) - 1, \ .buf = (c8 *)STRING}) // To be used only when initialising a static storage variable in compilers that don't support // initialisers with the syntax of wpStr8LitRo (e.g. gcc). Should only be used when necessary // and only be assigned to a WpStr8RO variable to avoid any attempt at modifying the string #define wpStr8LitRoInitialiserList(STRING) {.capacity = sizeof(STRING) - 1, \ .size = sizeof(STRING) - 1, \ .buf = (c8 *)STRING} #endif // !WP_PLATFORM_CPP /** * WpStr8 allocated buffers */ WpStr8 *wpStr8AllocBuf(const WpAllocator *allocator, u64 capacity); WpStr8 *wpStr8AllocAndFillBuf(const WpAllocator *allocator, u64 capacity); WpStr8 *wpStr8AllocCstr(const WpAllocator *allocator, const char *str); WpStr8 *wpStr8AllocStr8(const WpAllocator *allocator, WpStr8RO *str); WpStr8 *wpStr8AllocSubstr(const WpAllocator *allocator, WpStr8RO *str, u64 start, u64 end); WpStr8 *wpStr8AllocConcat(const WpAllocator *allocator, WpStr8 *dst, WpStr8RO *src); // Only needed for allocators like malloc where each allocation has to be freed on its own. // No need to use it for allocators like Arena. void wpStr8DeallocBuf(const WpAllocator *allocator, WpStr8 **str); /** * WpStr8 utilities */ c8 wpStr8Get(WpStr8RO *str, u64 index); void wpStr8Set(WpStr8 *str, u64 index, c8 c); void wpStr8PushBack(WpStr8 *str, c8 c); b8 wpStr8Equal(WpStr8RO *s1, WpStr8RO *s2); b8 wpStr8EqualToCount(WpStr8RO* s1, WpStr8RO* s2, u64 count); WpStr8 wpStr8Slice(WpStr8RO *str, u64 start, u64 end); void wpStr8ConcatCapped(WpStr8 *dst, WpStr8RO *src); void wpStr8CopyCstrCapped(WpStr8 *dst, const char *src); void wpStr8CopyStr8Capped(WpStr8 *dst, WpStr8RO *src); void wpStr8CopyToCstr(char *dst, WpStr8RO *src, u64 dst_capacity); void wpStr8Format(WpStr8 *dst, const char *format, ...); void wpStr8ToLower(WpStr8 *dst, WpStr8RO *src); void wpStr8ToUpper(WpStr8 *dst, WpStr8RO *src); void wpStr8FromBytes(WpStr8 *dst, const WpU8Array src); /** * WpStr8 find functions */ i64 wpStr8Find(WpStr8RO *str, WpStr8RO substr); i64 wpStr8Rfind(WpStr8RO *str, WpStr8RO substr); /** * WpStr8 split and join */ #define wpStr8Split(ALLOCATOR, STR, DELIMITER) wpStr8SplitWithMax(ALLOCATOR, STR, DELIMITER, -1) #define wpStr8Rsplit(ALLOCATOR, STR, DELIMITER) wpStr8RsplitWithMax(ALLOCATOR, STR, DELIMITER, -1) WpStr8List *wpStr8SplitWithMax(const WpAllocator *allocator, WpStr8RO *str, WpStr8RO *delimiter, i64 max_splits); WpStr8List *wpStr8RsplitWithMax(const WpAllocator *allocator, WpStr8RO *str, WpStr8RO *delimiter, i64 max_splits); WpStr8 *wpStr8Join(const WpAllocator *allocator, const WpStr8List *list, WpStr8RO *delimiter); /** * WpStr8 list utilities */ u64 wpStr8ListTotalSize(const WpStr8List *list); #ifdef WP_PLATFORM_CPP END_C_LINKAGE #endif // !WP_PLATFORM_CPP #endif // !STR8_H