#include #include #include #include #define NR_NAMES 6 #define ERROR_CLASS(id, title) \ [id] = {.c_type = IVY_DIAG_ERROR, .c_title = (title)} #define MSG(id, content) [id] = {.msg_content = (content)} enum { E_NONE = 0, E_UNRECOGNISED_SYMBOL, }; enum { MSG_NONE, MSG_SYMBOL_NOT_RECOGNISED, MSG_CORRECTION_1, MSG_EXAMPLE_2, }; static const char *fake_file_content[] = { "var x = 32.\n", "var y = 64.\n", "var z = x $ y.\n", }; static const size_t fake_file_lines = sizeof fake_file_content / sizeof fake_file_content[0]; static enum ivy_status get_name( struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read) { *nr_read = snprintf(buf, count, "SAMPLE"); return IVY_OK; } static enum ivy_status get_row( struct ivy_line_source *src, size_t row, char *buf, size_t count, size_t *nr_read) { if (row > fake_file_lines) { return IVY_ERR_EOF; } const char *line = fake_file_content[row - 1]; size_t len = strlen(line); if (len > count) { len = count; } memcpy(buf, line, len); buf[len - 1] = 0; *nr_read = len - 1; return IVY_OK; } static struct ivy_line_source source_file = { .s_get_name = get_name, .s_get_row = get_row, }; static const struct ivy_diag_class diag_classes[] = { ERROR_CLASS(E_UNRECOGNISED_SYMBOL, "Unrecognised symbol"), }; static const size_t nr_diag_classes = sizeof diag_classes / sizeof diag_classes[0]; static const struct ivy_diag_msg diag_msg[] = { MSG(MSG_SYMBOL_NOT_RECOGNISED, "encountered a symbol that is not part of the Ivy syntax."), MSG(MSG_CORRECTION_1, "perhaps you meant to use an arithmetic operator instead?"), MSG(MSG_EXAMPLE_2, "an example diagnostic message."), }; static const size_t nr_diag_msg = sizeof diag_msg / sizeof diag_msg[0]; int main(void) { struct ivy_diag_ctx *ctx; if (ivy_diag_ctx_create(&ctx) != IVY_OK) { return -1; } ivy_diag_ctx_set_line_source(ctx, &source_file); ivy_diag_ctx_set_class_definitions(ctx, diag_classes, nr_diag_classes); ivy_diag_ctx_set_msg_definitions(ctx, diag_msg, nr_diag_msg); const struct ivy_diag_highlight hl[] = { IVY_DIAG_HL(ERROR, 3, 11, 3, 11), }; const struct ivy_diag_highlight hl2[] = { IVY_DIAG_HL(HINT, 3, 11, 3, 11), }; const struct ivy_diag_amendment amend[] = { IVY_DIAG_REPLACE(3, 11, 1, "+"), }; struct ivy_diag *diag = ivy_diag_ctx_create_diag(ctx, E_UNRECOGNISED_SYMBOL); ivy_diag_set_location(diag, 3, 11); ivy_diag_push_msg(diag, MSG_SYMBOL_NOT_RECOGNISED); ivy_diag_push_snippet( diag, 1, 3, amend, sizeof amend / sizeof amend[0], hl, sizeof hl / sizeof hl[0]); ivy_diag_push_msg(diag, MSG_CORRECTION_1); ivy_diag_push_snippet( diag, 1, 3, amend, sizeof amend / sizeof amend[0], hl2, sizeof hl2 / sizeof hl2[0]); ivy_diag_push_msg(diag, MSG_EXAMPLE_2); struct ivy_diag_stream stream; ivy_diag_stream_init_tty(&stream, b_stdtty); ivy_diag_ctx_write(ctx, IVY_DIAG_FORMAT_PRETTY, &stream); #if 0 b_printf( "[cyan]--- UNRECOGNISED SYMBOL " "-------------------------" "--------------------------[reset]\n"); b_printf(" [cyan]> src/std/io/StreamReader.im[reset]:8:11\n\n"); b_printf( " encountered a symbol that is not part of the Ivy " "syntax.\n\n"); b_printf(" [cyan]6 |[reset] var x = 32.\n"); b_printf(" [cyan]7 |[reset] var y = 64.\n"); b_printf(" [cyan]8 |[reset] var z = x [red]$[reset] y.\n"); b_printf(" [red]^[reset]\n\n"); b_printf("\n\n"); b_printf( "[red,bold]error[[E0102][reset]: [bold]encountered an " "unrecognised symbol[reset]\n"); b_printf(" [blue,bold]-->[reset] src/std/io/StreamReader.im\n"); b_printf(" [blue,bold] |[reset]\n"); b_printf(" [blue,bold]6 |[reset] var x = 32.\n"); b_printf(" [blue,bold]7 |[reset] var y = 64.\n"); b_printf(" [blue,bold]8 |[reset] var z = x [red,bold]$[reset] y.\n"); b_printf(" [blue,bold] |[reset] [red,bold]^[reset]\n"); b_printf("\n\n"); b_printf(" [red,bold]\u2A2F[reset] unrecognised symbol\n"); b_printf(" [cyan,bold]>[reset] src/std/io/StreamReader.im\n"); b_printf(" \u256D\u2500\u2500\u2500\n"); b_printf(" [dark_grey]0[reset] \u2502 var x = 2 $ 3.\n"); b_printf(" \u00B7 [green]\u252C[reset]\n"); b_printf( " \u00B7 [green]\u2570\u2500\u2500 this symbol is " "not " "used in Ivy syntax.[reset]\n"); b_printf(" \u2570\u2500\u2500\u2500\n"); #endif return 0; }