herb 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/{LICENSE → LICENSE.txt} +4 -3
- data/Makefile +121 -0
- data/README.md +102 -107
- data/Rakefile +184 -0
- data/exe/herb +5 -0
- data/ext/herb/error_helpers.c +302 -0
- data/ext/herb/error_helpers.h +15 -0
- data/ext/herb/extconf.rb +75 -0
- data/ext/herb/extension.c +110 -0
- data/ext/herb/extension.h +6 -0
- data/ext/herb/extension_helpers.c +117 -0
- data/ext/herb/extension_helpers.h +24 -0
- data/ext/herb/nodes.c +936 -0
- data/ext/herb/nodes.h +12 -0
- data/herb.gemspec +49 -0
- data/lib/herb/ast/node.rb +61 -0
- data/lib/herb/ast/nodes.rb +1542 -0
- data/lib/herb/ast.rb +6 -0
- data/lib/herb/cli.rb +164 -0
- data/lib/herb/errors.rb +352 -0
- data/lib/herb/lex_result.rb +20 -0
- data/lib/herb/libherb/array.rb +48 -0
- data/lib/herb/libherb/ast_node.rb +47 -0
- data/lib/herb/libherb/buffer.rb +53 -0
- data/lib/herb/libherb/extract_result.rb +17 -0
- data/lib/herb/libherb/lex_result.rb +29 -0
- data/lib/herb/libherb/libherb.rb +49 -0
- data/lib/herb/libherb/parse_result.rb +17 -0
- data/lib/herb/libherb/token.rb +43 -0
- data/lib/herb/libherb.rb +32 -0
- data/lib/herb/location.rb +42 -0
- data/lib/herb/parse_result.rb +26 -0
- data/lib/herb/position.rb +36 -0
- data/lib/herb/project.rb +361 -0
- data/lib/herb/range.rb +40 -0
- data/lib/herb/result.rb +21 -0
- data/lib/herb/token.rb +43 -0
- data/lib/herb/token_list.rb +11 -0
- data/lib/herb/version.rb +5 -0
- data/lib/herb.rb +21 -68
- data/src/analyze.c +989 -0
- data/src/analyze_helpers.c +241 -0
- data/src/analyzed_ruby.c +35 -0
- data/src/array.c +137 -0
- data/src/ast_node.c +81 -0
- data/src/ast_nodes.c +866 -0
- data/src/ast_pretty_print.c +588 -0
- data/src/buffer.c +199 -0
- data/src/errors.c +740 -0
- data/src/extract.c +110 -0
- data/src/herb.c +103 -0
- data/src/html_util.c +143 -0
- data/src/include/analyze.h +36 -0
- data/src/include/analyze_helpers.h +43 -0
- data/src/include/analyzed_ruby.h +33 -0
- data/src/include/array.h +33 -0
- data/src/include/ast_node.h +35 -0
- data/src/include/ast_nodes.h +303 -0
- data/src/include/ast_pretty_print.h +17 -0
- data/src/include/buffer.h +36 -0
- data/src/include/errors.h +125 -0
- data/src/include/extract.h +20 -0
- data/src/include/herb.h +32 -0
- data/src/include/html_util.h +13 -0
- data/src/include/io.h +9 -0
- data/src/include/json.h +28 -0
- data/src/include/lexer.h +13 -0
- data/src/include/lexer_peek_helpers.h +23 -0
- data/src/include/lexer_struct.h +32 -0
- data/src/include/location.h +25 -0
- data/src/include/macros.h +10 -0
- data/src/include/memory.h +12 -0
- data/src/include/parser.h +22 -0
- data/src/include/parser_helpers.h +33 -0
- data/src/include/position.h +22 -0
- data/src/include/pretty_print.h +53 -0
- data/src/include/prism_helpers.h +18 -0
- data/src/include/range.h +23 -0
- data/src/include/ruby_parser.h +6 -0
- data/src/include/token.h +25 -0
- data/src/include/token_matchers.h +21 -0
- data/src/include/token_struct.h +51 -0
- data/src/include/util.h +25 -0
- data/src/include/version.h +6 -0
- data/src/include/visitor.h +11 -0
- data/src/io.c +30 -0
- data/src/json.c +205 -0
- data/src/lexer.c +284 -0
- data/src/lexer_peek_helpers.c +59 -0
- data/src/location.c +41 -0
- data/src/main.c +162 -0
- data/src/memory.c +53 -0
- data/src/parser.c +704 -0
- data/src/parser_helpers.c +161 -0
- data/src/position.c +33 -0
- data/src/pretty_print.c +242 -0
- data/src/prism_helpers.c +50 -0
- data/src/range.c +38 -0
- data/src/ruby_parser.c +47 -0
- data/src/token.c +194 -0
- data/src/token_matchers.c +32 -0
- data/src/util.c +128 -0
- data/src/visitor.c +321 -0
- metadata +126 -82
- data/test/helper.rb +0 -7
- data/test/helpers_test.rb +0 -25
- data/test/parsing_test.rb +0 -110
data/src/errors.c
ADDED
@@ -0,0 +1,740 @@
|
|
1
|
+
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/src/errors.c.erb
|
3
|
+
|
4
|
+
#include "include/array.h"
|
5
|
+
#include "include/errors.h"
|
6
|
+
#include "include/location.h"
|
7
|
+
#include "include/position.h"
|
8
|
+
#include "include/pretty_print.h"
|
9
|
+
#include "include/token.h"
|
10
|
+
#include "include/util.h"
|
11
|
+
|
12
|
+
#include <stdio.h>
|
13
|
+
#include <stdbool.h>
|
14
|
+
#include <stdlib.h>
|
15
|
+
#include <string.h>
|
16
|
+
|
17
|
+
#define ERROR_MESSAGES_TRUNCATED_LENGTH 128
|
18
|
+
|
19
|
+
size_t error_sizeof(void) {
|
20
|
+
return sizeof(struct ERROR_STRUCT);
|
21
|
+
}
|
22
|
+
|
23
|
+
void error_init(ERROR_T* error, const error_type_T type, position_T* start, position_T* end) {
|
24
|
+
if (!error) { return; }
|
25
|
+
|
26
|
+
error->type = type;
|
27
|
+
error->location = location_init(position_copy(start), position_copy(end));
|
28
|
+
}
|
29
|
+
|
30
|
+
UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T* start, position_T* end) {
|
31
|
+
UNEXPECTED_ERROR_T* unexpected_error = malloc(sizeof(UNEXPECTED_ERROR_T));
|
32
|
+
|
33
|
+
error_init(&unexpected_error->base, UNEXPECTED_ERROR, start, end);
|
34
|
+
|
35
|
+
const char* message_template = "%s. Expected: `%s`, found: `%s`.";
|
36
|
+
|
37
|
+
size_t message_size = 417;
|
38
|
+
char* message = (char*) malloc(message_size);
|
39
|
+
|
40
|
+
if (message) {
|
41
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
42
|
+
strncpy(truncated_argument_0, description, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
43
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
44
|
+
|
45
|
+
char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
46
|
+
strncpy(truncated_argument_1, expected, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
47
|
+
truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
48
|
+
|
49
|
+
char truncated_argument_2[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
50
|
+
strncpy(truncated_argument_2, found, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
51
|
+
truncated_argument_2[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
52
|
+
|
53
|
+
snprintf(
|
54
|
+
message,
|
55
|
+
message_size,
|
56
|
+
message_template,
|
57
|
+
truncated_argument_0,
|
58
|
+
truncated_argument_1,
|
59
|
+
truncated_argument_2
|
60
|
+
);
|
61
|
+
|
62
|
+
unexpected_error->base.message = herb_strdup(message);
|
63
|
+
free(message);
|
64
|
+
} else {
|
65
|
+
unexpected_error->base.message = herb_strdup("%s. Expected: `%s`, found: `%s`.");
|
66
|
+
}
|
67
|
+
|
68
|
+
unexpected_error->description = herb_strdup(description);
|
69
|
+
unexpected_error->expected = herb_strdup(expected);
|
70
|
+
unexpected_error->found = herb_strdup(found);
|
71
|
+
return unexpected_error;
|
72
|
+
}
|
73
|
+
|
74
|
+
void append_unexpected_error(const char* description, const char* expected, const char* found, position_T* start, position_T* end, array_T* errors) {
|
75
|
+
array_append(errors, unexpected_error_init(description, expected, found, start, end));
|
76
|
+
}
|
77
|
+
|
78
|
+
UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T* start, position_T* end) {
|
79
|
+
UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error = malloc(sizeof(UNEXPECTED_TOKEN_ERROR_T));
|
80
|
+
|
81
|
+
error_init(&unexpected_token_error->base, UNEXPECTED_TOKEN_ERROR, start, end);
|
82
|
+
|
83
|
+
const char* message_template = "Found `%s` when expecting `%s` at (%zu:%zu).";
|
84
|
+
|
85
|
+
size_t message_size = 333;
|
86
|
+
char* message = (char*) malloc(message_size);
|
87
|
+
|
88
|
+
if (message) {
|
89
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
90
|
+
strncpy(truncated_argument_0, token_type_to_string(found->type), ERROR_MESSAGES_TRUNCATED_LENGTH);
|
91
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
92
|
+
|
93
|
+
char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
94
|
+
strncpy(truncated_argument_1, token_type_to_string(expected_type), ERROR_MESSAGES_TRUNCATED_LENGTH);
|
95
|
+
truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
96
|
+
|
97
|
+
snprintf(
|
98
|
+
message,
|
99
|
+
message_size,
|
100
|
+
message_template,
|
101
|
+
truncated_argument_0,
|
102
|
+
truncated_argument_1,
|
103
|
+
found->location->start->line,
|
104
|
+
found->location->start->column
|
105
|
+
);
|
106
|
+
|
107
|
+
unexpected_token_error->base.message = herb_strdup(message);
|
108
|
+
free(message);
|
109
|
+
} else {
|
110
|
+
unexpected_token_error->base.message = herb_strdup("Found `%s` when expecting `%s` at (%zu:%zu).");
|
111
|
+
}
|
112
|
+
|
113
|
+
unexpected_token_error->expected_type = expected_type;
|
114
|
+
unexpected_token_error->found = token_copy(found);
|
115
|
+
return unexpected_token_error;
|
116
|
+
}
|
117
|
+
|
118
|
+
void append_unexpected_token_error(token_type_T expected_type, token_T* found, position_T* start, position_T* end, array_T* errors) {
|
119
|
+
array_append(errors, unexpected_token_error_init(expected_type, found, start, end));
|
120
|
+
}
|
121
|
+
|
122
|
+
MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag, position_T* start, position_T* end) {
|
123
|
+
MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error = malloc(sizeof(MISSING_OPENING_TAG_ERROR_T));
|
124
|
+
|
125
|
+
error_init(&missing_opening_tag_error->base, MISSING_OPENING_TAG_ERROR, start, end);
|
126
|
+
|
127
|
+
const char* message_template = "Found closing tag `</%s>` at (%zu:%zu) without a matching opening tag.";
|
128
|
+
|
129
|
+
size_t message_size = 231;
|
130
|
+
char* message = (char*) malloc(message_size);
|
131
|
+
|
132
|
+
if (message) {
|
133
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
134
|
+
strncpy(truncated_argument_0, closing_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
135
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
136
|
+
|
137
|
+
snprintf(
|
138
|
+
message,
|
139
|
+
message_size,
|
140
|
+
message_template,
|
141
|
+
truncated_argument_0,
|
142
|
+
closing_tag->location->start->line,
|
143
|
+
closing_tag->location->start->column
|
144
|
+
);
|
145
|
+
|
146
|
+
missing_opening_tag_error->base.message = herb_strdup(message);
|
147
|
+
free(message);
|
148
|
+
} else {
|
149
|
+
missing_opening_tag_error->base.message = herb_strdup("Found closing tag `</%s>` at (%zu:%zu) without a matching opening tag.");
|
150
|
+
}
|
151
|
+
|
152
|
+
missing_opening_tag_error->closing_tag = token_copy(closing_tag);
|
153
|
+
return missing_opening_tag_error;
|
154
|
+
}
|
155
|
+
|
156
|
+
void append_missing_opening_tag_error(token_T* closing_tag, position_T* start, position_T* end, array_T* errors) {
|
157
|
+
array_append(errors, missing_opening_tag_error_init(closing_tag, start, end));
|
158
|
+
}
|
159
|
+
|
160
|
+
MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag, position_T* start, position_T* end) {
|
161
|
+
MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error = malloc(sizeof(MISSING_CLOSING_TAG_ERROR_T));
|
162
|
+
|
163
|
+
error_init(&missing_closing_tag_error->base, MISSING_CLOSING_TAG_ERROR, start, end);
|
164
|
+
|
165
|
+
const char* message_template = "Opening tag `<%s>` at (%zu:%zu) doesn't have a matching closing tag `</%s>`.";
|
166
|
+
|
167
|
+
size_t message_size = 365;
|
168
|
+
char* message = (char*) malloc(message_size);
|
169
|
+
|
170
|
+
if (message) {
|
171
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
172
|
+
strncpy(truncated_argument_0, opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
173
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
174
|
+
|
175
|
+
char truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
176
|
+
strncpy(truncated_argument_3, opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
177
|
+
truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
178
|
+
|
179
|
+
snprintf(
|
180
|
+
message,
|
181
|
+
message_size,
|
182
|
+
message_template,
|
183
|
+
truncated_argument_0,
|
184
|
+
opening_tag->location->start->line,
|
185
|
+
opening_tag->location->start->column,
|
186
|
+
truncated_argument_3
|
187
|
+
);
|
188
|
+
|
189
|
+
missing_closing_tag_error->base.message = herb_strdup(message);
|
190
|
+
free(message);
|
191
|
+
} else {
|
192
|
+
missing_closing_tag_error->base.message = herb_strdup("Opening tag `<%s>` at (%zu:%zu) doesn't have a matching closing tag `</%s>`.");
|
193
|
+
}
|
194
|
+
|
195
|
+
missing_closing_tag_error->opening_tag = token_copy(opening_tag);
|
196
|
+
return missing_closing_tag_error;
|
197
|
+
}
|
198
|
+
|
199
|
+
void append_missing_closing_tag_error(token_T* opening_tag, position_T* start, position_T* end, array_T* errors) {
|
200
|
+
array_append(errors, missing_closing_tag_error_init(opening_tag, start, end));
|
201
|
+
}
|
202
|
+
|
203
|
+
TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag, token_T* closing_tag, position_T* start, position_T* end) {
|
204
|
+
TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error = malloc(sizeof(TAG_NAMES_MISMATCH_ERROR_T));
|
205
|
+
|
206
|
+
error_init(&tag_names_mismatch_error->base, TAG_NAMES_MISMATCH_ERROR, start, end);
|
207
|
+
|
208
|
+
const char* message_template = "Opening tag `<%s>` at (%zu:%zu) closed with `</%s>` at (%zu:%zu).";
|
209
|
+
|
210
|
+
size_t message_size = 386;
|
211
|
+
char* message = (char*) malloc(message_size);
|
212
|
+
|
213
|
+
if (message) {
|
214
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
215
|
+
strncpy(truncated_argument_0, opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
216
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
217
|
+
|
218
|
+
char truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
219
|
+
strncpy(truncated_argument_3, closing_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
220
|
+
truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
221
|
+
|
222
|
+
snprintf(
|
223
|
+
message,
|
224
|
+
message_size,
|
225
|
+
message_template,
|
226
|
+
truncated_argument_0,
|
227
|
+
opening_tag->location->start->line,
|
228
|
+
opening_tag->location->start->column,
|
229
|
+
truncated_argument_3,
|
230
|
+
closing_tag->location->start->line,
|
231
|
+
closing_tag->location->start->column
|
232
|
+
);
|
233
|
+
|
234
|
+
tag_names_mismatch_error->base.message = herb_strdup(message);
|
235
|
+
free(message);
|
236
|
+
} else {
|
237
|
+
tag_names_mismatch_error->base.message = herb_strdup("Opening tag `<%s>` at (%zu:%zu) closed with `</%s>` at (%zu:%zu).");
|
238
|
+
}
|
239
|
+
|
240
|
+
tag_names_mismatch_error->opening_tag = token_copy(opening_tag);
|
241
|
+
tag_names_mismatch_error->closing_tag = token_copy(closing_tag);
|
242
|
+
return tag_names_mismatch_error;
|
243
|
+
}
|
244
|
+
|
245
|
+
void append_tag_names_mismatch_error(token_T* opening_tag, token_T* closing_tag, position_T* start, position_T* end, array_T* errors) {
|
246
|
+
array_append(errors, tag_names_mismatch_error_init(opening_tag, closing_tag, start, end));
|
247
|
+
}
|
248
|
+
|
249
|
+
QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, token_T* closing_quote, position_T* start, position_T* end) {
|
250
|
+
QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error = malloc(sizeof(QUOTES_MISMATCH_ERROR_T));
|
251
|
+
|
252
|
+
error_init("es_mismatch_error->base, QUOTES_MISMATCH_ERROR, start, end);
|
253
|
+
|
254
|
+
const char* message_template = "String opened with %s but closed with %s at (%zu:%zu).";
|
255
|
+
|
256
|
+
size_t message_size = 343;
|
257
|
+
char* message = (char*) malloc(message_size);
|
258
|
+
|
259
|
+
if (message) {
|
260
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
261
|
+
strncpy(truncated_argument_0, opening_quote->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
262
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
263
|
+
|
264
|
+
char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
265
|
+
strncpy(truncated_argument_1, closing_quote->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
266
|
+
truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
267
|
+
|
268
|
+
snprintf(
|
269
|
+
message,
|
270
|
+
message_size,
|
271
|
+
message_template,
|
272
|
+
truncated_argument_0,
|
273
|
+
truncated_argument_1,
|
274
|
+
closing_quote->location->start->line,
|
275
|
+
closing_quote->location->start->column
|
276
|
+
);
|
277
|
+
|
278
|
+
quotes_mismatch_error->base.message = herb_strdup(message);
|
279
|
+
free(message);
|
280
|
+
} else {
|
281
|
+
quotes_mismatch_error->base.message = herb_strdup("String opened with %s but closed with %s at (%zu:%zu).");
|
282
|
+
}
|
283
|
+
|
284
|
+
quotes_mismatch_error->opening_quote = token_copy(opening_quote);
|
285
|
+
quotes_mismatch_error->closing_quote = token_copy(closing_quote);
|
286
|
+
return quotes_mismatch_error;
|
287
|
+
}
|
288
|
+
|
289
|
+
void append_quotes_mismatch_error(token_T* opening_quote, token_T* closing_quote, position_T* start, position_T* end, array_T* errors) {
|
290
|
+
array_append(errors, quotes_mismatch_error_init(opening_quote, closing_quote, start, end));
|
291
|
+
}
|
292
|
+
|
293
|
+
VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error_init(token_T* tag_name, const char* expected, const char* found, position_T* start, position_T* end) {
|
294
|
+
VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error = malloc(sizeof(VOID_ELEMENT_CLOSING_TAG_ERROR_T));
|
295
|
+
|
296
|
+
error_init(&void_element_closing_tag_error->base, VOID_ELEMENT_CLOSING_TAG_ERROR, start, end);
|
297
|
+
|
298
|
+
const char* message_template = "`%s` is a void element and should not be used as a closing tag. Use `<%s>` or `<%s />` instead of `</%s>`.";
|
299
|
+
|
300
|
+
size_t message_size = 619;
|
301
|
+
char* message = (char*) malloc(message_size);
|
302
|
+
|
303
|
+
if (message) {
|
304
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
305
|
+
strncpy(truncated_argument_0, tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
306
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
307
|
+
|
308
|
+
char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
309
|
+
strncpy(truncated_argument_1, tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
310
|
+
truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
311
|
+
|
312
|
+
char truncated_argument_2[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
313
|
+
strncpy(truncated_argument_2, tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
314
|
+
truncated_argument_2[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
315
|
+
|
316
|
+
char truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
317
|
+
strncpy(truncated_argument_3, tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
318
|
+
truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
319
|
+
|
320
|
+
snprintf(
|
321
|
+
message,
|
322
|
+
message_size,
|
323
|
+
message_template,
|
324
|
+
truncated_argument_0,
|
325
|
+
truncated_argument_1,
|
326
|
+
truncated_argument_2,
|
327
|
+
truncated_argument_3
|
328
|
+
);
|
329
|
+
|
330
|
+
void_element_closing_tag_error->base.message = herb_strdup(message);
|
331
|
+
free(message);
|
332
|
+
} else {
|
333
|
+
void_element_closing_tag_error->base.message = herb_strdup("`%s` is a void element and should not be used as a closing tag. Use `<%s>` or `<%s />` instead of `</%s>`.");
|
334
|
+
}
|
335
|
+
|
336
|
+
void_element_closing_tag_error->tag_name = token_copy(tag_name);
|
337
|
+
void_element_closing_tag_error->expected = herb_strdup(expected);
|
338
|
+
void_element_closing_tag_error->found = herb_strdup(found);
|
339
|
+
return void_element_closing_tag_error;
|
340
|
+
}
|
341
|
+
|
342
|
+
void append_void_element_closing_tag_error(token_T* tag_name, const char* expected, const char* found, position_T* start, position_T* end, array_T* errors) {
|
343
|
+
array_append(errors, void_element_closing_tag_error_init(tag_name, expected, found, start, end));
|
344
|
+
}
|
345
|
+
|
346
|
+
UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, position_T* start, position_T* end) {
|
347
|
+
UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error = malloc(sizeof(UNCLOSED_ELEMENT_ERROR_T));
|
348
|
+
|
349
|
+
error_init(&unclosed_element_error->base, UNCLOSED_ELEMENT_ERROR, start, end);
|
350
|
+
|
351
|
+
const char* message_template = "Tag `<%s>` opened at (%zu:%zu) was never closed before the end of document.";
|
352
|
+
|
353
|
+
size_t message_size = 236;
|
354
|
+
char* message = (char*) malloc(message_size);
|
355
|
+
|
356
|
+
if (message) {
|
357
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
358
|
+
strncpy(truncated_argument_0, opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
359
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
360
|
+
|
361
|
+
snprintf(
|
362
|
+
message,
|
363
|
+
message_size,
|
364
|
+
message_template,
|
365
|
+
truncated_argument_0,
|
366
|
+
opening_tag->location->start->line,
|
367
|
+
opening_tag->location->start->column
|
368
|
+
);
|
369
|
+
|
370
|
+
unclosed_element_error->base.message = herb_strdup(message);
|
371
|
+
free(message);
|
372
|
+
} else {
|
373
|
+
unclosed_element_error->base.message = herb_strdup("Tag `<%s>` opened at (%zu:%zu) was never closed before the end of document.");
|
374
|
+
}
|
375
|
+
|
376
|
+
unclosed_element_error->opening_tag = token_copy(opening_tag);
|
377
|
+
return unclosed_element_error;
|
378
|
+
}
|
379
|
+
|
380
|
+
void append_unclosed_element_error(token_T* opening_tag, position_T* start, position_T* end, array_T* errors) {
|
381
|
+
array_append(errors, unclosed_element_error_init(opening_tag, start, end));
|
382
|
+
}
|
383
|
+
|
384
|
+
RUBY_PARSE_ERROR_T* ruby_parse_error_init(const char* error_message, const char* diagnostic_id, const char* level, position_T* start, position_T* end) {
|
385
|
+
RUBY_PARSE_ERROR_T* ruby_parse_error = malloc(sizeof(RUBY_PARSE_ERROR_T));
|
386
|
+
|
387
|
+
error_init(&ruby_parse_error->base, RUBY_PARSE_ERROR, start, end);
|
388
|
+
|
389
|
+
const char* message_template = "%s: %s";
|
390
|
+
|
391
|
+
size_t message_size = 263;
|
392
|
+
char* message = (char*) malloc(message_size);
|
393
|
+
|
394
|
+
if (message) {
|
395
|
+
char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
396
|
+
strncpy(truncated_argument_0, diagnostic_id, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
397
|
+
truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
398
|
+
|
399
|
+
char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
|
400
|
+
strncpy(truncated_argument_1, error_message, ERROR_MESSAGES_TRUNCATED_LENGTH);
|
401
|
+
truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
|
402
|
+
|
403
|
+
snprintf(
|
404
|
+
message,
|
405
|
+
message_size,
|
406
|
+
message_template,
|
407
|
+
truncated_argument_0,
|
408
|
+
truncated_argument_1
|
409
|
+
);
|
410
|
+
|
411
|
+
ruby_parse_error->base.message = herb_strdup(message);
|
412
|
+
free(message);
|
413
|
+
} else {
|
414
|
+
ruby_parse_error->base.message = herb_strdup("%s: %s");
|
415
|
+
}
|
416
|
+
|
417
|
+
ruby_parse_error->error_message = herb_strdup(error_message);
|
418
|
+
ruby_parse_error->diagnostic_id = herb_strdup(diagnostic_id);
|
419
|
+
ruby_parse_error->level = herb_strdup(level);
|
420
|
+
return ruby_parse_error;
|
421
|
+
}
|
422
|
+
|
423
|
+
void append_ruby_parse_error(const char* error_message, const char* diagnostic_id, const char* level, position_T* start, position_T* end, array_T* errors) {
|
424
|
+
array_append(errors, ruby_parse_error_init(error_message, diagnostic_id, level, start, end));
|
425
|
+
}
|
426
|
+
|
427
|
+
const char* error_type_to_string(ERROR_T* error) {
|
428
|
+
switch (error->type) {
|
429
|
+
case UNEXPECTED_ERROR: return "UNEXPECTED_ERROR";
|
430
|
+
case UNEXPECTED_TOKEN_ERROR: return "UNEXPECTED_TOKEN_ERROR";
|
431
|
+
case MISSING_OPENING_TAG_ERROR: return "MISSING_OPENING_TAG_ERROR";
|
432
|
+
case MISSING_CLOSING_TAG_ERROR: return "MISSING_CLOSING_TAG_ERROR";
|
433
|
+
case TAG_NAMES_MISMATCH_ERROR: return "TAG_NAMES_MISMATCH_ERROR";
|
434
|
+
case QUOTES_MISMATCH_ERROR: return "QUOTES_MISMATCH_ERROR";
|
435
|
+
case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VOID_ELEMENT_CLOSING_TAG_ERROR";
|
436
|
+
case UNCLOSED_ELEMENT_ERROR: return "UNCLOSED_ELEMENT_ERROR";
|
437
|
+
case RUBY_PARSE_ERROR: return "RUBY_PARSE_ERROR";
|
438
|
+
}
|
439
|
+
|
440
|
+
return "Unknown error_type_T";
|
441
|
+
}
|
442
|
+
|
443
|
+
const char* error_human_type(ERROR_T* error) {
|
444
|
+
switch (error->type) {
|
445
|
+
case UNEXPECTED_ERROR: return "UnexpectedError";
|
446
|
+
case UNEXPECTED_TOKEN_ERROR: return "UnexpectedTokenError";
|
447
|
+
case MISSING_OPENING_TAG_ERROR: return "MissingOpeningTagError";
|
448
|
+
case MISSING_CLOSING_TAG_ERROR: return "MissingClosingTagError";
|
449
|
+
case TAG_NAMES_MISMATCH_ERROR: return "TagNamesMismatchError";
|
450
|
+
case QUOTES_MISMATCH_ERROR: return "QuotesMismatchError";
|
451
|
+
case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VoidElementClosingTagError";
|
452
|
+
case UNCLOSED_ELEMENT_ERROR: return "UnclosedElementError";
|
453
|
+
case RUBY_PARSE_ERROR: return "RubyParseError";
|
454
|
+
}
|
455
|
+
|
456
|
+
return "Unknown error_type_T";
|
457
|
+
}
|
458
|
+
|
459
|
+
void error_free_base_error(ERROR_T* error) {
|
460
|
+
if (error == NULL) { return; }
|
461
|
+
|
462
|
+
if (error->location != NULL) { location_free(error->location); }
|
463
|
+
if (error->message != NULL) { free(error->message); }
|
464
|
+
|
465
|
+
free(error);
|
466
|
+
}
|
467
|
+
|
468
|
+
static void error_free_unexpected_error(UNEXPECTED_ERROR_T* unexpected_error) {
|
469
|
+
if (unexpected_error->description != NULL) { free((char*) unexpected_error->description); }
|
470
|
+
if (unexpected_error->expected != NULL) { free((char*) unexpected_error->expected); }
|
471
|
+
if (unexpected_error->found != NULL) { free((char*) unexpected_error->found); }
|
472
|
+
|
473
|
+
error_free_base_error(&unexpected_error->base);
|
474
|
+
}
|
475
|
+
|
476
|
+
static void error_free_unexpected_token_error(UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error) {
|
477
|
+
// token_type_T is part of struct
|
478
|
+
if (unexpected_token_error->found != NULL) { token_free(unexpected_token_error->found); }
|
479
|
+
|
480
|
+
error_free_base_error(&unexpected_token_error->base);
|
481
|
+
}
|
482
|
+
|
483
|
+
static void error_free_missing_opening_tag_error(MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error) {
|
484
|
+
if (missing_opening_tag_error->closing_tag != NULL) { token_free(missing_opening_tag_error->closing_tag); }
|
485
|
+
|
486
|
+
error_free_base_error(&missing_opening_tag_error->base);
|
487
|
+
}
|
488
|
+
|
489
|
+
static void error_free_missing_closing_tag_error(MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error) {
|
490
|
+
if (missing_closing_tag_error->opening_tag != NULL) { token_free(missing_closing_tag_error->opening_tag); }
|
491
|
+
|
492
|
+
error_free_base_error(&missing_closing_tag_error->base);
|
493
|
+
}
|
494
|
+
|
495
|
+
static void error_free_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error) {
|
496
|
+
if (tag_names_mismatch_error->opening_tag != NULL) { token_free(tag_names_mismatch_error->opening_tag); }
|
497
|
+
if (tag_names_mismatch_error->closing_tag != NULL) { token_free(tag_names_mismatch_error->closing_tag); }
|
498
|
+
|
499
|
+
error_free_base_error(&tag_names_mismatch_error->base);
|
500
|
+
}
|
501
|
+
|
502
|
+
static void error_free_quotes_mismatch_error(QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error) {
|
503
|
+
if (quotes_mismatch_error->opening_quote != NULL) { token_free(quotes_mismatch_error->opening_quote); }
|
504
|
+
if (quotes_mismatch_error->closing_quote != NULL) { token_free(quotes_mismatch_error->closing_quote); }
|
505
|
+
|
506
|
+
error_free_base_error("es_mismatch_error->base);
|
507
|
+
}
|
508
|
+
|
509
|
+
static void error_free_void_element_closing_tag_error(VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error) {
|
510
|
+
if (void_element_closing_tag_error->tag_name != NULL) { token_free(void_element_closing_tag_error->tag_name); }
|
511
|
+
if (void_element_closing_tag_error->expected != NULL) { free((char*) void_element_closing_tag_error->expected); }
|
512
|
+
if (void_element_closing_tag_error->found != NULL) { free((char*) void_element_closing_tag_error->found); }
|
513
|
+
|
514
|
+
error_free_base_error(&void_element_closing_tag_error->base);
|
515
|
+
}
|
516
|
+
|
517
|
+
static void error_free_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error) {
|
518
|
+
if (unclosed_element_error->opening_tag != NULL) { token_free(unclosed_element_error->opening_tag); }
|
519
|
+
|
520
|
+
error_free_base_error(&unclosed_element_error->base);
|
521
|
+
}
|
522
|
+
|
523
|
+
static void error_free_ruby_parse_error(RUBY_PARSE_ERROR_T* ruby_parse_error) {
|
524
|
+
if (ruby_parse_error->error_message != NULL) { free((char*) ruby_parse_error->error_message); }
|
525
|
+
if (ruby_parse_error->diagnostic_id != NULL) { free((char*) ruby_parse_error->diagnostic_id); }
|
526
|
+
if (ruby_parse_error->level != NULL) { free((char*) ruby_parse_error->level); }
|
527
|
+
|
528
|
+
error_free_base_error(&ruby_parse_error->base);
|
529
|
+
}
|
530
|
+
|
531
|
+
void error_free(ERROR_T* error) {
|
532
|
+
if (!error) { return; }
|
533
|
+
|
534
|
+
switch (error->type) {
|
535
|
+
case UNEXPECTED_ERROR: error_free_unexpected_error((UNEXPECTED_ERROR_T*) error); break;
|
536
|
+
case UNEXPECTED_TOKEN_ERROR: error_free_unexpected_token_error((UNEXPECTED_TOKEN_ERROR_T*) error); break;
|
537
|
+
case MISSING_OPENING_TAG_ERROR: error_free_missing_opening_tag_error((MISSING_OPENING_TAG_ERROR_T*) error); break;
|
538
|
+
case MISSING_CLOSING_TAG_ERROR: error_free_missing_closing_tag_error((MISSING_CLOSING_TAG_ERROR_T*) error); break;
|
539
|
+
case TAG_NAMES_MISMATCH_ERROR: error_free_tag_names_mismatch_error((TAG_NAMES_MISMATCH_ERROR_T*) error); break;
|
540
|
+
case QUOTES_MISMATCH_ERROR: error_free_quotes_mismatch_error((QUOTES_MISMATCH_ERROR_T*) error); break;
|
541
|
+
case VOID_ELEMENT_CLOSING_TAG_ERROR: error_free_void_element_closing_tag_error((VOID_ELEMENT_CLOSING_TAG_ERROR_T*) error); break;
|
542
|
+
case UNCLOSED_ELEMENT_ERROR: error_free_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error); break;
|
543
|
+
case RUBY_PARSE_ERROR: error_free_ruby_parse_error((RUBY_PARSE_ERROR_T*) error); break;
|
544
|
+
}
|
545
|
+
}
|
546
|
+
|
547
|
+
void error_pretty_print_array(
|
548
|
+
const char* name, array_T* array, const size_t indent, const size_t relative_indent, const bool last_property,
|
549
|
+
buffer_T* buffer
|
550
|
+
) {
|
551
|
+
if (array == NULL) {
|
552
|
+
pretty_print_property(name, "∅", indent, relative_indent, last_property, buffer);
|
553
|
+
|
554
|
+
return;
|
555
|
+
}
|
556
|
+
|
557
|
+
if (array_size(array) == 0) {
|
558
|
+
pretty_print_property(name, "[]", indent, relative_indent, last_property, buffer);
|
559
|
+
|
560
|
+
return;
|
561
|
+
}
|
562
|
+
|
563
|
+
pretty_print_label(name, indent, relative_indent, last_property, buffer);
|
564
|
+
|
565
|
+
buffer_append(buffer, "(");
|
566
|
+
|
567
|
+
char count[16];
|
568
|
+
sprintf(count, "%zu", array_size(array));
|
569
|
+
buffer_append(buffer, count);
|
570
|
+
buffer_append(buffer, ")\n");
|
571
|
+
|
572
|
+
if (indent < 20) {
|
573
|
+
for (size_t i = 0; i < array_size(array); i++) {
|
574
|
+
ERROR_T* child = array_get(array, i);
|
575
|
+
pretty_print_indent(buffer, indent);
|
576
|
+
pretty_print_indent(buffer, relative_indent + 1);
|
577
|
+
|
578
|
+
if (i == array_size(array) - 1) {
|
579
|
+
buffer_append(buffer, "└── ");
|
580
|
+
} else {
|
581
|
+
buffer_append(buffer, "├── ");
|
582
|
+
}
|
583
|
+
|
584
|
+
error_pretty_print(child, indent + 1, relative_indent + 1, buffer);
|
585
|
+
|
586
|
+
if (i != array_size(array) - 1) { pretty_print_newline(indent + 1, relative_indent, buffer); }
|
587
|
+
}
|
588
|
+
}
|
589
|
+
}
|
590
|
+
|
591
|
+
static void error_pretty_print_unexpected_error(UNEXPECTED_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
592
|
+
if (!error) { return; }
|
593
|
+
|
594
|
+
buffer_append(buffer, "@ ");
|
595
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
596
|
+
buffer_append(buffer, " ");
|
597
|
+
|
598
|
+
pretty_print_location(error->base.location, buffer);
|
599
|
+
buffer_append(buffer, "\n");
|
600
|
+
|
601
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
602
|
+
pretty_print_quoted_property("description", error->description, indent, relative_indent, false, buffer);
|
603
|
+
pretty_print_quoted_property("expected", error->expected, indent, relative_indent, false, buffer);
|
604
|
+
pretty_print_quoted_property("found", error->found, indent, relative_indent, true, buffer);
|
605
|
+
}
|
606
|
+
|
607
|
+
static void error_pretty_print_unexpected_token_error(UNEXPECTED_TOKEN_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
608
|
+
if (!error) { return; }
|
609
|
+
|
610
|
+
buffer_append(buffer, "@ ");
|
611
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
612
|
+
buffer_append(buffer, " ");
|
613
|
+
|
614
|
+
pretty_print_location(error->base.location, buffer);
|
615
|
+
buffer_append(buffer, "\n");
|
616
|
+
|
617
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
618
|
+
pretty_print_property(token_type_to_string(error->expected_type), "expected_type", indent, relative_indent, false, buffer);
|
619
|
+
pretty_print_token_property(error->found, "found", indent, relative_indent, true, buffer);
|
620
|
+
}
|
621
|
+
|
622
|
+
static void error_pretty_print_missing_opening_tag_error(MISSING_OPENING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
623
|
+
if (!error) { return; }
|
624
|
+
|
625
|
+
buffer_append(buffer, "@ ");
|
626
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
627
|
+
buffer_append(buffer, " ");
|
628
|
+
|
629
|
+
pretty_print_location(error->base.location, buffer);
|
630
|
+
buffer_append(buffer, "\n");
|
631
|
+
|
632
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
633
|
+
pretty_print_token_property(error->closing_tag, "closing_tag", indent, relative_indent, true, buffer);
|
634
|
+
}
|
635
|
+
|
636
|
+
static void error_pretty_print_missing_closing_tag_error(MISSING_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
637
|
+
if (!error) { return; }
|
638
|
+
|
639
|
+
buffer_append(buffer, "@ ");
|
640
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
641
|
+
buffer_append(buffer, " ");
|
642
|
+
|
643
|
+
pretty_print_location(error->base.location, buffer);
|
644
|
+
buffer_append(buffer, "\n");
|
645
|
+
|
646
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
647
|
+
pretty_print_token_property(error->opening_tag, "opening_tag", indent, relative_indent, true, buffer);
|
648
|
+
}
|
649
|
+
|
650
|
+
static void error_pretty_print_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
651
|
+
if (!error) { return; }
|
652
|
+
|
653
|
+
buffer_append(buffer, "@ ");
|
654
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
655
|
+
buffer_append(buffer, " ");
|
656
|
+
|
657
|
+
pretty_print_location(error->base.location, buffer);
|
658
|
+
buffer_append(buffer, "\n");
|
659
|
+
|
660
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
661
|
+
pretty_print_token_property(error->opening_tag, "opening_tag", indent, relative_indent, false, buffer);
|
662
|
+
pretty_print_token_property(error->closing_tag, "closing_tag", indent, relative_indent, true, buffer);
|
663
|
+
}
|
664
|
+
|
665
|
+
static void error_pretty_print_quotes_mismatch_error(QUOTES_MISMATCH_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
666
|
+
if (!error) { return; }
|
667
|
+
|
668
|
+
buffer_append(buffer, "@ ");
|
669
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
670
|
+
buffer_append(buffer, " ");
|
671
|
+
|
672
|
+
pretty_print_location(error->base.location, buffer);
|
673
|
+
buffer_append(buffer, "\n");
|
674
|
+
|
675
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
676
|
+
pretty_print_token_property(error->opening_quote, "opening_quote", indent, relative_indent, false, buffer);
|
677
|
+
pretty_print_token_property(error->closing_quote, "closing_quote", indent, relative_indent, true, buffer);
|
678
|
+
}
|
679
|
+
|
680
|
+
static void error_pretty_print_void_element_closing_tag_error(VOID_ELEMENT_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
681
|
+
if (!error) { return; }
|
682
|
+
|
683
|
+
buffer_append(buffer, "@ ");
|
684
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
685
|
+
buffer_append(buffer, " ");
|
686
|
+
|
687
|
+
pretty_print_location(error->base.location, buffer);
|
688
|
+
buffer_append(buffer, "\n");
|
689
|
+
|
690
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
691
|
+
pretty_print_token_property(error->tag_name, "tag_name", indent, relative_indent, false, buffer);
|
692
|
+
pretty_print_quoted_property("expected", error->expected, indent, relative_indent, false, buffer);
|
693
|
+
pretty_print_quoted_property("found", error->found, indent, relative_indent, true, buffer);
|
694
|
+
}
|
695
|
+
|
696
|
+
static void error_pretty_print_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
697
|
+
if (!error) { return; }
|
698
|
+
|
699
|
+
buffer_append(buffer, "@ ");
|
700
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
701
|
+
buffer_append(buffer, " ");
|
702
|
+
|
703
|
+
pretty_print_location(error->base.location, buffer);
|
704
|
+
buffer_append(buffer, "\n");
|
705
|
+
|
706
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
707
|
+
pretty_print_token_property(error->opening_tag, "opening_tag", indent, relative_indent, true, buffer);
|
708
|
+
}
|
709
|
+
|
710
|
+
static void error_pretty_print_ruby_parse_error(RUBY_PARSE_ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
711
|
+
if (!error) { return; }
|
712
|
+
|
713
|
+
buffer_append(buffer, "@ ");
|
714
|
+
buffer_append(buffer, error_human_type((ERROR_T*) error));
|
715
|
+
buffer_append(buffer, " ");
|
716
|
+
|
717
|
+
pretty_print_location(error->base.location, buffer);
|
718
|
+
buffer_append(buffer, "\n");
|
719
|
+
|
720
|
+
pretty_print_quoted_property("message", error->base.message, indent, relative_indent, false, buffer);
|
721
|
+
pretty_print_quoted_property("error_message", error->error_message, indent, relative_indent, false, buffer);
|
722
|
+
pretty_print_quoted_property("diagnostic_id", error->diagnostic_id, indent, relative_indent, false, buffer);
|
723
|
+
pretty_print_quoted_property("level", error->level, indent, relative_indent, true, buffer);
|
724
|
+
}
|
725
|
+
|
726
|
+
void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, buffer_T* buffer) {
|
727
|
+
if (!error) { return; }
|
728
|
+
|
729
|
+
switch (error->type) {
|
730
|
+
case UNEXPECTED_ERROR: error_pretty_print_unexpected_error((UNEXPECTED_ERROR_T*) error, indent, relative_indent, buffer); break;
|
731
|
+
case UNEXPECTED_TOKEN_ERROR: error_pretty_print_unexpected_token_error((UNEXPECTED_TOKEN_ERROR_T*) error, indent, relative_indent, buffer); break;
|
732
|
+
case MISSING_OPENING_TAG_ERROR: error_pretty_print_missing_opening_tag_error((MISSING_OPENING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
|
733
|
+
case MISSING_CLOSING_TAG_ERROR: error_pretty_print_missing_closing_tag_error((MISSING_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
|
734
|
+
case TAG_NAMES_MISMATCH_ERROR: error_pretty_print_tag_names_mismatch_error((TAG_NAMES_MISMATCH_ERROR_T*) error, indent, relative_indent, buffer); break;
|
735
|
+
case QUOTES_MISMATCH_ERROR: error_pretty_print_quotes_mismatch_error((QUOTES_MISMATCH_ERROR_T*) error, indent, relative_indent, buffer); break;
|
736
|
+
case VOID_ELEMENT_CLOSING_TAG_ERROR: error_pretty_print_void_element_closing_tag_error((VOID_ELEMENT_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
|
737
|
+
case UNCLOSED_ELEMENT_ERROR: error_pretty_print_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error, indent, relative_indent, buffer); break;
|
738
|
+
case RUBY_PARSE_ERROR: error_pretty_print_ruby_parse_error((RUBY_PARSE_ERROR_T*) error, indent, relative_indent, buffer); break;
|
739
|
+
}
|
740
|
+
}
|