#include "utils.h" #include #include #include result ok(void *value) { return (struct result){.value = value, .errmsg = NULL}; } result err(const char *errmsg) { return (struct result){.value = NULL, .errmsg = errmsg}; } struct allocator { void** bufs; size_t cap; size_t len; }; allocator* new_allocator() { struct allocator * alct = malloc(sizeof(struct allocator)); alct->bufs = malloc(sizeof(void*) * 16); alct->cap = 16; alct->len = 0; alct->bufs[0] = NULL; return alct; } void delete_allocator(allocator* alct) { for (size_t i = 0; i < alct->len; i++) { free(alct->bufs[i]); } free(alct->bufs); free(alct); } void * allocate(allocator* alct, size_t size) { assert(size > 0); if (alct->len >= alct->cap) { alct->cap = alct->cap * 2; // Doubling the capacity alct->bufs = realloc(alct->bufs, sizeof(void*) * alct->cap); } void* ptr = malloc(size); // Allocate requested size alct->bufs[alct->len] = ptr; // Store pointer in array alct->len++; return ptr; } char* safe_sprintf(allocator* alct, const char* format, ...) { va_list args; va_list args_copy; int length; char* buffer; va_start(args, format); va_copy(args_copy, args); length = vsnprintf(NULL, 0, format, args); if (length < 0) { va_end(args); va_end(args_copy); return NULL; } buffer = (char*)allocate(alct, length + 1); if (buffer == NULL) { va_end(args); va_end(args_copy); return NULL; } vsprintf(buffer, format, args_copy); va_end(args); va_end(args_copy); return buffer; }