#include "util.h" #include "aoc.h" #include #include #include void die(const char *fmtstr, ...) { va_list ap; va_start(ap, fmtstr); fprintf(stderr, "\n"); vfprintf(stderr, fmtstr, ap); fprintf(stderr, "\n"); va_end(ap); abort(); } bool readtok(char *buf, size_t buflen, char sep, const char **pos, const char *end) { const char *c; size_t len; if (*pos >= end) return false; len = 0; for (c = *pos; c != end && *c != sep; c++) { if (len == buflen) die("util: readline: no space"); buf[len++] = *c; } if (len == buflen) die("util: readline: no space"); buf[len++] = '\0'; *pos = c + 1; return true; } int64_t parsei64(const char *str) { int64_t val; char *end; val = strtoll(str, &end, 0); if (end && *end && !isspace(*end)) die("util: parsei64: invalid %s", str); return val; } char * aprintf(const char *fmtstr, ...) { va_list ap, cpy; ssize_t nb; char *str; va_copy(cpy, ap); va_start(cpy, fmtstr); nb = vsnprintf(NULL, 0, fmtstr, cpy); if (nb < 0) die("util: aprintf: invalid fmtstr: %s", fmtstr); va_end(cpy); str = malloc((size_t) nb + 1); if (!str) die("util: aprintf: malloc %lu", nb + 1); va_start(ap, fmtstr); nb = vsnprintf(str, (size_t) nb + 1, fmtstr, ap); va_end(ap); return str; } char * strdup(const char *str) { char *alloc; alloc = malloc(strlen(str) + 1); strcpy(alloc, str); return alloc; } char * apprintf(char *str, const char *fmtstr, ...) { va_list ap, cpy; ssize_t nb; size_t len; len = str ? strlen(str) : 0; va_copy(cpy, ap); va_start(cpy, fmtstr); nb = vsnprintf(NULL, 0, fmtstr, cpy); if (nb < 0) die("util: aprintf: invalid fmtstr: %s", fmtstr); va_end(cpy); str = realloc(str, len + (size_t) nb + 1); if (!str) die("util: aprintf: realloc %lu", nb + 1); va_start(ap, fmtstr); nb = vsnprintf(str + len, (size_t) nb + 1, fmtstr, ap); va_end(ap); return str; } void * memdup(const void *data, size_t size) { void *new; new = malloc(size); if (!new) die("util: memdup: malloc %lu", size); memcpy(new, data, size); return new; } void readall(FILE *file, void **data, size_t *size) { ssize_t pos; fseek(file, 0, SEEK_END); pos = ftell(file); if (pos < 0) die("util: readall: ftell"); *size = (size_t) pos; fseek(file, 0, SEEK_SET); *data = malloc(*size); if (!*data) die("util: readall: malloc %lu", *size); if (fread(*data, 1, *size, file) != *size) die("util: readall: incomplete"); }