#include "util.h" #include #include #include #include #include #include void* realloc_safe(void* oldptr, size_t size) { static const char OOM_MSG[] = "fatal: out of memory\n"; void* ptr = realloc(oldptr, size); if (size && !ptr) { fwrite(OOM_MSG, 1, sizeof(OOM_MSG) - 1, stderr); abort(); } return ptr; } void* malloc_safe(size_t size) { return realloc_safe(NULL, size); } // asprintf is not POSIX int alloc_sprintf(char* restrict* restrict out, const char* restrict fmt, ...) { va_list args; va_start(args, fmt); va_list args2; va_copy(args2, args); int need = vsnprintf(NULL, 0, fmt, args2); va_end(args2); *out = realloc_safe(*out, need + 1); int written = vsnprintf(*out, need + 1, fmt, args); va_end(args); return written; } void log_error(const char* restrict fmt, ...) { time_t cur_time = time(NULL); struct tm tm; localtime_r(&cur_time, &tm); char time_str[32]; strftime(time_str, sizeof(time_str), "%c", &tm); fprintf(stderr, "[%s] error: ", time_str); va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fputc('\n', stderr); } void log_errno(const char* detail) { log_error("%s: %s", detail, strerror(errno)); }