#include #include #include #include static void context_print(FILE *fd, struct ctx *ctx) { const char *data = ctx->data ? ctx->data : ctx->raw; // Find line, column size_t line = 0, column = 0, index = 0; for (; index < ctx->size; index++) { char cur = data[index]; column++; if (line == ctx->line && column == ctx->column) break; if (cur == '\n') { line++; column = 0; continue; } else if (cur == '\0') { fprintf(stderr, "Invalid context!"); context_destroy(ctx); exit(1); break; } } if (++index >= ctx->size) return; // Couldn't find context, idc? fprintf(fd, "\x1B[1;36m%s:%ld:%ld:\x1B[0m '", ctx->path, ctx->line + 1, ctx->column + 1); // Print line context size_t start = ctx->column > 5 ? index - 5 : index; size_t end = ctx->size - index > 5 ? index + 5 : index + 1; for (size_t i = start; i < end; i++) { if (i == index) { fprintf(fd, "\x1B[1;32m%c\x1B[0m", data[i]); } else { fprintf(fd, "%c", data[i]); } } fprintf(fd, "': "); } void errln(struct ctx *ctx, const char *fmt, ...) { context_print(stderr, ctx); fprintf(stderr, "\x1B[1;31m"); va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); fprintf(stderr, "\x1B[0m"); context_destroy(ctx); exit(1); } void err(const char *fmt, ...) { fprintf(stderr, "\x1B[1;31m"); va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); fprintf(stderr, "\x1B[0m"); exit(1); }