/* * SPDX-FileCopyrightText: 2025 William Bell * * SPDX-License-Identifier: GPL-3.0-or-later */ #include "err.h" #include "../external/libdye/include/dye.h" #include #include #include #include #include #include #include #include #include #ifdef _WIN32 ssize_t getline(char **lineptr, size_t *n, FILE *stream) { if (lineptr == NULL || n == NULL || stream == NULL) { return -1; } size_t pos = 0; int c; if (*lineptr == NULL || *n == 0) { *n = 128; // initial buffer size *lineptr = malloc(*n); if (*lineptr == NULL) { return -1; } } while ((c = fgetc(stream)) != EOF) { // Resize buffer if needed if (pos + 1 >= *n) { size_t new_size = *n * 2; char *new_ptr = realloc(*lineptr, new_size); if (new_ptr == NULL) { return -1; } *lineptr = new_ptr; *n = new_size; } (*lineptr)[pos++] = (char)c; if (c == '\n') { break; } } if (pos == 0 && c == EOF) { return -1; // EOF and no data read } (*lineptr)[pos] = '\0'; return (ssize_t)pos; } #endif const ArErr no_err = (ArErr){false}; ArErr create_err(int64_t line, int64_t column, int length, char *path, const char *type, const char *fmt, ...) { ArErr err; err.exists = true; err.path = path; err.line = line; err.column = column; err.length = length; // Copy error type safely strncpy(err.type, type, sizeof(err.type) - 1); err.type[sizeof(err.type) - 1] = '\0'; // Format error message va_list args; va_start(args, fmt); vsnprintf(err.message, sizeof(err.message), fmt, args); va_end(args); return err; } void output_err(ArErr err) { if (!err.exists) return; dye(stderr, DYE_WHITE, DYE_RED); fprintf(stderr, "ERROR!"); dye(stderr, DYE_RESET, DYE_RESET); fprintf(stderr, " "); dyefg(stderr, DYE_RED); dye_style(stderr, DYE_STYLE_BOLD); fprintf(stderr, "%s", err.type); dye_style(stderr, DYE_STYLE_RESET); dyefg(stderr, DYE_RESET); fprintf(stderr, ": "); dyefg(stderr, DYE_RED); fprintf(stderr, "%s", err.message); dye_style(stderr, DYE_STYLE_RESET); dyefg(stderr, DYE_RESET); fprintf(stderr, "\n"); if (err.path && err.line) { dyefg(stderr, DYE_GRAY); fprintf(stderr, " --> "); dyefg(stderr, DYE_CYAN); fprintf(stderr, "%s", err.path); dyefg(stderr, DYE_GRAY); fprintf(stderr, ":"); dyefg(stderr, DYE_YELLOW); fprintf(stderr, "%" PRIu64 , err.line); dyefg(stderr, DYE_GRAY); fprintf(stderr, ":"); dyefg(stderr, DYE_YELLOW); fprintf(stderr, "%" PRIu64, err.column); dye_style(stderr, DYE_STYLE_RESET); dyefg(stderr, DYE_RESET); fprintf(stderr, "\n"); FILE *file = fopen(err.path, "r"); if (file) { dye_style(stderr, DYE_STYLE_RESET); dyefg(stderr, DYE_RESET); int line_number_width = snprintf(NULL, 0, "%" PRIu64, err.line); char *buffer = NULL; size_t size = 0; int current_line = 1; ssize_t len; while ((len = getline(&buffer, &size, file)) != -1) { if (current_line == err.line) { break; } current_line++; } fprintf(stderr, " "); for (int i = 0; i < line_number_width; i++) { fprintf(stderr, " "); } fprintf(stderr, "|\n"); for (ssize_t i = 0;i