58 lines
1.7 KiB
C
58 lines
1.7 KiB
C
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
|
|
#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, )
|