Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2016 Andrew Kelley
3 : : *
4 : : * This file is part of zig, which is MIT licensed.
5 : : * See http://opensource.org/licenses/MIT
6 : : */
7 : :
8 : : #include "errmsg.hpp"
9 : : #include "os.hpp"
10 : :
11 : : #include <stdio.h>
12 : :
13 : : enum ErrType {
14 : : ErrTypeError,
15 : : ErrTypeNote,
16 : : };
17 : :
18 : 0 : static void print_err_msg_type(ErrorMsg *err, ErrColor color, ErrType err_type) {
19 : 0 : const char *path = buf_ptr(err->path);
20 : 0 : size_t line = err->line_start + 1;
21 : 0 : size_t col = err->column_start + 1;
22 : 0 : const char *text = buf_ptr(err->msg);
23 : :
24 : 0 : bool is_tty = os_stderr_tty();
25 [ # # ][ # # ]: 0 : if (color == ErrColorOn || (color == ErrColorAuto && is_tty)) {
[ # # ]
26 [ # # ]: 0 : if (err_type == ErrTypeError) {
27 : 0 : os_stderr_set_color(TermColorBold);
28 : 0 : fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col);
29 : 0 : os_stderr_set_color(TermColorRed);
30 : 0 : fprintf(stderr, "error:");
31 : 0 : os_stderr_set_color(TermColorBold);
32 : 0 : fprintf(stderr, " %s", text);
33 : 0 : os_stderr_set_color(TermColorReset);
34 : 0 : fprintf(stderr, "\n");
35 [ # # ]: 0 : } else if (err_type == ErrTypeNote) {
36 : 0 : os_stderr_set_color(TermColorBold);
37 : 0 : fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col);
38 : 0 : os_stderr_set_color(TermColorCyan);
39 : 0 : fprintf(stderr, "note:");
40 : 0 : os_stderr_set_color(TermColorBold);
41 : 0 : fprintf(stderr, " %s", text);
42 : 0 : os_stderr_set_color(TermColorReset);
43 : 0 : fprintf(stderr, "\n");
44 : : } else {
45 : 0 : zig_unreachable();
46 : : }
47 : :
48 : 0 : fprintf(stderr, "%s\n", buf_ptr(&err->line_buf));
49 [ # # ]: 0 : for (size_t i = 0; i < err->column_start; i += 1) {
50 : 0 : fprintf(stderr, " ");
51 : : }
52 : 0 : os_stderr_set_color(TermColorGreen);
53 : 0 : fprintf(stderr, "^");
54 : 0 : os_stderr_set_color(TermColorReset);
55 : 0 : fprintf(stderr, "\n");
56 : : } else {
57 [ # # ]: 0 : if (err_type == ErrTypeError) {
58 : 0 : fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": error: %s\n", path, line, col, text);
59 [ # # ]: 0 : } else if (err_type == ErrTypeNote) {
60 : 0 : fprintf(stderr, " %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": note: %s\n", path, line, col, text);
61 : : } else {
62 : 0 : zig_unreachable();
63 : : }
64 : : }
65 : :
66 [ # # ]: 0 : for (size_t i = 0; i < err->notes.length; i += 1) {
67 : 0 : ErrorMsg *note = err->notes.at(i);
68 : 0 : print_err_msg_type(note, color, ErrTypeNote);
69 : : }
70 : 0 : }
71 : :
72 : 0 : void print_err_msg(ErrorMsg *err, ErrColor color) {
73 : 0 : print_err_msg_type(err, color, ErrTypeError);
74 : 0 : }
75 : :
76 : 0 : void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note) {
77 : 0 : parent->notes.append(note);
78 : 0 : }
79 : :
80 : 0 : ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size_t offset,
81 : : const char *source, Buf *msg)
82 : : {
83 : 0 : ErrorMsg *err_msg = allocate<ErrorMsg>(1);
84 : 0 : err_msg->path = path;
85 : 0 : err_msg->line_start = line;
86 : 0 : err_msg->column_start = column;
87 : 0 : err_msg->msg = msg;
88 : :
89 : 0 : size_t line_start_offset = offset;
90 : : for (;;) {
91 [ # # ]: 0 : if (line_start_offset == 0) {
92 : 0 : break;
93 : : }
94 : :
95 : 0 : line_start_offset -= 1;
96 : :
97 [ # # ]: 0 : if (source[line_start_offset] == '\n') {
98 : 0 : line_start_offset += 1;
99 : 0 : break;
100 : : }
101 : : }
102 : :
103 : 0 : size_t line_end_offset = offset;
104 [ # # ][ # # ]: 0 : while (source[line_end_offset] && source[line_end_offset] != '\n') {
105 : 0 : line_end_offset += 1;
106 : : }
107 : :
108 : 0 : buf_init_from_mem(&err_msg->line_buf, source + line_start_offset, line_end_offset - line_start_offset);
109 : :
110 : 0 : return err_msg;
111 : : }
112 : :
113 : 0 : ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,
114 : : Buf *source, ZigList<size_t> *line_offsets, Buf *msg)
115 : : {
116 : 0 : ErrorMsg *err_msg = allocate<ErrorMsg>(1);
117 : 0 : err_msg->path = path;
118 : 0 : err_msg->line_start = line;
119 : 0 : err_msg->column_start = column;
120 : 0 : err_msg->msg = msg;
121 : :
122 : 0 : size_t line_start_offset = line_offsets->at(line);
123 : 0 : size_t end_line = line + 1;
124 [ # # ]: 0 : size_t line_end_offset = (end_line >= line_offsets->length) ? buf_len(source) : line_offsets->at(line + 1);
125 [ # # ]: 0 : size_t len = (line_end_offset + 1 > line_start_offset) ? (line_end_offset - line_start_offset - 1) : 0;
126 [ # # ]: 0 : if (len == SIZE_MAX) len = 0;
127 : :
128 : 0 : buf_init_from_mem(&err_msg->line_buf, buf_ptr(source) + line_start_offset, len);
129 : :
130 : 0 : return err_msg;
131 : : }
|