From c035571d85e3d756804519d82de8b354f3910b29 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Thu, 8 Feb 2024 21:19:38 +0200 Subject: project work phase 1 --- src/debug.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/debug.c (limited to 'src/debug.c') diff --git a/src/debug.c b/src/debug.c new file mode 100644 index 0000000..c146719 --- /dev/null +++ b/src/debug.c @@ -0,0 +1,81 @@ +#include +#include + +#include + +/** + * Find position in file buffer where line number \p no + * starts. Lines are assumed to be one-indexed, with + * \p no = \c 0 and \p no = \c 1 both considered the first line. + * + * @param buf Buffer to look in. + * @param no Line number whose start to look for. + * @return Pointer to location in buffer where line number \p no + * starts. + */ +static const char *find_lineno(const char *buf, size_t no) +{ + if (no == 0 || no == 1) + return buf; + + char c; + while ((c = *buf)) { + buf++; + + if (c == '\n') + no--; + + if (no == 1) + break; + } + + return buf; +} + +void vsrc_issue(struct src_issue issue, const char *msg, va_list args) +{ + const char *line_start = find_lineno(issue.buf, issue.loc.first_line); + const char *line_end = strchr(line_start, '\n'); + if (!line_end) + line_end = strchr(line_start, 0); + + int line_len = line_end - line_start; + + fprintf(stderr, "%s:%i:%i: ", issue.fname, + issue.loc.first_line, + issue.loc.first_col); + + vfprintf(stderr, msg, args); + fputc('\n', stderr); + + int lineno_len = snprintf(NULL, 0, "%i", issue.loc.first_line); + fputc(' ', stderr); + fprintf(stderr, "%i | ", issue.loc.first_line); + + fprintf(stderr, "%.*s\n", line_len, line_start); + + for (int i = 0; i < lineno_len + 2; ++i) + fputc(' ', stderr); + + fprintf(stderr, "| "); + + for (int i = 0; i < issue.loc.first_col - 1; ++i) + fputc(line_start[i] == '\t' ? '\t' : ' ', stderr); + + for (int i = issue.loc.first_col; i < issue.loc.last_col; ++i) { + if (i == issue.loc.first_col) + fputc('^', stderr); + else + fputc('~', stderr); + } + + fputc('\n', stderr); +} + +void src_issue(struct src_issue issue, const char *msg, ...) +{ + va_list args; + va_start(args, msg); + vsrc_issue(issue, msg, args); + va_end(args); +} -- cgit v1.2.3