diff options
| author | 2022-08-03 20:24:47 +0200 | |
|---|---|---|
| committer | 2022-08-03 20:24:47 +0200 | |
| commit | 1625c50f0c0e4b1c7ba01a5df5713efaf6dce606 (patch) | |
| tree | bc5f24811413749b776964c1bbdec13a46dd9768 /bootstrap/util.c | |
initial
Diffstat (limited to 'bootstrap/util.c')
| -rw-r--r-- | bootstrap/util.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/bootstrap/util.c b/bootstrap/util.c new file mode 100644 index 0000000..4aebbe6 --- /dev/null +++ b/bootstrap/util.c @@ -0,0 +1,105 @@ +#include "all.h" + +// Bob Jenkins's one_at_a_time hash +u32 +jkhash(u32 h, const u8 *data, size_t length) { + size_t i = 0; + while (i != length) { + h += data[i++]; + h += h << 10; + h ^= h >> 6; + } + h += h << 3; + h ^= h >> 11; + h += h << 15; + return h; +} + +static const char *filepaths[100]; +static int nfilepaths = 0; + +int addfilepath(const char *s) { + for (int i = 0; i < nfilepaths; ++i) + if (!strcmp(filepaths[i], s)) + return i; + + assert(nfilepaths < sizeof filepaths); + filepaths[nfilepaths] = s; + return nfilepaths++; +} + +const char *fileid2path(int id) { + assert(id < nfilepaths); + return filepaths[id]; +} + +void * +xmalloc(size_t n) { + void *p = malloc(n); + assert(p && "malloc"); + return p; +} + +void * +xcalloc(size_t n, size_t m) { + void *p = calloc(n,m); + assert(p && "calloc"); + return p; +} + +void * +xrealloc(void *p, size_t n) { + if (!p) + return xmalloc(n); + if (!n) + return free(p), NULL; + p = realloc(p, n); + assert(p && "realloc"); + return p; +} + +char * +xasprintf(const char *fmt, ...) { + va_list ap, aq; + int n = 32, m; + char *str = xcalloc(n, 1); + va_start(ap, fmt); + m = vsnprintf(str, n, fmt, ap) + 1; + if (m > n) { + va_copy(aq, ap); + str = xrealloc(str, m); + vsprintf(str, fmt, ap); + va_end(aq); + } + va_end(ap); + return str; +} + +char * +xstrdup(const char *s) { + return strcpy(xmalloc(strlen(s) + 1), s); +} + + +void noreturn +fatal(struct parser *P, struct span span, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int i = 0; + + fprintf(stderr, "%s:%d:%d: error: ", fileid2path(span.fileid), span.line, span.col); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + for (struct expan *ep = P->curexpan; ep; ep = ep->prev, ++i) { + if (ep->name && (i < 8 || !ep->prev || !ep->prev->prev)) { + span = ep->span; + fprintf(stderr, " while expanding macro `%s' at %s:%d:%d\n", + ep->name, + fileid2path(ep->span.fileid), span.line, span.col); + } else if (ep->name && i == 10) { + fprintf(stderr, " ... (some expansions omitted)\n"); + } + } + va_end(ap); + exit(127); +} |