#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; }