diff options
Diffstat (limited to 'src/log.c')
-rw-r--r-- | src/log.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..efcf9db --- /dev/null +++ b/src/log.c @@ -0,0 +1,77 @@ +#include <log.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +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); +} |