From 7ccae1c362a45b28f4fbf96da4f479730e4b382b Mon Sep 17 00:00:00 2001 From: Elis Eriksson Date: Sat, 13 Jun 2026 17:40:25 +0200 Subject: Initial Commit, probably needs heavy code cleanup --- src/str.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/str.c (limited to 'src/str.c') diff --git a/src/str.c b/src/str.c new file mode 100644 index 0000000..ddca742 --- /dev/null +++ b/src/str.c @@ -0,0 +1,119 @@ +#include "str.h" + +#include +#include +#include +#include +#include + +#define STARTING_SIZE 256 +#define READ_CHUNK_SIZE 1024 + +static void str_ensure_init(str *s) { + if (s->data) + return; + + s->capacity = STARTING_SIZE; + s->length = 0; + s->data = malloc(s->capacity); + if (!s->data) + abort(); + + s->data[0] = '\0'; +} + +static void str_ensure_capacity(str *s, size_t extra) { + str_ensure_init(s); + + size_t needed = s->length + extra + 1; // +1 for '\0' + if (needed <= s->capacity) + return; + + while (s->capacity < needed) + s->capacity *= 2; + + char *new_data = realloc(s->data, s->capacity); + if (!new_data) + abort(); + + s->data = new_data; +} + +void free_str(str *s) { + free(s->data); + s->data = NULL; + s->length = 0; + s->capacity = 0; +} + +void str_append(str *s, const char *from) { + str_append_len(s, from, strlen(from)); +} + +void str_append_c(str *s, char c) { str_append_len(s, &c, 1); } + +void str_append_len(str *s, const char *from, size_t len) { + str_ensure_capacity(s, len); + + memcpy(s->data + s->length, from, len); + s->length += len; + s->data[s->length] = '\0'; +} + +void str_append_read(str *s, int fd) { + char buf[READ_CHUNK_SIZE]; + ssize_t n; + + while ((n = read(fd, buf, sizeof(buf))) > 0) { + str_append_len(s, buf, (size_t)n); + } +} + +void str_append_fread(str *s, FILE *file) { + char buf[READ_CHUNK_SIZE]; + size_t n; + + while ((n = fread(buf, 1, sizeof(buf), file)) > 0) { + str_append_len(s, buf, n); + } +} + +void str_append_fread_len(str *s, size_t size, FILE *file) { + char buf[READ_CHUNK_SIZE]; + + while (size > 0) { + size_t chunk = size > sizeof(buf) ? sizeof(buf) : size; + size_t n = fread(buf, 1, chunk, file); + + if (n == 0) + break; + + str_append_len(s, buf, n); + size -= n; + + if (n < chunk) + break; + } +} + +void str_appendf(str *s, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + + va_list copy; + va_copy(copy, args); + int needed = vsnprintf(NULL, 0, fmt, copy); + va_end(copy); + + if (needed < 0) { + va_end(args); + return; + } + + str_ensure_capacity(s, (size_t)needed); + + vsnprintf(s->data + s->length, s->capacity - s->length, fmt, args); + s->length += (size_t)needed; + + va_end(args); +} -- cgit v1.3-7-ge9ab