diff --git a/compile_commands.json b/compile_commands.json new file mode 100644 index 0000000..a7988aa --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,79 @@ +[ + { + "arguments": [ + "/usr/bin/clang", + "-c", + "-I./include", + "-fPIC", + "-o", + "dstring.so", + "src/dstring.c" + ], + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/dstring", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/dstring/src/dstring.c", + "output": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/dstring/dstring.so" + }, + { + "arguments": [ + "/usr/bin/clang-16", + "-cc1", + "-triple", + "x86_64-redhat-linux-gnu", + "-emit-obj", + "-mrelax-all", + "-disable-free", + "-clear-ast-before-backend", + "-disable-llvm-verifier", + "-discard-value-names", + "-main-file-name", + "-mrelocation-model", + "pic", + "-pic-level", + "2", + "-fhalf-no-semantic-interposition", + "-mframe-pointer=all", + "-fmath-errno", + "-ffp-contract=on", + "-fno-rounding-math", + "-mconstructor-aliases", + "-funwind-tables=2", + "-target-cpu", + "x86-64", + "-tune-cpu", + "generic", + "-mllvm", + "-treat-scalable-fixed-error-as-warning", + "-debugger-tuning=gdb", + "-fcoverage-compilation-dir=/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/dstring", + "-resource-dir", + "/usr/lib64/clang/16", + "-I", + "./include", + "-internal-isystem", + "/usr/lib64/clang/16/include", + "-internal-isystem", + "/usr/local/include", + "-internal-isystem", + "/usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include", + "-internal-externc-isystem", + "/include", + "-internal-externc-isystem", + "/usr/include", + "-fdebug-compilation-dir=/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/dstring", + "-ferror-limit", + "19", + "-fgnuc-version=4.2.1", + "-fcolor-diagnostics", + "-faddrsig", + "-D__GCC_HAVE_DWARF2_CFI_ASM=1", + "-x", + "c", + "-o", + "/tmp/dstring-694812.o", + "src/dstring.c" + ], + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/dstring", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/dstring/src/dstring.c", + "output": "/tmp/dstring-694812.o" + } +] diff --git a/src/dstring.c b/src/dstring.c new file mode 100644 index 0000000..f6dd3d7 --- /dev/null +++ b/src/dstring.c @@ -0,0 +1,211 @@ +#include "dstring.h" +#include "aliases.h" +#include +#include +#include + +// Use this scalar to allocate extra memory in order to avoid having to +// constantly reallocate +#define CAPACITY_SCALAR 8 + +struct dstring { + u64 capacity; + u64 size; + char buf[]; +}; + +dstr_t *dstr_with_capacity(u64 capacity) { + dstr_t *out = (dstr_t *)malloc(sizeof(dstr_t) + capacity + 1); + + if (!out) { + return NULL; + } + + out->capacity = capacity; + out->size = 0; + memset(out->buf, 0, capacity + 1); + + return out; +} + +dstr_t *dstr_from_string(const char *str) { + u64 length = strlen(str); + + u64 capacity = length * CAPACITY_SCALAR; + + dstr_t *out = dstr_with_capacity(capacity); + + if (!out) { + return NULL; + } + + out->size = length; + strncpy(out->buf, str, length); + + return out; +} + +void dstr_update(dstr_t **dst, const char *src) { + if (!(*dst)) { + return; + } + + u64 length = strlen(src); + + dstr_t *str = *dst; + + if (length <= str->capacity) { + memset(str->buf, 0, str->capacity); + + str->size = length; + + strncpy(str->buf, src, length); + } else { + u64 capacity = length * CAPACITY_SCALAR; + + dstr_t *tmp = (dstr_t *)realloc(*dst, sizeof(dstr_t) + capacity + 1); + + if (!tmp) { + return; + } + + tmp->capacity = capacity; + tmp->size = length; + strncpy(tmp->buf, src, length); + + *dst = tmp; + } +} + +void dstr_free(dstr_t **str) { + if (!(*str)) { + return; + } + + free(*str); + *str = NULL; +} + +void dstr_concat(dstr_t **dst, const char *src) { + if (!(*dst)) { + return; + } + + u64 src_length = strlen(src); + + if (src_length == 0) { + return; + } + + u64 new_length = (*dst)->size + src_length; + + char str[new_length + 1]; + memset(str, 0, new_length + 1); + + strncpy(str, (*dst)->buf, (*dst)->size); + strncat(str, src, src_length); + + dstr_update(dst, str); +} + +void dstr_append(dstr_t **dst, char c) { + if (!(*dst)) { + return; + } + + u64 new_length = (*dst)->size + 1; + + char str[new_length + 1]; + memset(str, 0, new_length + 1); + + strncpy(str, (*dst)->buf, (*dst)->size); + str[(*dst)->size] = c; + + dstr_update(dst, str); +} + +void dstr_resize(dstr_t **str) { + u64 capacity = (*str)->size; + + dstr_t *tmp = (dstr_t *)realloc(*str, sizeof(dstr_t) + capacity + 1); + + if (!tmp) { + return; + } + + tmp->capacity = capacity; + + *str = tmp; +} + +void dstr_clear(dstr_t *str) { + if (!str || str->size == 0) { + return; + } + + memset(str->buf, 0, str->capacity); + str->size = 0; +} + +void dstr_print(const dstr_t *str) { + if (!str) { + return; + } + + printf("%s\n", str->buf); +} + +i64 dstr_find(const dstr_t *str, const char *substr) { + if (!str || !substr) { + return -1; + } + + u64 substr_length = strlen(substr); + + if (substr_length == 0 || substr_length > str->size) { + return -1; + } + + char buf[substr_length + 1]; + memset(buf, 0, substr_length + 1); + + for (i64 i = 0; i < str->size; ++i) { + if (i + substr_length >= str->size) { + break; + } + + for (u64 j = 0; j < substr_length; ++j) { + buf[j] = str->buf[i + j]; + } + + if (strcmp(buf, substr) == 0) { + return i; + } + } + + return -1; +} + +u64 dstr_length(const dstr_t *str) { + if (!str) { + return 0; + } + + return str->size; +} + +u64 dstr_capacity(const dstr_t *str) { + if (!str) { + return 0; + } + + return str->capacity; +} + +const char *dstr_to_cstr(const dstr_t *str) { + if (!str) { + return ""; + } + + return str->buf; +}