103 lines
2.3 KiB
C
103 lines
2.3 KiB
C
#include "../include/mrc_diagnostic.h"
|
|
|
|
static void
|
|
line_and_column_by_start_and_offset(const uint8_t *source_start, const uint8_t *location_start, uint32_t *line, uint32_t *column)
|
|
{
|
|
if (!location_start) {
|
|
*line = 0;
|
|
*column = 0;
|
|
return;
|
|
}
|
|
uint32_t start_offset = (uint32_t)(location_start - source_start);
|
|
uint32_t l = 1, c = 1;
|
|
const uint8_t *p = source_start;
|
|
while (p < source_start + start_offset) {
|
|
if (*p == '\n') {
|
|
l++;
|
|
c = 1;
|
|
} else {
|
|
c++;
|
|
}
|
|
p++;
|
|
}
|
|
*line = l;
|
|
*column = c;
|
|
}
|
|
|
|
/*
|
|
const char *level;
|
|
switch (diagnostic->level) {
|
|
case PM_ERROR_LEVEL_SYNTAX:
|
|
level = "syntax";
|
|
break;
|
|
case PM_ERROR_LEVEL_ARGUMENT:
|
|
level = "argument";
|
|
break;
|
|
case PM_ERROR_LEVEL_LOAD:
|
|
level = "load";
|
|
break;
|
|
default:
|
|
abort();
|
|
}
|
|
*/
|
|
|
|
const char *
|
|
mrc_diagnostic_code_to_string(mrc_diagnostic_code code)
|
|
{
|
|
switch (code) {
|
|
case MRC_PARSER_ERROR:
|
|
return "syntax error";
|
|
case MRC_GENERATOR_ERROR:
|
|
return "generator error";
|
|
case MRC_PARSER_WARNING:
|
|
return "syntax warning";
|
|
case MRC_GENERATOR_WARNING:
|
|
return "generator warning";
|
|
default:
|
|
return "unknown";
|
|
}
|
|
}
|
|
|
|
void
|
|
mrc_diagnostic_list_append(mrc_ccontext *c, const uint8_t * location_start, const char *message, mrc_diagnostic_code code)
|
|
{
|
|
mrc_diagnostic_list *list = mrc_calloc(c, 1, sizeof(mrc_diagnostic_list));
|
|
line_and_column_by_start_and_offset(c->p->start, location_start, &list->line, &list->column);
|
|
char buf[256];
|
|
const char *diagnostic_code_str = mrc_diagnostic_code_to_string(code);
|
|
snprintf(buf, sizeof(buf), "%s, %s", diagnostic_code_str, message);
|
|
size_t len = strlen(buf);
|
|
list->message = (char *)mrc_malloc(c, len + 1);
|
|
strcpy(list->message, buf);
|
|
list->message[len] = '\0';
|
|
list->code = code;
|
|
|
|
if (c->diagnostic_list == NULL) {
|
|
c->diagnostic_list = list;
|
|
} else {
|
|
mrc_diagnostic_list *p = c->diagnostic_list;
|
|
while (p->next) {
|
|
p = p->next;
|
|
}
|
|
p->next = list;
|
|
}
|
|
|
|
if (code == MRC_PARSER_ERROR || code == MRC_GENERATOR_ERROR) {
|
|
c->capture_errors = TRUE;
|
|
}
|
|
}
|
|
|
|
void
|
|
mrc_diagnostic_list_free(mrc_ccontext *c)
|
|
{
|
|
mrc_diagnostic_list *p = c->diagnostic_list;
|
|
while (p) {
|
|
mrc_diagnostic_list *next = p->next;
|
|
mrc_free(c, p->message);
|
|
mrc_free(c, p);
|
|
p = next;
|
|
}
|
|
c->diagnostic_list = NULL;
|
|
}
|
|
|