#include #include #include #include "messages.h" #include "location.h" /* SGI sequence */ #define ANSI_C(c) "\x1b["c"m" /* 8bit palette color */ #define ANSI_8C(c) "\x1b[38;5;"c"m" #define ANSI_8CB(c) "\x1b[48;5;"c"m" /* True color */ #define ANSI_RC(r,g,b) "\x1b[38;2;"r";"g";"b"m" #define ANSI_RCB(r,g,b) "\x1b[48;2;"r";"g";"b"m" #define ANSI_RESET "\x1b[0m" #define ANSI_BOLD "\x1b[1m" #define ANSI_IF(cond, seq) (cond ? (seq) : "") #define make_diag_func(name, diagtype, after) \ void name(Compiler *cm, const Location *loc, const char *s, ...) { \ va_list args; \ va_start(args, s); \ print_diagnostic(cm, loc, diagtype, s, args); \ va_end(args); \ after; \ } void print_diagnostic(Compiler *cm, const Location *loc, DiagType dt, const char *msg, va_list args) { static const char *ds[] = {"fatal", "error", "warning", "note"}; static const char *dsc[] = { ANSI_C("1;90"), ANSI_C("1;31"), ANSI_C("1;35"), ANSI_C("1;34") }; char fmsg[4096] = {0}; char dmsg[32] = {0}; bool color = cm != nil ? cm->opts.color : false; if (dt == diag_error && cm->error_count < cm->opts.max_errors) ++cm->error_count; vsnprintf(fmsg, sizeof(fmsg), msg, args); snprintf(dmsg, sizeof(dmsg), "%s%s:%s", ANSI_IF(color, dsc[dt]), ds[dt], ANSI_IF(color, ANSI_RESET)); if (loc != nil) { fprintf(stderr, "(%s:%li:%li) %s %s\n", loc->source.s, loc->line, loc->column, dmsg, fmsg); } else { fprintf(stderr, "%s %s\n", dmsg, fmsg); } } make_diag_func(fatal, diag_fatal, exit(EXIT_FAILURE)) make_diag_func(error, diag_error, ) make_diag_func(warning, diag_warning, ) make_diag_func(note, diag_note, )