#include #include #include #include "source.h" void source_init(struct source *src, str name, str contents) { src->name = name; src->offset = 0; src->contents = contents; src->strings.len = src->strings.cap = 0; src->strings.ptr = nullptr; } void source_error(struct source *src, struct range loc, const char *fmt, ...) { char *p_start = src->contents.ptr + loc.start; char *p_end = src->contents.ptr + loc.end; unsigned int lineno = 0; str iter = src->contents; str line; do { line = str_walk(&iter, S("\n")); lineno++; } while (line.ptr + line.len <= p_start); fprintf(stderr, "parse error in %.*s:%u: ", PSTR(src->name), lineno); va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr, "\n"); while (line.ptr && line.ptr < p_end) { fprintf(stderr, " %4u: %.*s\n", lineno, PSTR(line)); fprintf(stderr, " "); for (size_t i = 0; i < line.len+1; i++) { char *p = line.ptr + i; fprintf(stderr, "%c", p >= p_start && p < p_end ? '^' : ' '); } fprintf(stderr, "\n"); line = str_walk(&iter, S("\n")); lineno++; } exit(EXIT_FAILURE); } void source_free(struct source *src) { free(src->contents.ptr); for (size_t i = 0; i < src->strings.len; i++) free(src->strings.ptr[i].ptr); free(src->strings.ptr); }