gwion-util
utilities for the Gwion project
Loading...
Searching...
No Matches
Macros | Functions | Variables
prettyerr.c File Reference
#include <string.h>
#include <ctype.h>
#include <termcolor.h>
#include <prettyerr.h>

Go to the source code of this file.

Macros

#define _PRINTF(...)   tcol_fprintf(printer->stream, __VA_ARGS__)
 
#define _PUTCHR(...)   fputc(__VA_ARGS__, printer->stream)
 

Functions

void perr_printer_init (perr_printer_t *printer, FILE *stream, const char *source, bool utf8, perr_runner_t style)
 
static void perr_print_column (const perr_printer_t *printer, const char *color, const size_t column)
 
static void _perr_print_filename (const perr_printer_t *printer, const perr_t *err, const size_t column)
 
static void _perr_print_error (const perr_printer_t *printer, const perr_t *err, const char *color)
 
void perr_print_line_number (const perr_printer_t *printer, const perr_t *err, const char *color)
 
static void _perr_print_offending_line (const perr_printer_t *printer, const perr_t *err, const char *error_line, const char *color, const size_t column)
 
static void _perr_print_highlight_error (const perr_printer_t *printer, const perr_t *err, const char *error_line, const char *color, const size_t column, const bool small)
 
static void _perr_print_fix (const perr_printer_t *printer, const char *fix)
 
static void lookup_color (char *color, enum libprettyerr_errtype type)
 
static void perr_print_basic_style (const perr_printer_t *printer, const perr_t *err)
 
static void perr_print_secondary_style (const perr_printer_t *printer, const perr_t *err)
 
void perr_print_error (const perr_printer_t *printer, const perr_t *err)
 

Variables

static char const _tcol_lookup [5] = {'G', 'R', 'M', 'B', 'Y'}
 
static char const * _ascii_box_lookup [8] = {"|", "|", "+", "-", "+", "|"}
 
static char const * _utf8_box_lookup [8]
 
static const char * _errtype_lookup [5]
 
perr_runner_t perr_runner_basic_style = perr_print_basic_style
 
perr_runner_t perr_runner_secondary_style = perr_print_secondary_style
 

Macro Definition Documentation

◆ _PRINTF

#define _PRINTF ( ...)    tcol_fprintf(printer->stream, __VA_ARGS__)

Definition at line 29 of file prettyerr.c.

◆ _PUTCHR

#define _PUTCHR ( ...)    fputc(__VA_ARGS__, printer->stream)

Definition at line 30 of file prettyerr.c.

Function Documentation

◆ _perr_print_error()

static void _perr_print_error ( const perr_printer_t * printer,
const perr_t * err,
const char * color )
static

Definition at line 79 of file prettyerr.c.

80 {
81 _PRINTF("%s%s", color, _errtype_lookup[err->type]);
82 if (err->error_code)
83 _PRINTF("[%c%04d]", toupper(_errtype_lookup[err->type][0]),
84 err->error_code);
85 _PRINTF("{0}: ");
86}
static const char * _errtype_lookup[5]
Definition prettyerr.c:39
#define _PRINTF(...)
Definition prettyerr.c:29
enum libprettyerr_errtype type
Definition prettyerr.h:63

◆ _perr_print_filename()

static void _perr_print_filename ( const perr_printer_t * printer,
const perr_t * err,
const size_t column )
inlinestatic

Definition at line 73 of file prettyerr.c.

75 {
76 _PRINTF("{0}{+}%s{0}:%zu:%zu: ", err->filename, err->primary.line, column);
77}
const char * filename
Definition prettyerr.h:72
struct libprettyerr_str primary
Definition prettyerr.h:65

◆ _perr_print_fix()

static void _perr_print_fix ( const perr_printer_t * printer,
const char * fix )
inlinestatic

Definition at line 142 of file prettyerr.c.

143 {
144 _PRINTF("{-}");
145 _PRINTF(fix);
146 _PRINTF("{0}\n");
147}

◆ _perr_print_highlight_error()

static void _perr_print_highlight_error ( const perr_printer_t * printer,
const perr_t * err,
const char * error_line,
const char * color,
const size_t column,
const bool small )
inlinestatic

Definition at line 110 of file prettyerr.c.

115 {
116 perr_print_column(printer, color, 0);
117 char* line = (char*)error_line;
118 size_t i = 0;
119 while(i < column) {
120 if(*line =='\t') _PRINTF("\t");
121 else _PRINTF(" ");
122 i++;
123 line++;
124 }
125 const enum libprettyerr_boxtype type =
126 (!small ? PERR_BOX_THIN_UL : PERR_BOX_THIN_BL) + printer->rounded;
127 if (err->error_position.length > 1) {
128 _PRINTF("%s{-}%s", color, printer->box_lookup[type]);
129 {
130 size_t i;
131 for (i = 1; i < err->error_position.length; i++) {
133 }
134 }
135 } else
136 _PRINTF("%s{-}%s", color, printer->box_lookup[PERR_BOX_THIN_VERT]);
137 _PRINTF("{0}\n");
138}
static void perr_print_column(const perr_printer_t *printer, const char *color, const size_t column)
Definition prettyerr.c:67
libprettyerr_boxtype
Definition prettyerr.h:50
@ PERR_BOX_THIN_VERT
Definition prettyerr.h:58
@ PERR_BOX_THIN_BL
Definition prettyerr.h:56
@ PERR_BOX_THIN_UL
Definition prettyerr.h:53
@ PERR_BOX_THIN_HORIZ
Definition prettyerr.h:55
struct libprettyerr_pos error_position
Definition prettyerr.h:66
const char ** box_lookup
Definition prettyerr.h:94

◆ _perr_print_offending_line()

static void _perr_print_offending_line ( const perr_printer_t * printer,
const perr_t * err,
const char * error_line,
const char * color,
const size_t column )
static

Definition at line 96 of file prettyerr.c.

99 {
100 _PRINTF("%.*s", (int)column, error_line);
101 const char *bug = error_line + column;
102 _PRINTF("%s{-}%.*s{0}", color, (int)err->error_position.length, bug);
103 const char *end = bug + err->error_position.length;
104 char * nl = strstr(end, "\n");
105 ptrdiff_t nl_index = nl ? nl - end : (ptrdiff_t)strlen(end) - 1;
106 _PRINTF("%.*s\n", (int)nl_index, end);
107}

◆ lookup_color()

static void lookup_color ( char * color,
enum libprettyerr_errtype type )
static

Definition at line 149 of file prettyerr.c.

149 {
150 char _color[16];
151 sprintf(_color, "+%c", _tcol_lookup[type]);
152 size_t len;
153 const int status = tcol_color_parse(color, 16, _color, 2, &len);
154 if (status != TermColorErrorNone) {
155 color[0] = 0;
156 // error
157 } else
158 color[len] = 0;
159}
static char const _tcol_lookup[5]
Definition prettyerr.c:32
int tcol_color_parse(char *dst, size_t dstn, char color[16], size_t k, size_t *len)
Definition termcolor.c:142
@ TermColorErrorNone
Definition termcolor.h:39

◆ perr_print_basic_style()

static void perr_print_basic_style ( const perr_printer_t * printer,
const perr_t * err )
inlinestatic

Definition at line 161 of file prettyerr.c.

162 {
163 // Normal errors:
164 //
165 // $filename:$line:$col: $type: $msg
166 // $line | <long line here>
167 // | ^^^^
168
169 // Here we scan backwards until we reach the start of the line (or the
170 // start of the source code). This allows us to retrieve the line that has
171 // the error.
172 size_t idx_cpy = err->error_position.index;
173 while (idx_cpy > 0 && printer->source[idx_cpy - 1] != '\n') { idx_cpy--; }
174 const char *error_line = (printer->source + idx_cpy);
175 error_line += (printer->source[idx_cpy] == '\n') ? 1 : 0;
176
177 // The column is how far the error's index is from the start-of-line's
178 // index.
179 const size_t column = err->error_position.index - idx_cpy;
180
181 char color[17];
182 lookup_color(color, err->type);
183
184 // Here we print the first row of the error message which provides general
185 // information such as filename, line, column, error type and a message.
186 _perr_print_filename(printer, err, column);
187 _perr_print_error(printer, err, color);
188 _PRINTF(err->main);
189 _PUTCHR('\n');
190
191 perr_print_line_number(printer, err, color);
192 _perr_print_offending_line(printer, err, error_line, color, column);
193 _perr_print_highlight_error(printer, err, error_line, color, column, !err->explain);
194
195 // Adds a subsidiary error note, if applicable
196 if (err->explain) {
197 perr_print_column(printer, color, column);
198 _PRINTF("{-}%s%s{0}\n", color, printer->box_lookup[PERR_BOX_THIN_HIGH]);
199 perr_print_column(printer, color, column);
200 _PRINTF(err->explain);
201 _PUTCHR('\n');
202 }
203}
static void _perr_print_highlight_error(const perr_printer_t *printer, const perr_t *err, const char *error_line, const char *color, const size_t column, const bool small)
Definition prettyerr.c:110
static void _perr_print_error(const perr_printer_t *printer, const perr_t *err, const char *color)
Definition prettyerr.c:79
static void _perr_print_filename(const perr_printer_t *printer, const perr_t *err, const size_t column)
Definition prettyerr.c:73
static void _perr_print_offending_line(const perr_printer_t *printer, const perr_t *err, const char *error_line, const char *color, const size_t column)
Definition prettyerr.c:96
static void lookup_color(char *color, enum libprettyerr_errtype type)
Definition prettyerr.c:149
#define _PUTCHR(...)
Definition prettyerr.c:30
void perr_print_line_number(const perr_printer_t *printer, const perr_t *err, const char *color)
Definition prettyerr.c:89
@ PERR_BOX_THIN_HIGH
Definition prettyerr.h:52
const char * main
Definition prettyerr.h:68
const char * explain
Definition prettyerr.h:69
const char * source
Definition prettyerr.h:92

◆ perr_print_column()

static void perr_print_column ( const perr_printer_t * printer,
const char * color,
const size_t column )
static

Definition at line 67 of file prettyerr.c.

68 {
69 _PRINTF(" %s%s{0} %*s", color, printer->box_lookup[PERR_BOX_THICK_VERT],
70 (int)column, "");
71}
@ PERR_BOX_THICK_VERT
Definition prettyerr.h:51

◆ perr_print_error()

void perr_print_error ( const perr_printer_t * printer,
const perr_t * err )

Definition at line 241 of file prettyerr.c.

241 {
242 printer->runner(printer, err);
243}
libprettyerr_runner_t runner
Definition prettyerr.h:95

◆ perr_print_line_number()

void perr_print_line_number ( const perr_printer_t * printer,
const perr_t * err,
const char * color )

Definition at line 89 of file prettyerr.c.

90 {
91 _PRINTF("{-}%5zu{0} %s%s{0} ", err->primary.line, color,
93}

◆ perr_print_secondary_style()

static void perr_print_secondary_style ( const perr_printer_t * printer,
const perr_t * err )
inlinestatic

Definition at line 212 of file prettyerr.c.

213 {
214 size_t idx_cpy = err->error_position.index;
215 while (idx_cpy > 0 && printer->source[idx_cpy - 1] != '\n') { idx_cpy--; }
216 const char *error_line = (printer->source + idx_cpy);
217 error_line += (printer->source[idx_cpy] == '\n') ? 1 : 0;
218
219 // The column is how far the error's index is from the start-of-line's
220 // index.
221 const size_t column = err->error_position.index - idx_cpy;
222
223 char color[17];
224 lookup_color(color, err->type);
225
226 _perr_print_filename(printer, err, column);
227 _PUTCHR('\n');
228
229 perr_print_line_number(printer, err, color);
230 _perr_print_offending_line(printer, err, error_line, color, column);
231 _perr_print_highlight_error(printer, err, error_line, color, column, false);
232
233 perr_print_column(printer, color, column);
234 _PRINTF("{-}%s%s%.*s{0} ", color,
235 printer->box_lookup[PERR_BOX_THIN_BL + printer->rounded], 3,
237 _PRINTF(err->main);
238 _PUTCHR('\n');
239}

◆ perr_printer_init()

void perr_printer_init ( perr_printer_t * printer,
FILE * stream,
const char * source,
bool utf8,
perr_runner_t style )

Definition at line 42 of file prettyerr.c.

43 {
44 printer->source = source;
45 printer->stream = stream;
46
47// Enables ANSI colors only in Unix terminals. False by default on Windows.
48#if defined(__unix__) || defined(__unix) || \
49 (defined(__APPLE__) && defined(__MACH__))
50 const int fd = fileno(stream);
51 // if (fd < 0) {
52 // perror("fileno");
53 // }
54 printer->color = isatty(fd);
55#else
56 printer->color = false;
57#endif
58
59 if ((printer->utf8 = utf8)) {
61 } else {
63 }
64 printer->runner = style;
65}
static char const * _utf8_box_lookup[8]
Definition prettyerr.c:36
static char const * _ascii_box_lookup[8]
Definition prettyerr.c:34

Variable Documentation

◆ _ascii_box_lookup

char const* _ascii_box_lookup[8] = {"|", "|", "+", "-", "+", "|"}
static

Definition at line 34 of file prettyerr.c.

34{"|", "|", "+", "-", "+", "|"};

◆ _errtype_lookup

const char* _errtype_lookup[5]
static
Initial value:
= {"succes", "error", "warning", "info",
"hint"}

Definition at line 39 of file prettyerr.c.

39 {"succes", "error", "warning", "info",
40 "hint"};

◆ _tcol_lookup

char const _tcol_lookup[5] = {'G', 'R', 'M', 'B', 'Y'}
static

Definition at line 32 of file prettyerr.c.

32{'G', 'R', 'M', 'B', 'Y'};

◆ _utf8_box_lookup

char const* _utf8_box_lookup[8]
static
Initial value:
= {"┃", "╵", "┌", "╭",
"─", "└", "╰", "│"}

Definition at line 36 of file prettyerr.c.

36 {"┃", "╵", "┌", "╭",
37 "─", "└", "╰", "│"};

◆ perr_runner_basic_style

perr_runner_t perr_runner_basic_style = perr_print_basic_style

Definition at line 245 of file prettyerr.c.

◆ perr_runner_secondary_style

perr_runner_t perr_runner_secondary_style = perr_print_secondary_style

Definition at line 246 of file prettyerr.c.