#include "util.h" void* checkp(void *p) { if (!p) die("pointer assertion failed, OOM?\n"); return p; } void* die(const char *fmtstr, ...) { va_list ap; va_start(ap, fmtstr); vfprintf(stderr, fmtstr, ap); va_end(ap); exit(EXIT_FAILURE); } char* aprintf(const char *fmtstr, ...) { va_list ap, cpy; size_t nb; char *str; va_copy(cpy, ap); va_start(cpy, fmtstr); nb = vsnprintf(NULL, 0, fmtstr, cpy); va_end(cpy); if (nb <= 0) die("Invalid fmtstr!\n"); str = checkp(malloc(nb+1)); va_start(ap, fmtstr); nb = vsnprintf(str, nb+1, fmtstr, ap); va_end(ap); return str; } const char* mhash(const char *filename, int len) { static const char *hexalph = "0123456789ABCDEF"; static char buf[2 * MHASHLEN + 1]; int i, k; if (len == -1) len = strlen(filename); for (i = 0; i < MIN(MHASHLEN, len); i++) { unsigned char v = 0; for (k = i; k < len; k += MHASHLEN) v ^= filename[k]; buf[i*2+0] = hexalph[(v >> 4) & 0x0f]; buf[i*2+1] = hexalph[(v >> 0) & 0x0f]; } if (i == 0) { memset(buf, '0', MHASHLEN); } else if (i < MHASHLEN) { for (k = 0; k < MHASHLEN; k++) buf[k] = buf[k % i]; } buf[MHASHLEN] = '\0'; return buf; } void freadstr(FILE *f, char **dst) { size_t start, len; char c; start = ftell(f); for (len = 0; (c = fgetc(f)) != EOF && c; len++); fseek(f, start, SEEK_SET); *dst = checkp(calloc(1, len + 1)); fread(*dst, len, 1, f); fgetc(f); } void fputstr(FILE *f, char *s) { fprintf(f, "%s", s); fputc(0, f); } const char* ask(const char *fmtstr, ...) { static char linebuf[256]; va_list ap; int fail; va_start(ap, fmtstr); vprintf(fmtstr, ap); va_end(ap); fail = !fgets(linebuf, sizeof(linebuf), stdin); if (!fail) linebuf[strlen(linebuf) - 1] = '\0'; return fail ? "" : linebuf; } void dump(const char *filename) { char buf[256]; FILE *f; int nb; if (!(f = fopen(filename, "r"))) return; while ((nb = fread(buf, 1, sizeof(buf), f))) printf("%.*s\n", nb, buf); fclose(f); } int strpfcmp(const char *prefix, const char *str) { return strncmp(prefix, str, strlen(prefix)); }