diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-07-14 21:12:37 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-07-14 21:12:37 +0200 |
commit | 30740ca4131d1f574718262451b4410207dc8d4e (patch) | |
tree | fc88b16a216079397ad85b9c6b1a1c1c5712a814 /kit/string_builder.h | |
parent | 5e3c99bb1cf1d03ea006300121265571f5008fd2 (diff) | |
download | saw-30740ca4131d1f574718262451b4410207dc8d4e.zip |
Reworking the build system
Diffstat (limited to 'kit/string_builder.h')
-rw-r--r-- | kit/string_builder.h | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/kit/string_builder.h b/kit/string_builder.h new file mode 100644 index 0000000..23eda65 --- /dev/null +++ b/kit/string_builder.h @@ -0,0 +1,112 @@ +#ifndef KIT_STRING_BUILDER_H +#define KIT_STRING_BUILDER_H + +#include "status.h" +#include "string_ref.h" +#include "dynamic_array.h" + +#include <assert.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef KIT_DA(char) kit_str_builder_t; + +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-function" +# pragma GCC diagnostic ignored "-Wunknown-pragmas" +# pragma GCC push_options +# pragma GCC optimize("O3") +#endif + +static kit_str_builder_t kit_str_build(kit_str_t s, + kit_allocator_t *alloc) { + assert(s.size >= 0 && (s.size == 0 || s.values != NULL)); + kit_str_builder_t builder; + memset(&builder, 0, sizeof builder); + if (s.size < 0 || (s.size != 0 && s.values == NULL)) + return builder; + KIT_DA_INIT(builder, s.size, alloc); + assert(builder.size == s.size); + if (builder.size == s.size) + memcpy(builder.values, s.values, s.size); + return builder; +} + +static kit_str_builder_t kit_substr_build(kit_str_t s, i64 index, + i64 size, + kit_allocator_t *alloc) { + assert(index + size <= s.size); + if (index + size > s.size) { + kit_str_builder_t builder; + memset(&builder, 0, sizeof builder); + return builder; + } + return kit_str_build(kit_str(size, s.values + index), alloc); +} + +static s32 kit_str_append(kit_str_builder_t *a, kit_str_t b) { + assert(a != NULL); + if (a == NULL) + return KIT_ERROR_INVALID_ARGUMENT; + if (b.size <= 0) + return KIT_OK; + i64 n = a->size; + KIT_DA_RESIZE(*a, n + b.size); + if (a->size != n + b.size) + return KIT_ERROR_OUT_OF_MEMORY; + memcpy(a->values + n, b.values, b.size); + return KIT_OK; +} + +static s32 kit_str_insert(kit_str_builder_t *a, i64 index, + kit_str_t b) { + assert(a != NULL && index >= 0 && index <= a->size); + if (a == NULL || index < 0 || index > a->size) + return KIT_ERROR_INVALID_ARGUMENT; + if (b.size <= 0) + return KIT_OK; + i64 n = a->size; + KIT_DA_RESIZE(*a, n + b.size); + if (a->size != n + b.size) + return KIT_ERROR_OUT_OF_MEMORY; + if (index < n) + memmove(a->values + (index + b.size), a->values + index, + n - index); + memcpy(a->values + index, b.values, b.size); + return KIT_OK; +} + +static s32 kit_str_erase(kit_str_builder_t *a, i64 index, i64 size) { + assert(a != NULL && index >= 0 && size >= 0 && + index + size <= a->size); + if (a == NULL || index < 0 || size < 0 || index + size > a->size) + return KIT_ERROR_INVALID_ARGUMENT; + if (size <= 0) + return KIT_OK; + if (index + size < a->size) + memmove(a->values + index, a->values + (index + size), + a->size - index - size); + KIT_DA_RESIZE(*a, a->size - size); + return KIT_OK; +} + +#ifdef __GNUC__ +# pragma GCC pop_options +# pragma GCC diagnostic pop +#endif + +#ifdef __cplusplus +} +#endif + +#define str_builder_t kit_str_builder_t +#define str_build kit_str_build +#define substr_build kit_substr_build +#define str_append kit_str_append +#define str_insert kit_str_insert +#define str_erase kit_str_erase + +#endif |