@herb-tools/node 0.8.10 → 0.9.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.
Files changed (169) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/binding.gyp +26 -8
  3. package/dist/herb-node.cjs +41 -12
  4. package/dist/herb-node.cjs.map +1 -1
  5. package/dist/herb-node.esm.js +8 -1
  6. package/dist/herb-node.esm.js.map +1 -1
  7. package/dist/types/node-backend.d.ts +3 -1
  8. package/extension/error_helpers.cpp +395 -73
  9. package/extension/error_helpers.h +13 -3
  10. package/extension/extension_helpers.cpp +38 -35
  11. package/extension/extension_helpers.h +2 -2
  12. package/extension/herb.cpp +183 -64
  13. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.c +290 -0
  14. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.h +36 -0
  15. package/extension/libherb/analyze/action_view/content_tag.c +70 -0
  16. package/extension/libherb/analyze/action_view/link_to.c +143 -0
  17. package/extension/libherb/analyze/action_view/registry.c +60 -0
  18. package/extension/libherb/analyze/action_view/tag.c +64 -0
  19. package/extension/libherb/analyze/action_view/tag_helper_handler.h +41 -0
  20. package/extension/libherb/analyze/action_view/tag_helper_node_builders.c +305 -0
  21. package/extension/libherb/analyze/action_view/tag_helper_node_builders.h +70 -0
  22. package/extension/libherb/analyze/action_view/tag_helpers.c +748 -0
  23. package/extension/libherb/analyze/action_view/tag_helpers.h +38 -0
  24. package/extension/libherb/analyze/action_view/turbo_frame_tag.c +88 -0
  25. package/extension/libherb/analyze/analyze.c +882 -0
  26. package/extension/libherb/{include → analyze}/analyze.h +14 -4
  27. package/extension/libherb/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
  28. package/extension/libherb/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  29. package/extension/libherb/analyze/builders.c +343 -0
  30. package/extension/libherb/analyze/builders.h +27 -0
  31. package/extension/libherb/analyze/conditional_elements.c +594 -0
  32. package/extension/libherb/analyze/conditional_elements.h +9 -0
  33. package/extension/libherb/analyze/conditional_open_tags.c +640 -0
  34. package/extension/libherb/analyze/conditional_open_tags.h +9 -0
  35. package/extension/libherb/analyze/control_type.c +250 -0
  36. package/extension/libherb/analyze/control_type.h +14 -0
  37. package/extension/libherb/{analyze_helpers.c → analyze/helpers.c} +48 -23
  38. package/extension/libherb/{analyze_helpers.h → analyze/helpers.h} +4 -2
  39. package/extension/libherb/analyze/invalid_structures.c +193 -0
  40. package/extension/libherb/analyze/invalid_structures.h +11 -0
  41. package/extension/libherb/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
  42. package/extension/libherb/analyze/parse_errors.c +84 -0
  43. package/extension/libherb/analyze/prism_annotate.c +397 -0
  44. package/extension/libherb/analyze/prism_annotate.h +16 -0
  45. package/extension/libherb/{analyze_transform.c → analyze/transform.c} +17 -3
  46. package/extension/libherb/ast_node.c +17 -7
  47. package/extension/libherb/ast_node.h +11 -5
  48. package/extension/libherb/ast_nodes.c +663 -388
  49. package/extension/libherb/ast_nodes.h +118 -39
  50. package/extension/libherb/ast_pretty_print.c +191 -7
  51. package/extension/libherb/ast_pretty_print.h +6 -1
  52. package/extension/libherb/element_source.h +3 -8
  53. package/extension/libherb/errors.c +1077 -521
  54. package/extension/libherb/errors.h +149 -56
  55. package/extension/libherb/extract.c +145 -49
  56. package/extension/libherb/extract.h +21 -5
  57. package/extension/libherb/herb.c +52 -34
  58. package/extension/libherb/herb.h +18 -6
  59. package/extension/libherb/herb_prism_node.h +13 -0
  60. package/extension/libherb/html_util.c +241 -12
  61. package/extension/libherb/html_util.h +7 -2
  62. package/extension/libherb/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
  63. package/extension/libherb/include/analyze/action_view/tag_helper_handler.h +41 -0
  64. package/extension/libherb/include/analyze/action_view/tag_helper_node_builders.h +70 -0
  65. package/extension/libherb/include/analyze/action_view/tag_helpers.h +38 -0
  66. package/extension/libherb/{analyze.h → include/analyze/analyze.h} +14 -4
  67. package/extension/libherb/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  68. package/extension/libherb/include/analyze/builders.h +27 -0
  69. package/extension/libherb/include/analyze/conditional_elements.h +9 -0
  70. package/extension/libherb/include/analyze/conditional_open_tags.h +9 -0
  71. package/extension/libherb/include/analyze/control_type.h +14 -0
  72. package/extension/libherb/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
  73. package/extension/libherb/include/analyze/invalid_structures.h +11 -0
  74. package/extension/libherb/include/analyze/prism_annotate.h +16 -0
  75. package/extension/libherb/include/ast_node.h +11 -5
  76. package/extension/libherb/include/ast_nodes.h +118 -39
  77. package/extension/libherb/include/ast_pretty_print.h +6 -1
  78. package/extension/libherb/include/element_source.h +3 -8
  79. package/extension/libherb/include/errors.h +149 -56
  80. package/extension/libherb/include/extract.h +21 -5
  81. package/extension/libherb/include/herb.h +18 -6
  82. package/extension/libherb/include/herb_prism_node.h +13 -0
  83. package/extension/libherb/include/html_util.h +7 -2
  84. package/extension/libherb/include/io.h +3 -1
  85. package/extension/libherb/include/lex_helpers.h +29 -0
  86. package/extension/libherb/include/lexer.h +1 -1
  87. package/extension/libherb/include/lexer_peek_helpers.h +87 -13
  88. package/extension/libherb/include/lexer_struct.h +2 -0
  89. package/extension/libherb/include/location.h +2 -1
  90. package/extension/libherb/include/parser.h +27 -2
  91. package/extension/libherb/include/parser_helpers.h +19 -3
  92. package/extension/libherb/include/pretty_print.h +10 -5
  93. package/extension/libherb/include/prism_context.h +45 -0
  94. package/extension/libherb/include/prism_helpers.h +10 -7
  95. package/extension/libherb/include/prism_serialized.h +12 -0
  96. package/extension/libherb/include/token.h +16 -4
  97. package/extension/libherb/include/token_struct.h +10 -3
  98. package/extension/libherb/include/utf8.h +2 -1
  99. package/extension/libherb/include/util/hb_allocator.h +78 -0
  100. package/extension/libherb/include/util/hb_arena.h +6 -1
  101. package/extension/libherb/include/util/hb_arena_debug.h +12 -1
  102. package/extension/libherb/include/util/hb_array.h +7 -3
  103. package/extension/libherb/include/util/hb_buffer.h +6 -4
  104. package/extension/libherb/include/util/hb_foreach.h +79 -0
  105. package/extension/libherb/include/util/hb_narray.h +8 -4
  106. package/extension/libherb/include/util/hb_string.h +56 -9
  107. package/extension/libherb/include/util.h +6 -3
  108. package/extension/libherb/include/version.h +1 -1
  109. package/extension/libherb/io.c +3 -2
  110. package/extension/libherb/io.h +3 -1
  111. package/extension/libherb/lex_helpers.h +29 -0
  112. package/extension/libherb/lexer.c +42 -30
  113. package/extension/libherb/lexer.h +1 -1
  114. package/extension/libherb/lexer_peek_helpers.c +12 -74
  115. package/extension/libherb/lexer_peek_helpers.h +87 -13
  116. package/extension/libherb/lexer_struct.h +2 -0
  117. package/extension/libherb/location.c +2 -2
  118. package/extension/libherb/location.h +2 -1
  119. package/extension/libherb/main.c +53 -28
  120. package/extension/libherb/parser.c +783 -247
  121. package/extension/libherb/parser.h +27 -2
  122. package/extension/libherb/parser_helpers.c +110 -23
  123. package/extension/libherb/parser_helpers.h +19 -3
  124. package/extension/libherb/parser_match_tags.c +110 -49
  125. package/extension/libherb/pretty_print.c +29 -24
  126. package/extension/libherb/pretty_print.h +10 -5
  127. package/extension/libherb/prism_context.h +45 -0
  128. package/extension/libherb/prism_helpers.c +30 -27
  129. package/extension/libherb/prism_helpers.h +10 -7
  130. package/extension/libherb/prism_serialized.h +12 -0
  131. package/extension/libherb/ruby_parser.c +2 -0
  132. package/extension/libherb/token.c +151 -66
  133. package/extension/libherb/token.h +16 -4
  134. package/extension/libherb/token_matchers.c +0 -1
  135. package/extension/libherb/token_struct.h +10 -3
  136. package/extension/libherb/utf8.c +7 -6
  137. package/extension/libherb/utf8.h +2 -1
  138. package/extension/libherb/util/hb_allocator.c +341 -0
  139. package/extension/libherb/util/hb_allocator.h +78 -0
  140. package/extension/libherb/util/hb_arena.c +81 -56
  141. package/extension/libherb/util/hb_arena.h +6 -1
  142. package/extension/libherb/util/hb_arena_debug.c +32 -17
  143. package/extension/libherb/util/hb_arena_debug.h +12 -1
  144. package/extension/libherb/util/hb_array.c +30 -15
  145. package/extension/libherb/util/hb_array.h +7 -3
  146. package/extension/libherb/util/hb_buffer.c +17 -21
  147. package/extension/libherb/util/hb_buffer.h +6 -4
  148. package/extension/libherb/util/hb_foreach.h +79 -0
  149. package/extension/libherb/util/hb_narray.c +22 -7
  150. package/extension/libherb/util/hb_narray.h +8 -4
  151. package/extension/libherb/util/hb_string.c +49 -35
  152. package/extension/libherb/util/hb_string.h +56 -9
  153. package/extension/libherb/util.c +21 -11
  154. package/extension/libherb/util.h +6 -3
  155. package/extension/libherb/version.h +1 -1
  156. package/extension/libherb/visitor.c +48 -1
  157. package/extension/nodes.cpp +451 -6
  158. package/extension/nodes.h +8 -1
  159. package/package.json +12 -8
  160. package/src/node-backend.ts +11 -1
  161. package/dist/types/index-cjs.d.cts +0 -1
  162. package/extension/libherb/analyze.c +0 -1608
  163. package/extension/libherb/element_source.c +0 -12
  164. package/extension/libherb/include/util/hb_system.h +0 -9
  165. package/extension/libherb/util/hb_system.c +0 -30
  166. package/extension/libherb/util/hb_system.h +0 -9
  167. package/src/index-cjs.cts +0 -22
  168. /package/dist/types/{index-esm.d.mts → index.d.ts} +0 -0
  169. /package/src/{index-esm.mts → index.ts} +0 -0
@@ -1,5 +1,5 @@
1
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-0.8.10/templates/src/errors.c.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.0/templates/src/errors.c.erb
3
3
 
4
4
  #include "include/errors.h"
5
5
  #include "include/location.h"
@@ -7,7 +7,9 @@
7
7
  #include "include/pretty_print.h"
8
8
  #include "include/token.h"
9
9
  #include "include/util.h"
10
+ #include "include/util/hb_allocator.h"
10
11
  #include "include/util/hb_array.h"
12
+ #include "include/util/hb_string.h"
11
13
 
12
14
  #include <stdio.h>
13
15
  #include <stdbool.h>
@@ -28,658 +30,1052 @@ void error_init(ERROR_T* error, const error_type_T type, position_T start, posit
28
30
  error->location.end = end;
29
31
  }
30
32
 
31
- UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T start, position_T end) {
32
- UNEXPECTED_ERROR_T* unexpected_error = malloc(sizeof(UNEXPECTED_ERROR_T));
33
+ UNEXPECTED_ERROR_T* unexpected_error_init(hb_string_T description, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator) {
34
+ UNEXPECTED_ERROR_T* unexpected_error = hb_allocator_alloc(allocator, sizeof(UNEXPECTED_ERROR_T));
35
+
36
+ if (!unexpected_error) { return NULL; }
33
37
 
34
38
  error_init(&unexpected_error->base, UNEXPECTED_ERROR, start, end);
35
39
 
36
- const char* message_template = "%s. Expected: `%s`, found: `%s`.";
37
-
38
- size_t message_size = 417;
39
- char* message = (char*) malloc(message_size);
40
-
41
- if (message) {
42
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
43
- strncpy(truncated_argument_0, description, ERROR_MESSAGES_TRUNCATED_LENGTH);
44
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
45
-
46
- char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
47
- strncpy(truncated_argument_1, expected, ERROR_MESSAGES_TRUNCATED_LENGTH);
48
- truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
49
-
50
- char truncated_argument_2[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
51
- strncpy(truncated_argument_2, found, ERROR_MESSAGES_TRUNCATED_LENGTH);
52
- truncated_argument_2[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
53
-
54
- snprintf(
55
- message,
56
- message_size,
57
- message_template,
58
- truncated_argument_0,
59
- truncated_argument_1,
60
- truncated_argument_2
61
- );
62
-
63
- unexpected_error->base.message = herb_strdup(message);
64
- free(message);
65
- } else {
66
- unexpected_error->base.message = herb_strdup("%s. Expected: `%s`, found: `%s`.");
67
- }
40
+ const char* message_template = "%s. Expected: %s, found: %s.";
41
+
42
+ hb_string_T truncated_argument_0 = hb_string_truncate(description, ERROR_MESSAGES_TRUNCATED_LENGTH);
43
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
44
+
45
+ hb_string_T truncated_argument_1 = hb_string_truncate(expected, ERROR_MESSAGES_TRUNCATED_LENGTH);
46
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
47
+
48
+ hb_string_T truncated_argument_2 = hb_string_truncate(found, ERROR_MESSAGES_TRUNCATED_LENGTH);
49
+ char* truncated_c_string_2 = hb_string_to_c_string_using_malloc(truncated_argument_2);
50
+
51
+ char message[413];
52
+ snprintf(
53
+ message,
54
+ sizeof(message),
55
+ message_template,
56
+ truncated_c_string_0 ? truncated_c_string_0 : "",
57
+ truncated_c_string_1 ? truncated_c_string_1 : "",
58
+ truncated_c_string_2 ? truncated_c_string_2 : ""
59
+ );
68
60
 
69
- unexpected_error->description = herb_strdup(description);
70
- unexpected_error->expected = herb_strdup(expected);
71
- unexpected_error->found = herb_strdup(found);
61
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
62
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
63
+ if (truncated_c_string_2) { free(truncated_c_string_2); }
64
+ unexpected_error->base.message = hb_string_copy(hb_string(message), allocator);
65
+
66
+ unexpected_error->description = hb_string_copy(description, allocator);
67
+ unexpected_error->expected = hb_string_copy(expected, allocator);
68
+ unexpected_error->found = hb_string_copy(found, allocator);
72
69
  return unexpected_error;
73
70
  }
74
71
 
75
- void append_unexpected_error(const char* description, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors) {
76
- hb_array_append(errors, unexpected_error_init(description, expected, found, start, end));
72
+ void append_unexpected_error(hb_string_T description, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
73
+ hb_array_append(errors, unexpected_error_init(description, expected, found, start, end, allocator));
77
74
  }
78
75
 
79
- UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end) {
80
- UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error = malloc(sizeof(UNEXPECTED_TOKEN_ERROR_T));
76
+ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end, hb_allocator_T* allocator) {
77
+ UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error = hb_allocator_alloc(allocator, sizeof(UNEXPECTED_TOKEN_ERROR_T));
78
+
79
+ if (!unexpected_token_error) { return NULL; }
81
80
 
82
81
  error_init(&unexpected_token_error->base, UNEXPECTED_TOKEN_ERROR, start, end);
83
82
 
84
- const char* message_template = "Found `%s` when expecting `%s` at (%u:%u).";
85
-
86
- size_t message_size = 319;
87
- char* message = (char*) malloc(message_size);
88
-
89
- if (message) {
90
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
91
- strncpy(truncated_argument_0, token_type_to_string(found->type), ERROR_MESSAGES_TRUNCATED_LENGTH);
92
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
93
-
94
- char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
95
- strncpy(truncated_argument_1, token_type_to_string(expected_type), ERROR_MESSAGES_TRUNCATED_LENGTH);
96
- truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
97
-
98
- snprintf(
99
- message,
100
- message_size,
101
- message_template,
102
- truncated_argument_0,
103
- truncated_argument_1,
104
- found->location.start.line,
105
- found->location.start.column
106
- );
107
-
108
- unexpected_token_error->base.message = herb_strdup(message);
109
- free(message);
110
- } else {
111
- unexpected_token_error->base.message = herb_strdup("Found `%s` when expecting `%s` at (%u:%u).");
112
- }
83
+ const char* message_template = "Found %s when expecting %s at (%u:%u).";
84
+
85
+ hb_string_T truncated_argument_0 = hb_string_truncate(token_type_to_friendly_string(found->type), ERROR_MESSAGES_TRUNCATED_LENGTH);
86
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
87
+
88
+ hb_string_T truncated_argument_1 = hb_string_truncate(token_type_to_friendly_string(expected_type), ERROR_MESSAGES_TRUNCATED_LENGTH);
89
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
90
+
91
+ char message[315];
92
+ snprintf(
93
+ message,
94
+ sizeof(message),
95
+ message_template,
96
+ truncated_c_string_0 ? truncated_c_string_0 : "",
97
+ truncated_c_string_1 ? truncated_c_string_1 : "",
98
+ found->location.start.line,
99
+ found->location.start.column
100
+ );
101
+
102
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
103
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
104
+ unexpected_token_error->base.message = hb_string_copy(hb_string(message), allocator);
113
105
 
114
106
  unexpected_token_error->expected_type = expected_type;
115
- unexpected_token_error->found = token_copy(found);
107
+ unexpected_token_error->found = token_copy(found, allocator);
116
108
  return unexpected_token_error;
117
109
  }
118
110
 
119
- void append_unexpected_token_error(token_type_T expected_type, token_T* found, position_T start, position_T end, hb_array_T* errors) {
120
- hb_array_append(errors, unexpected_token_error_init(expected_type, found, start, end));
111
+ void append_unexpected_token_error(token_type_T expected_type, token_T* found, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
112
+ hb_array_append(errors, unexpected_token_error_init(expected_type, found, start, end, allocator));
121
113
  }
122
114
 
123
- MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag, position_T start, position_T end) {
124
- MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error = malloc(sizeof(MISSING_OPENING_TAG_ERROR_T));
115
+ MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error_init(token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator) {
116
+ MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error = hb_allocator_alloc(allocator, sizeof(MISSING_OPENING_TAG_ERROR_T));
117
+
118
+ if (!missing_opening_tag_error) { return NULL; }
125
119
 
126
120
  error_init(&missing_opening_tag_error->base, MISSING_OPENING_TAG_ERROR, start, end);
127
121
 
128
122
  const char* message_template = "Found closing tag `</%s>` at (%u:%u) without a matching opening tag in the same scope.";
129
123
 
130
- size_t message_size = 235;
131
- char* message = (char*) malloc(message_size);
132
-
133
- if (message) {
134
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
135
- strncpy(truncated_argument_0, closing_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
136
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
137
-
138
- snprintf(
139
- message,
140
- message_size,
141
- message_template,
142
- truncated_argument_0,
143
- closing_tag->location.start.line,
144
- closing_tag->location.start.column
145
- );
146
-
147
- missing_opening_tag_error->base.message = herb_strdup(message);
148
- free(message);
149
- } else {
150
- missing_opening_tag_error->base.message = herb_strdup("Found closing tag `</%s>` at (%u:%u) without a matching opening tag in the same scope.");
151
- }
124
+ hb_string_T truncated_argument_0 = hb_string_truncate(closing_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
125
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
126
+
127
+ char message[235];
128
+ snprintf(
129
+ message,
130
+ sizeof(message),
131
+ message_template,
132
+ truncated_c_string_0 ? truncated_c_string_0 : "",
133
+ closing_tag->location.start.line,
134
+ closing_tag->location.start.column
135
+ );
152
136
 
153
- missing_opening_tag_error->closing_tag = token_copy(closing_tag);
137
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
138
+ missing_opening_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
139
+
140
+ missing_opening_tag_error->closing_tag = token_copy(closing_tag, allocator);
154
141
  return missing_opening_tag_error;
155
142
  }
156
143
 
157
- void append_missing_opening_tag_error(token_T* closing_tag, position_T start, position_T end, hb_array_T* errors) {
158
- hb_array_append(errors, missing_opening_tag_error_init(closing_tag, start, end));
144
+ void append_missing_opening_tag_error(token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
145
+ hb_array_append(errors, missing_opening_tag_error_init(closing_tag, start, end, allocator));
159
146
  }
160
147
 
161
- MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag, position_T start, position_T end) {
162
- MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error = malloc(sizeof(MISSING_CLOSING_TAG_ERROR_T));
148
+ MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error_init(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator) {
149
+ MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error = hb_allocator_alloc(allocator, sizeof(MISSING_CLOSING_TAG_ERROR_T));
150
+
151
+ if (!missing_closing_tag_error) { return NULL; }
163
152
 
164
153
  error_init(&missing_closing_tag_error->base, MISSING_CLOSING_TAG_ERROR, start, end);
165
154
 
166
155
  const char* message_template = "Opening tag `<%s>` at (%u:%u) doesn't have a matching closing tag `</%s>` in the same scope.";
167
156
 
168
- size_t message_size = 369;
169
- char* message = (char*) malloc(message_size);
170
-
171
- if (message) {
172
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
173
- strncpy(truncated_argument_0, opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
174
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
175
-
176
- char truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
177
- strncpy(truncated_argument_3, opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
178
- truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
179
-
180
- snprintf(
181
- message,
182
- message_size,
183
- message_template,
184
- truncated_argument_0,
185
- opening_tag->location.start.line,
186
- opening_tag->location.start.column,
187
- truncated_argument_3
188
- );
189
-
190
- missing_closing_tag_error->base.message = herb_strdup(message);
191
- free(message);
192
- } else {
193
- missing_closing_tag_error->base.message = herb_strdup("Opening tag `<%s>` at (%u:%u) doesn't have a matching closing tag `</%s>` in the same scope.");
194
- }
157
+ hb_string_T truncated_argument_0 = hb_string_truncate(opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
158
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
159
+
160
+ hb_string_T truncated_argument_3 = hb_string_truncate(opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
161
+ char* truncated_c_string_3 = hb_string_to_c_string_using_malloc(truncated_argument_3);
162
+
163
+ char message[369];
164
+ snprintf(
165
+ message,
166
+ sizeof(message),
167
+ message_template,
168
+ truncated_c_string_0 ? truncated_c_string_0 : "",
169
+ opening_tag->location.start.line,
170
+ opening_tag->location.start.column,
171
+ truncated_c_string_3 ? truncated_c_string_3 : ""
172
+ );
195
173
 
196
- missing_closing_tag_error->opening_tag = token_copy(opening_tag);
174
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
175
+ if (truncated_c_string_3) { free(truncated_c_string_3); }
176
+ missing_closing_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
177
+
178
+ missing_closing_tag_error->opening_tag = token_copy(opening_tag, allocator);
197
179
  return missing_closing_tag_error;
198
180
  }
199
181
 
200
- void append_missing_closing_tag_error(token_T* opening_tag, position_T start, position_T end, hb_array_T* errors) {
201
- hb_array_append(errors, missing_closing_tag_error_init(opening_tag, start, end));
182
+ void append_missing_closing_tag_error(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
183
+ hb_array_append(errors, missing_closing_tag_error_init(opening_tag, start, end, allocator));
202
184
  }
203
185
 
204
- TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end) {
205
- TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error = malloc(sizeof(TAG_NAMES_MISMATCH_ERROR_T));
186
+ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error_init(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator) {
187
+ TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error = hb_allocator_alloc(allocator, sizeof(TAG_NAMES_MISMATCH_ERROR_T));
188
+
189
+ if (!tag_names_mismatch_error) { return NULL; }
206
190
 
207
191
  error_init(&tag_names_mismatch_error->base, TAG_NAMES_MISMATCH_ERROR, start, end);
208
192
 
209
193
  const char* message_template = "Opening tag `<%s>` at (%u:%u) closed with `</%s>` at (%u:%u).";
210
194
 
211
- size_t message_size = 358;
212
- char* message = (char*) malloc(message_size);
213
-
214
- if (message) {
215
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
216
- strncpy(truncated_argument_0, opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
217
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
218
-
219
- char truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
220
- strncpy(truncated_argument_3, closing_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
221
- truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
222
-
223
- snprintf(
224
- message,
225
- message_size,
226
- message_template,
227
- truncated_argument_0,
228
- opening_tag->location.start.line,
229
- opening_tag->location.start.column,
230
- truncated_argument_3,
231
- closing_tag->location.start.line,
232
- closing_tag->location.start.column
233
- );
234
-
235
- tag_names_mismatch_error->base.message = herb_strdup(message);
236
- free(message);
237
- } else {
238
- tag_names_mismatch_error->base.message = herb_strdup("Opening tag `<%s>` at (%u:%u) closed with `</%s>` at (%u:%u).");
239
- }
240
-
241
- tag_names_mismatch_error->opening_tag = token_copy(opening_tag);
242
- tag_names_mismatch_error->closing_tag = token_copy(closing_tag);
195
+ hb_string_T truncated_argument_0 = hb_string_truncate(opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
196
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
197
+
198
+ hb_string_T truncated_argument_3 = hb_string_truncate(closing_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
199
+ char* truncated_c_string_3 = hb_string_to_c_string_using_malloc(truncated_argument_3);
200
+
201
+ char message[358];
202
+ snprintf(
203
+ message,
204
+ sizeof(message),
205
+ message_template,
206
+ truncated_c_string_0 ? truncated_c_string_0 : "",
207
+ opening_tag->location.start.line,
208
+ opening_tag->location.start.column,
209
+ truncated_c_string_3 ? truncated_c_string_3 : "",
210
+ closing_tag->location.start.line,
211
+ closing_tag->location.start.column
212
+ );
213
+
214
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
215
+ if (truncated_c_string_3) { free(truncated_c_string_3); }
216
+ tag_names_mismatch_error->base.message = hb_string_copy(hb_string(message), allocator);
217
+
218
+ tag_names_mismatch_error->opening_tag = token_copy(opening_tag, allocator);
219
+ tag_names_mismatch_error->closing_tag = token_copy(closing_tag, allocator);
243
220
  return tag_names_mismatch_error;
244
221
  }
245
222
 
246
- void append_tag_names_mismatch_error(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end, hb_array_T* errors) {
247
- hb_array_append(errors, tag_names_mismatch_error_init(opening_tag, closing_tag, start, end));
248
- }
249
-
250
- QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error_init(token_T* opening_quote, token_T* closing_quote, position_T start, position_T end) {
251
- QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error = malloc(sizeof(QUOTES_MISMATCH_ERROR_T));
252
-
253
- error_init(&quotes_mismatch_error->base, QUOTES_MISMATCH_ERROR, start, end);
254
-
255
- const char* message_template = "String opened with %s but closed with %s at (%u:%u).";
256
-
257
- size_t message_size = 329;
258
- char* message = (char*) malloc(message_size);
259
-
260
- if (message) {
261
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
262
- strncpy(truncated_argument_0, opening_quote->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
263
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
264
-
265
- char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
266
- strncpy(truncated_argument_1, closing_quote->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
267
- truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
268
-
269
- snprintf(
270
- message,
271
- message_size,
272
- message_template,
273
- truncated_argument_0,
274
- truncated_argument_1,
275
- closing_quote->location.start.line,
276
- closing_quote->location.start.column
277
- );
278
-
279
- quotes_mismatch_error->base.message = herb_strdup(message);
280
- free(message);
281
- } else {
282
- quotes_mismatch_error->base.message = herb_strdup("String opened with %s but closed with %s at (%u:%u).");
283
- }
284
-
285
- quotes_mismatch_error->opening_quote = token_copy(opening_quote);
286
- quotes_mismatch_error->closing_quote = token_copy(closing_quote);
287
- return quotes_mismatch_error;
223
+ void append_tag_names_mismatch_error(token_T* opening_tag, token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
224
+ hb_array_append(errors, tag_names_mismatch_error_init(opening_tag, closing_tag, start, end, allocator));
288
225
  }
289
226
 
290
- void append_quotes_mismatch_error(token_T* opening_quote, token_T* closing_quote, position_T start, position_T end, hb_array_T* errors) {
291
- hb_array_append(errors, quotes_mismatch_error_init(opening_quote, closing_quote, start, end));
292
- }
227
+ VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error_init(token_T* tag_name, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator) {
228
+ VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error = hb_allocator_alloc(allocator, sizeof(VOID_ELEMENT_CLOSING_TAG_ERROR_T));
293
229
 
294
- 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) {
295
- VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error = malloc(sizeof(VOID_ELEMENT_CLOSING_TAG_ERROR_T));
230
+ if (!void_element_closing_tag_error) { return NULL; }
296
231
 
297
232
  error_init(&void_element_closing_tag_error->base, VOID_ELEMENT_CLOSING_TAG_ERROR, start, end);
298
233
 
299
234
  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>`.";
300
235
 
301
- size_t message_size = 619;
302
- char* message = (char*) malloc(message_size);
303
-
304
- if (message) {
305
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
306
- strncpy(truncated_argument_0, tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
307
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
308
-
309
- char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
310
- strncpy(truncated_argument_1, tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
311
- truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
312
-
313
- char truncated_argument_2[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
314
- strncpy(truncated_argument_2, tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
315
- truncated_argument_2[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
316
-
317
- char truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
318
- strncpy(truncated_argument_3, tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
319
- truncated_argument_3[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
320
-
321
- snprintf(
322
- message,
323
- message_size,
324
- message_template,
325
- truncated_argument_0,
326
- truncated_argument_1,
327
- truncated_argument_2,
328
- truncated_argument_3
329
- );
330
-
331
- void_element_closing_tag_error->base.message = herb_strdup(message);
332
- free(message);
333
- } else {
334
- 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>`.");
335
- }
336
-
337
- void_element_closing_tag_error->tag_name = token_copy(tag_name);
338
- void_element_closing_tag_error->expected = herb_strdup(expected);
339
- void_element_closing_tag_error->found = herb_strdup(found);
236
+ hb_string_T truncated_argument_0 = hb_string_truncate(tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
237
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
238
+
239
+ hb_string_T truncated_argument_1 = hb_string_truncate(tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
240
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
241
+
242
+ hb_string_T truncated_argument_2 = hb_string_truncate(tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
243
+ char* truncated_c_string_2 = hb_string_to_c_string_using_malloc(truncated_argument_2);
244
+
245
+ hb_string_T truncated_argument_3 = hb_string_truncate(tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
246
+ char* truncated_c_string_3 = hb_string_to_c_string_using_malloc(truncated_argument_3);
247
+
248
+ char message[619];
249
+ snprintf(
250
+ message,
251
+ sizeof(message),
252
+ message_template,
253
+ truncated_c_string_0 ? truncated_c_string_0 : "",
254
+ truncated_c_string_1 ? truncated_c_string_1 : "",
255
+ truncated_c_string_2 ? truncated_c_string_2 : "",
256
+ truncated_c_string_3 ? truncated_c_string_3 : ""
257
+ );
258
+
259
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
260
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
261
+ if (truncated_c_string_2) { free(truncated_c_string_2); }
262
+ if (truncated_c_string_3) { free(truncated_c_string_3); }
263
+ void_element_closing_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
264
+
265
+ void_element_closing_tag_error->tag_name = token_copy(tag_name, allocator);
266
+ void_element_closing_tag_error->expected = hb_string_copy(expected, allocator);
267
+ void_element_closing_tag_error->found = hb_string_copy(found, allocator);
340
268
  return void_element_closing_tag_error;
341
269
  }
342
270
 
343
- void append_void_element_closing_tag_error(token_T* tag_name, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors) {
344
- hb_array_append(errors, void_element_closing_tag_error_init(tag_name, expected, found, start, end));
271
+ void append_void_element_closing_tag_error(token_T* tag_name, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
272
+ hb_array_append(errors, void_element_closing_tag_error_init(tag_name, expected, found, start, end, allocator));
345
273
  }
346
274
 
347
- UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, position_T start, position_T end) {
348
- UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error = malloc(sizeof(UNCLOSED_ELEMENT_ERROR_T));
275
+ UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error_init(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator) {
276
+ UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error = hb_allocator_alloc(allocator, sizeof(UNCLOSED_ELEMENT_ERROR_T));
277
+
278
+ if (!unclosed_element_error) { return NULL; }
349
279
 
350
280
  error_init(&unclosed_element_error->base, UNCLOSED_ELEMENT_ERROR, start, end);
351
281
 
352
282
  const char* message_template = "Tag `<%s>` opened at (%u:%u) was never closed before the end of document.";
353
283
 
354
- size_t message_size = 222;
355
- char* message = (char*) malloc(message_size);
356
-
357
- if (message) {
358
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
359
- strncpy(truncated_argument_0, opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
360
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
361
-
362
- snprintf(
363
- message,
364
- message_size,
365
- message_template,
366
- truncated_argument_0,
367
- opening_tag->location.start.line,
368
- opening_tag->location.start.column
369
- );
370
-
371
- unclosed_element_error->base.message = herb_strdup(message);
372
- free(message);
373
- } else {
374
- unclosed_element_error->base.message = herb_strdup("Tag `<%s>` opened at (%u:%u) was never closed before the end of document.");
375
- }
284
+ hb_string_T truncated_argument_0 = hb_string_truncate(opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
285
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
376
286
 
377
- unclosed_element_error->opening_tag = token_copy(opening_tag);
287
+ char message[222];
288
+ snprintf(
289
+ message,
290
+ sizeof(message),
291
+ message_template,
292
+ truncated_c_string_0 ? truncated_c_string_0 : "",
293
+ opening_tag->location.start.line,
294
+ opening_tag->location.start.column
295
+ );
296
+
297
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
298
+ unclosed_element_error->base.message = hb_string_copy(hb_string(message), allocator);
299
+
300
+ unclosed_element_error->opening_tag = token_copy(opening_tag, allocator);
378
301
  return unclosed_element_error;
379
302
  }
380
303
 
381
- void append_unclosed_element_error(token_T* opening_tag, position_T start, position_T end, hb_array_T* errors) {
382
- hb_array_append(errors, unclosed_element_error_init(opening_tag, start, end));
304
+ void append_unclosed_element_error(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
305
+ hb_array_append(errors, unclosed_element_error_init(opening_tag, start, end, allocator));
383
306
  }
384
307
 
385
- 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) {
386
- RUBY_PARSE_ERROR_T* ruby_parse_error = malloc(sizeof(RUBY_PARSE_ERROR_T));
308
+ RUBY_PARSE_ERROR_T* ruby_parse_error_init(hb_string_T error_message, hb_string_T diagnostic_id, hb_string_T level, position_T start, position_T end, hb_allocator_T* allocator) {
309
+ RUBY_PARSE_ERROR_T* ruby_parse_error = hb_allocator_alloc(allocator, sizeof(RUBY_PARSE_ERROR_T));
310
+
311
+ if (!ruby_parse_error) { return NULL; }
387
312
 
388
313
  error_init(&ruby_parse_error->base, RUBY_PARSE_ERROR, start, end);
389
314
 
390
315
  const char* message_template = "%s: %s";
391
316
 
392
- size_t message_size = 263;
393
- char* message = (char*) malloc(message_size);
394
-
395
- if (message) {
396
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
397
- strncpy(truncated_argument_0, diagnostic_id, ERROR_MESSAGES_TRUNCATED_LENGTH);
398
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
399
-
400
- char truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
401
- strncpy(truncated_argument_1, error_message, ERROR_MESSAGES_TRUNCATED_LENGTH);
402
- truncated_argument_1[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
403
-
404
- snprintf(
405
- message,
406
- message_size,
407
- message_template,
408
- truncated_argument_0,
409
- truncated_argument_1
410
- );
411
-
412
- ruby_parse_error->base.message = herb_strdup(message);
413
- free(message);
414
- } else {
415
- ruby_parse_error->base.message = herb_strdup("%s: %s");
416
- }
317
+ hb_string_T truncated_argument_0 = hb_string_truncate(diagnostic_id, ERROR_MESSAGES_TRUNCATED_LENGTH);
318
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
319
+
320
+ hb_string_T truncated_argument_1 = hb_string_truncate(error_message, ERROR_MESSAGES_TRUNCATED_LENGTH);
321
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
322
+
323
+ char message[263];
324
+ snprintf(
325
+ message,
326
+ sizeof(message),
327
+ message_template,
328
+ truncated_c_string_0 ? truncated_c_string_0 : "",
329
+ truncated_c_string_1 ? truncated_c_string_1 : ""
330
+ );
417
331
 
418
- ruby_parse_error->error_message = herb_strdup(error_message);
419
- ruby_parse_error->diagnostic_id = herb_strdup(diagnostic_id);
420
- ruby_parse_error->level = herb_strdup(level);
332
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
333
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
334
+ ruby_parse_error->base.message = hb_string_copy(hb_string(message), allocator);
335
+
336
+ ruby_parse_error->error_message = hb_string_copy(error_message, allocator);
337
+ ruby_parse_error->diagnostic_id = hb_string_copy(diagnostic_id, allocator);
338
+ ruby_parse_error->level = hb_string_copy(level, allocator);
421
339
  return ruby_parse_error;
422
340
  }
423
341
 
424
- void append_ruby_parse_error(const char* error_message, const char* diagnostic_id, const char* level, position_T start, position_T end, hb_array_T* errors) {
425
- hb_array_append(errors, ruby_parse_error_init(error_message, diagnostic_id, level, start, end));
342
+ void append_ruby_parse_error(hb_string_T error_message, hb_string_T diagnostic_id, hb_string_T level, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
343
+ hb_array_append(errors, ruby_parse_error_init(error_message, diagnostic_id, level, start, end, allocator));
426
344
  }
427
345
 
428
- ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error_init(const char* keyword, position_T start, position_T end) {
429
- ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error = malloc(sizeof(ERB_CONTROL_FLOW_SCOPE_ERROR_T));
346
+ ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error_init(hb_string_T keyword, position_T start, position_T end, hb_allocator_T* allocator) {
347
+ ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error = hb_allocator_alloc(allocator, sizeof(ERB_CONTROL_FLOW_SCOPE_ERROR_T));
348
+
349
+ if (!erb_control_flow_scope_error) { return NULL; }
430
350
 
431
351
  error_init(&erb_control_flow_scope_error->base, ERB_CONTROL_FLOW_SCOPE_ERROR, start, end);
432
352
 
433
353
  const char* message_template = "%s appears outside its control flow block. Keep ERB control flow statements together within the same HTML scope (tag, attribute, or content).";
434
354
 
435
- size_t message_size = 270;
436
- char* message = (char*) malloc(message_size);
437
-
438
- if (message) {
439
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
440
- strncpy(truncated_argument_0, keyword, ERROR_MESSAGES_TRUNCATED_LENGTH);
441
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
442
-
443
- snprintf(
444
- message,
445
- message_size,
446
- message_template,
447
- truncated_argument_0
448
- );
449
-
450
- erb_control_flow_scope_error->base.message = herb_strdup(message);
451
- free(message);
452
- } else {
453
- erb_control_flow_scope_error->base.message = herb_strdup("%s appears outside its control flow block. Keep ERB control flow statements together within the same HTML scope (tag, attribute, or content).");
454
- }
355
+ hb_string_T truncated_argument_0 = hb_string_truncate(keyword, ERROR_MESSAGES_TRUNCATED_LENGTH);
356
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
357
+
358
+ char message[270];
359
+ snprintf(
360
+ message,
361
+ sizeof(message),
362
+ message_template,
363
+ truncated_c_string_0 ? truncated_c_string_0 : ""
364
+ );
365
+
366
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
367
+ erb_control_flow_scope_error->base.message = hb_string_copy(hb_string(message), allocator);
455
368
 
456
- erb_control_flow_scope_error->keyword = herb_strdup(keyword);
369
+ erb_control_flow_scope_error->keyword = hb_string_copy(keyword, allocator);
457
370
  return erb_control_flow_scope_error;
458
371
  }
459
372
 
460
- void append_erb_control_flow_scope_error(const char* keyword, position_T start, position_T end, hb_array_T* errors) {
461
- hb_array_append(errors, erb_control_flow_scope_error_init(keyword, start, end));
373
+ void append_erb_control_flow_scope_error(hb_string_T keyword, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
374
+ hb_array_append(errors, erb_control_flow_scope_error_init(keyword, start, end, allocator));
462
375
  }
463
376
 
464
- MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error_init(const char* keyword, position_T start, position_T end) {
465
- MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error = malloc(sizeof(MISSINGERB_END_TAG_ERROR_T));
377
+ MISSING_ERB_END_TAG_ERROR_T* missing_erb_end_tag_error_init(hb_string_T keyword, position_T start, position_T end, hb_allocator_T* allocator) {
378
+ MISSING_ERB_END_TAG_ERROR_T* missing_erb_end_tag_error = hb_allocator_alloc(allocator, sizeof(MISSING_ERB_END_TAG_ERROR_T));
466
379
 
467
- error_init(&missingerb_end_tag_error->base, MISSINGERB_END_TAG_ERROR, start, end);
380
+ if (!missing_erb_end_tag_error) { return NULL; }
381
+
382
+ error_init(&missing_erb_end_tag_error->base, MISSING_ERB_END_TAG_ERROR, start, end);
468
383
 
469
384
  const char* message_template = "%s started here but never closed with an end tag. The end tag may be in a different scope.";
470
385
 
471
- size_t message_size = 219;
472
- char* message = (char*) malloc(message_size);
473
-
474
- if (message) {
475
- char truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH + 1];
476
- strncpy(truncated_argument_0, keyword, ERROR_MESSAGES_TRUNCATED_LENGTH);
477
- truncated_argument_0[ERROR_MESSAGES_TRUNCATED_LENGTH] = '\0';
478
-
479
- snprintf(
480
- message,
481
- message_size,
482
- message_template,
483
- truncated_argument_0
484
- );
485
-
486
- missingerb_end_tag_error->base.message = herb_strdup(message);
487
- free(message);
488
- } else {
489
- missingerb_end_tag_error->base.message = herb_strdup("%s started here but never closed with an end tag. The end tag may be in a different scope.");
490
- }
386
+ hb_string_T truncated_argument_0 = hb_string_truncate(keyword, ERROR_MESSAGES_TRUNCATED_LENGTH);
387
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
388
+
389
+ char message[219];
390
+ snprintf(
391
+ message,
392
+ sizeof(message),
393
+ message_template,
394
+ truncated_c_string_0 ? truncated_c_string_0 : ""
395
+ );
491
396
 
492
- missingerb_end_tag_error->keyword = herb_strdup(keyword);
493
- return missingerb_end_tag_error;
397
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
398
+ missing_erb_end_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
399
+
400
+ missing_erb_end_tag_error->keyword = hb_string_copy(keyword, allocator);
401
+ return missing_erb_end_tag_error;
494
402
  }
495
403
 
496
- void append_missingerb_end_tag_error(const char* keyword, position_T start, position_T end, hb_array_T* errors) {
497
- hb_array_append(errors, missingerb_end_tag_error_init(keyword, start, end));
404
+ void append_missing_erb_end_tag_error(hb_string_T keyword, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
405
+ hb_array_append(errors, missing_erb_end_tag_error_init(keyword, start, end, allocator));
498
406
  }
499
407
 
500
- ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error_init(position_T start, position_T end) {
501
- ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error = malloc(sizeof(ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T));
408
+ ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error_init(position_T start, position_T end, hb_allocator_T* allocator) {
409
+ ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error = hb_allocator_alloc(allocator, sizeof(ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T));
410
+
411
+ if (!erb_multiple_blocks_in_tag_error) { return NULL; }
502
412
 
503
413
  error_init(&erb_multiple_blocks_in_tag_error->base, ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR, start, end);
504
414
 
505
- erb_multiple_blocks_in_tag_error->base.message = herb_strdup("Multiple unclosed control flow blocks in a single ERB tag. Split each block into its own ERB tag, or close all blocks within the same tag.");
415
+ erb_multiple_blocks_in_tag_error->base.message = hb_string_copy(hb_string("Multiple unclosed control flow blocks in a single ERB tag. Split each block into its own ERB tag, or close all blocks within the same tag."), allocator);
506
416
 
507
417
  return erb_multiple_blocks_in_tag_error;
508
418
  }
509
419
 
510
- void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, hb_array_T* errors) {
511
- hb_array_append(errors, erb_multiple_blocks_in_tag_error_init(start, end));
420
+ void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
421
+ hb_array_append(errors, erb_multiple_blocks_in_tag_error_init(start, end, allocator));
512
422
  }
513
423
 
514
- ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error_init(position_T start, position_T end) {
515
- ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error = malloc(sizeof(ERB_CASE_WITH_CONDITIONS_ERROR_T));
424
+ ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error_init(position_T start, position_T end, hb_allocator_T* allocator) {
425
+ ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error = hb_allocator_alloc(allocator, sizeof(ERB_CASE_WITH_CONDITIONS_ERROR_T));
426
+
427
+ if (!erb_case_with_conditions_error) { return NULL; }
516
428
 
517
429
  error_init(&erb_case_with_conditions_error->base, ERB_CASE_WITH_CONDITIONS_ERROR, start, end);
518
430
 
519
- erb_case_with_conditions_error->base.message = herb_strdup("A `case` statement with `when`/`in` in a single ERB tag cannot be formatted. Use separate tags for `case` and its conditions.");
431
+ erb_case_with_conditions_error->base.message = hb_string_copy(hb_string("A `case` statement with `when`/`in` conditions in a single ERB tag cannot be reliably parsed, compiled, and formatted. Use separate ERB tags for `case` and its conditions (e.g., `<% case x %>` followed by `<% when y %>`)."), allocator);
520
432
 
521
433
  return erb_case_with_conditions_error;
522
434
  }
523
435
 
524
- void append_erb_case_with_conditions_error(position_T start, position_T end, hb_array_T* errors) {
525
- hb_array_append(errors, erb_case_with_conditions_error_init(start, end));
436
+ void append_erb_case_with_conditions_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
437
+ hb_array_append(errors, erb_case_with_conditions_error_init(start, end, allocator));
438
+ }
439
+
440
+ CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T* conditional_element_multiple_tags_error_init(size_t line, size_t column, position_T start, position_T end, hb_allocator_T* allocator) {
441
+ CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T* conditional_element_multiple_tags_error = hb_allocator_alloc(allocator, sizeof(CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T));
442
+
443
+ if (!conditional_element_multiple_tags_error) { return NULL; }
444
+
445
+ error_init(&conditional_element_multiple_tags_error->base, CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR, start, end);
446
+
447
+ const char* message_template = "Conditional element pattern detected at (%zu:%zu) but the conditional block contains multiple HTML tags. Each conditional element must wrap exactly one opening and one closing tag. Consider nesting the conditionals individually.";
448
+
449
+ char message[269];
450
+ snprintf(
451
+ message,
452
+ sizeof(message),
453
+ message_template,
454
+ line,
455
+ column
456
+ );
457
+
458
+ conditional_element_multiple_tags_error->base.message = hb_string_copy(hb_string(message), allocator);
459
+
460
+ conditional_element_multiple_tags_error->line = line;
461
+ conditional_element_multiple_tags_error->column = column;
462
+ return conditional_element_multiple_tags_error;
463
+ }
464
+
465
+ void append_conditional_element_multiple_tags_error(size_t line, size_t column, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
466
+ hb_array_append(errors, conditional_element_multiple_tags_error_init(line, column, start, end, allocator));
467
+ }
468
+
469
+ CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T* conditional_element_condition_mismatch_error_init(hb_string_T tag_name, hb_string_T open_condition, size_t open_line, size_t open_column, hb_string_T close_condition, size_t close_line, size_t close_column, position_T start, position_T end, hb_allocator_T* allocator) {
470
+ CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T* conditional_element_condition_mismatch_error = hb_allocator_alloc(allocator, sizeof(CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T));
471
+
472
+ if (!conditional_element_condition_mismatch_error) { return NULL; }
473
+
474
+ error_init(&conditional_element_condition_mismatch_error->base, CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR, start, end);
475
+
476
+ const char* message_template = "Conditional element `<%s>` has mismatched conditions: opening uses `%s` at (%zu:%zu) but closing uses `%s` at (%zu:%zu). Both conditions must be identical.";
477
+
478
+ hb_string_T truncated_argument_0 = hb_string_truncate(tag_name, ERROR_MESSAGES_TRUNCATED_LENGTH);
479
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
480
+
481
+ hb_string_T truncated_argument_1 = hb_string_truncate(open_condition, ERROR_MESSAGES_TRUNCATED_LENGTH);
482
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
483
+
484
+ hb_string_T truncated_argument_4 = hb_string_truncate(close_condition, ERROR_MESSAGES_TRUNCATED_LENGTH);
485
+ char* truncated_c_string_4 = hb_string_to_c_string_using_malloc(truncated_argument_4);
486
+
487
+ char message[620];
488
+ snprintf(
489
+ message,
490
+ sizeof(message),
491
+ message_template,
492
+ truncated_c_string_0 ? truncated_c_string_0 : "",
493
+ truncated_c_string_1 ? truncated_c_string_1 : "",
494
+ open_line,
495
+ open_column,
496
+ truncated_c_string_4 ? truncated_c_string_4 : "",
497
+ close_line,
498
+ close_column
499
+ );
500
+
501
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
502
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
503
+ if (truncated_c_string_4) { free(truncated_c_string_4); }
504
+ conditional_element_condition_mismatch_error->base.message = hb_string_copy(hb_string(message), allocator);
505
+
506
+ conditional_element_condition_mismatch_error->tag_name = hb_string_copy(tag_name, allocator);
507
+ conditional_element_condition_mismatch_error->open_condition = hb_string_copy(open_condition, allocator);
508
+ conditional_element_condition_mismatch_error->open_line = open_line;
509
+ conditional_element_condition_mismatch_error->open_column = open_column;
510
+ conditional_element_condition_mismatch_error->close_condition = hb_string_copy(close_condition, allocator);
511
+ conditional_element_condition_mismatch_error->close_line = close_line;
512
+ conditional_element_condition_mismatch_error->close_column = close_column;
513
+ return conditional_element_condition_mismatch_error;
514
+ }
515
+
516
+ void append_conditional_element_condition_mismatch_error(hb_string_T tag_name, hb_string_T open_condition, size_t open_line, size_t open_column, hb_string_T close_condition, size_t close_line, size_t close_column, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
517
+ hb_array_append(errors, conditional_element_condition_mismatch_error_init(tag_name, open_condition, open_line, open_column, close_condition, close_line, close_column, start, end, allocator));
518
+ }
519
+
520
+ INVALID_COMMENT_CLOSING_TAG_ERROR_T* invalid_comment_closing_tag_error_init(token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator) {
521
+ INVALID_COMMENT_CLOSING_TAG_ERROR_T* invalid_comment_closing_tag_error = hb_allocator_alloc(allocator, sizeof(INVALID_COMMENT_CLOSING_TAG_ERROR_T));
522
+
523
+ if (!invalid_comment_closing_tag_error) { return NULL; }
524
+
525
+ error_init(&invalid_comment_closing_tag_error->base, INVALID_COMMENT_CLOSING_TAG_ERROR, start, end);
526
+
527
+ const char* message_template = "Invalid comment closing tag `%s` at (%u:%u). Use `-->` instead of `--!>`.";
528
+
529
+ hb_string_T truncated_argument_0 = hb_string_truncate(closing_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
530
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
531
+
532
+ char message[222];
533
+ snprintf(
534
+ message,
535
+ sizeof(message),
536
+ message_template,
537
+ truncated_c_string_0 ? truncated_c_string_0 : "",
538
+ closing_tag->location.start.line,
539
+ closing_tag->location.start.column
540
+ );
541
+
542
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
543
+ invalid_comment_closing_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
544
+
545
+ invalid_comment_closing_tag_error->closing_tag = token_copy(closing_tag, allocator);
546
+ return invalid_comment_closing_tag_error;
547
+ }
548
+
549
+ void append_invalid_comment_closing_tag_error(token_T* closing_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
550
+ hb_array_append(errors, invalid_comment_closing_tag_error_init(closing_tag, start, end, allocator));
551
+ }
552
+
553
+ OMITTED_CLOSING_TAG_ERROR_T* omitted_closing_tag_error_init(token_T* opening_tag, position_T insertion_point, position_T start, position_T end, hb_allocator_T* allocator) {
554
+ OMITTED_CLOSING_TAG_ERROR_T* omitted_closing_tag_error = hb_allocator_alloc(allocator, sizeof(OMITTED_CLOSING_TAG_ERROR_T));
555
+
556
+ if (!omitted_closing_tag_error) { return NULL; }
557
+
558
+ error_init(&omitted_closing_tag_error->base, OMITTED_CLOSING_TAG_ERROR, start, end);
559
+
560
+ const char* message_template = "Element `<%s>` at (%u:%u) has its closing tag omitted. While valid HTML, consider adding an explicit `</%s>` closing tag at (%u:%u) for clarity, or set `strict: false` to allow this.";
561
+
562
+ hb_string_T truncated_argument_0 = hb_string_truncate(opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
563
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
564
+
565
+ hb_string_T truncated_argument_3 = hb_string_truncate(opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
566
+ char* truncated_c_string_3 = hb_string_to_c_string_using_malloc(truncated_argument_3);
567
+
568
+ char message[479];
569
+ snprintf(
570
+ message,
571
+ sizeof(message),
572
+ message_template,
573
+ truncated_c_string_0 ? truncated_c_string_0 : "",
574
+ opening_tag->location.start.line,
575
+ opening_tag->location.start.column,
576
+ truncated_c_string_3 ? truncated_c_string_3 : "",
577
+ insertion_point.line,
578
+ insertion_point.column
579
+ );
580
+
581
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
582
+ if (truncated_c_string_3) { free(truncated_c_string_3); }
583
+ omitted_closing_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
584
+
585
+ omitted_closing_tag_error->opening_tag = token_copy(opening_tag, allocator);
586
+ omitted_closing_tag_error->insertion_point = insertion_point;
587
+ return omitted_closing_tag_error;
588
+ }
589
+
590
+ void append_omitted_closing_tag_error(token_T* opening_tag, position_T insertion_point, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
591
+ hb_array_append(errors, omitted_closing_tag_error_init(opening_tag, insertion_point, start, end, allocator));
592
+ }
593
+
594
+ UNCLOSED_OPEN_TAG_ERROR_T* unclosed_open_tag_error_init(token_T* tag_name, position_T start, position_T end, hb_allocator_T* allocator) {
595
+ UNCLOSED_OPEN_TAG_ERROR_T* unclosed_open_tag_error = hb_allocator_alloc(allocator, sizeof(UNCLOSED_OPEN_TAG_ERROR_T));
596
+
597
+ if (!unclosed_open_tag_error) { return NULL; }
598
+
599
+ error_init(&unclosed_open_tag_error->base, UNCLOSED_OPEN_TAG_ERROR, start, end);
600
+
601
+ const char* message_template = "Opening tag `<%s>` at (%u:%u) is missing closing `>`.";
602
+
603
+ hb_string_T truncated_argument_0 = hb_string_truncate(tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
604
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
605
+
606
+ char message[202];
607
+ snprintf(
608
+ message,
609
+ sizeof(message),
610
+ message_template,
611
+ truncated_c_string_0 ? truncated_c_string_0 : "",
612
+ tag_name->location.start.line,
613
+ tag_name->location.start.column
614
+ );
615
+
616
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
617
+ unclosed_open_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
618
+
619
+ unclosed_open_tag_error->tag_name = token_copy(tag_name, allocator);
620
+ return unclosed_open_tag_error;
621
+ }
622
+
623
+ void append_unclosed_open_tag_error(token_T* tag_name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
624
+ hb_array_append(errors, unclosed_open_tag_error_init(tag_name, start, end, allocator));
625
+ }
626
+
627
+ UNCLOSED_CLOSE_TAG_ERROR_T* unclosed_close_tag_error_init(token_T* tag_name, position_T start, position_T end, hb_allocator_T* allocator) {
628
+ UNCLOSED_CLOSE_TAG_ERROR_T* unclosed_close_tag_error = hb_allocator_alloc(allocator, sizeof(UNCLOSED_CLOSE_TAG_ERROR_T));
629
+
630
+ if (!unclosed_close_tag_error) { return NULL; }
631
+
632
+ error_init(&unclosed_close_tag_error->base, UNCLOSED_CLOSE_TAG_ERROR, start, end);
633
+
634
+ const char* message_template = "Closing tag `</%s>` at (%u:%u) is missing closing `>`.";
635
+
636
+ hb_string_T truncated_argument_0 = hb_string_truncate(tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
637
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
638
+
639
+ char message[203];
640
+ snprintf(
641
+ message,
642
+ sizeof(message),
643
+ message_template,
644
+ truncated_c_string_0 ? truncated_c_string_0 : "",
645
+ tag_name->location.start.line,
646
+ tag_name->location.start.column
647
+ );
648
+
649
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
650
+ unclosed_close_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
651
+
652
+ unclosed_close_tag_error->tag_name = token_copy(tag_name, allocator);
653
+ return unclosed_close_tag_error;
654
+ }
655
+
656
+ void append_unclosed_close_tag_error(token_T* tag_name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
657
+ hb_array_append(errors, unclosed_close_tag_error_init(tag_name, start, end, allocator));
658
+ }
659
+
660
+ UNCLOSED_QUOTE_ERROR_T* unclosed_quote_error_init(token_T* opening_quote, position_T start, position_T end, hb_allocator_T* allocator) {
661
+ UNCLOSED_QUOTE_ERROR_T* unclosed_quote_error = hb_allocator_alloc(allocator, sizeof(UNCLOSED_QUOTE_ERROR_T));
662
+
663
+ if (!unclosed_quote_error) { return NULL; }
664
+
665
+ error_init(&unclosed_quote_error->base, UNCLOSED_QUOTE_ERROR, start, end);
666
+
667
+ const char* message_template = "Attribute value opened with %s at (%u:%u) was never closed.";
668
+
669
+ hb_string_T truncated_argument_0 = hb_string_truncate(opening_quote->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
670
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
671
+
672
+ char message[208];
673
+ snprintf(
674
+ message,
675
+ sizeof(message),
676
+ message_template,
677
+ truncated_c_string_0 ? truncated_c_string_0 : "",
678
+ opening_quote->location.start.line,
679
+ opening_quote->location.start.column
680
+ );
681
+
682
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
683
+ unclosed_quote_error->base.message = hb_string_copy(hb_string(message), allocator);
684
+
685
+ unclosed_quote_error->opening_quote = token_copy(opening_quote, allocator);
686
+ return unclosed_quote_error;
687
+ }
688
+
689
+ void append_unclosed_quote_error(token_T* opening_quote, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
690
+ hb_array_append(errors, unclosed_quote_error_init(opening_quote, start, end, allocator));
526
691
  }
527
692
 
528
- const char* error_type_to_string(ERROR_T* error) {
693
+ MISSING_ATTRIBUTE_VALUE_ERROR_T* missing_attribute_value_error_init(hb_string_T attribute_name, position_T start, position_T end, hb_allocator_T* allocator) {
694
+ MISSING_ATTRIBUTE_VALUE_ERROR_T* missing_attribute_value_error = hb_allocator_alloc(allocator, sizeof(MISSING_ATTRIBUTE_VALUE_ERROR_T));
695
+
696
+ if (!missing_attribute_value_error) { return NULL; }
697
+
698
+ error_init(&missing_attribute_value_error->base, MISSING_ATTRIBUTE_VALUE_ERROR, start, end);
699
+
700
+ const char* message_template = "Attribute `%s` at (%u:%u) is missing a value after the equals sign.";
701
+
702
+ hb_string_T truncated_argument_0 = hb_string_truncate(attribute_name, ERROR_MESSAGES_TRUNCATED_LENGTH);
703
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
704
+
705
+ char message[216];
706
+ snprintf(
707
+ message,
708
+ sizeof(message),
709
+ message_template,
710
+ truncated_c_string_0 ? truncated_c_string_0 : "",
711
+ start.line,
712
+ start.column
713
+ );
714
+
715
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
716
+ missing_attribute_value_error->base.message = hb_string_copy(hb_string(message), allocator);
717
+
718
+ missing_attribute_value_error->attribute_name = hb_string_copy(attribute_name, allocator);
719
+ return missing_attribute_value_error;
720
+ }
721
+
722
+ void append_missing_attribute_value_error(hb_string_T attribute_name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
723
+ hb_array_append(errors, missing_attribute_value_error_init(attribute_name, start, end, allocator));
724
+ }
725
+
726
+ UNCLOSED_ERB_TAG_ERROR_T* unclosed_erb_tag_error_init(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator) {
727
+ UNCLOSED_ERB_TAG_ERROR_T* unclosed_erb_tag_error = hb_allocator_alloc(allocator, sizeof(UNCLOSED_ERB_TAG_ERROR_T));
728
+
729
+ if (!unclosed_erb_tag_error) { return NULL; }
730
+
731
+ error_init(&unclosed_erb_tag_error->base, UNCLOSED_ERB_TAG_ERROR, start, end);
732
+
733
+ const char* message_template = "ERB tag `%s` at (%u:%u) is missing closing `%%>`.";
734
+
735
+ hb_string_T truncated_argument_0 = hb_string_truncate(opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
736
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
737
+
738
+ char message[198];
739
+ snprintf(
740
+ message,
741
+ sizeof(message),
742
+ message_template,
743
+ truncated_c_string_0 ? truncated_c_string_0 : "",
744
+ opening_tag->location.start.line,
745
+ opening_tag->location.start.column
746
+ );
747
+
748
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
749
+ unclosed_erb_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
750
+
751
+ unclosed_erb_tag_error->opening_tag = token_copy(opening_tag, allocator);
752
+ return unclosed_erb_tag_error;
753
+ }
754
+
755
+ void append_unclosed_erb_tag_error(token_T* opening_tag, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
756
+ hb_array_append(errors, unclosed_erb_tag_error_init(opening_tag, start, end, allocator));
757
+ }
758
+
759
+ STRAY_ERB_CLOSING_TAG_ERROR_T* stray_erb_closing_tag_error_init(position_T start, position_T end, hb_allocator_T* allocator) {
760
+ STRAY_ERB_CLOSING_TAG_ERROR_T* stray_erb_closing_tag_error = hb_allocator_alloc(allocator, sizeof(STRAY_ERB_CLOSING_TAG_ERROR_T));
761
+
762
+ if (!stray_erb_closing_tag_error) { return NULL; }
763
+
764
+ error_init(&stray_erb_closing_tag_error->base, STRAY_ERB_CLOSING_TAG_ERROR, start, end);
765
+
766
+ const char* message_template = "Stray `%%>` found at (%u:%u). This closing delimiter is not part of an ERB tag and will be treated as plain text. If you want a literal `%%>`, use the HTML entities `&percnt;&gt;` instead.";
767
+
768
+ char message[209];
769
+ snprintf(
770
+ message,
771
+ sizeof(message),
772
+ message_template,
773
+ start.line,
774
+ start.column
775
+ );
776
+
777
+ stray_erb_closing_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
778
+
779
+ return stray_erb_closing_tag_error;
780
+ }
781
+
782
+ void append_stray_erb_closing_tag_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
783
+ hb_array_append(errors, stray_erb_closing_tag_error_init(start, end, allocator));
784
+ }
785
+
786
+ NESTED_ERB_TAG_ERROR_T* nested_erb_tag_error_init(token_T* opening_tag, size_t nested_tag_line, size_t nested_tag_column, position_T start, position_T end, hb_allocator_T* allocator) {
787
+ NESTED_ERB_TAG_ERROR_T* nested_erb_tag_error = hb_allocator_alloc(allocator, sizeof(NESTED_ERB_TAG_ERROR_T));
788
+
789
+ if (!nested_erb_tag_error) { return NULL; }
790
+
791
+ error_init(&nested_erb_tag_error->base, NESTED_ERB_TAG_ERROR, start, end);
792
+
793
+ const char* message_template = "ERB tag `%s` at (%u:%u) was terminated by nested `<%%` tag at (%zu:%zu). Nesting `<%%` tags is not supported.";
794
+
795
+ hb_string_T truncated_argument_0 = hb_string_truncate(opening_tag->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
796
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
797
+
798
+ char message[298];
799
+ snprintf(
800
+ message,
801
+ sizeof(message),
802
+ message_template,
803
+ truncated_c_string_0 ? truncated_c_string_0 : "",
804
+ opening_tag->location.start.line,
805
+ opening_tag->location.start.column,
806
+ nested_tag_line,
807
+ nested_tag_column
808
+ );
809
+
810
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
811
+ nested_erb_tag_error->base.message = hb_string_copy(hb_string(message), allocator);
812
+
813
+ nested_erb_tag_error->opening_tag = token_copy(opening_tag, allocator);
814
+ nested_erb_tag_error->nested_tag_line = nested_tag_line;
815
+ nested_erb_tag_error->nested_tag_column = nested_tag_column;
816
+ return nested_erb_tag_error;
817
+ }
818
+
819
+ void append_nested_erb_tag_error(token_T* opening_tag, size_t nested_tag_line, size_t nested_tag_column, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
820
+ hb_array_append(errors, nested_erb_tag_error_init(opening_tag, nested_tag_line, nested_tag_column, start, end, allocator));
821
+ }
822
+
823
+ hb_string_T error_type_to_string(ERROR_T* error) {
529
824
  switch (error->type) {
530
- case UNEXPECTED_ERROR: return "UNEXPECTED_ERROR";
531
- case UNEXPECTED_TOKEN_ERROR: return "UNEXPECTED_TOKEN_ERROR";
532
- case MISSING_OPENING_TAG_ERROR: return "MISSING_OPENING_TAG_ERROR";
533
- case MISSING_CLOSING_TAG_ERROR: return "MISSING_CLOSING_TAG_ERROR";
534
- case TAG_NAMES_MISMATCH_ERROR: return "TAG_NAMES_MISMATCH_ERROR";
535
- case QUOTES_MISMATCH_ERROR: return "QUOTES_MISMATCH_ERROR";
536
- case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VOID_ELEMENT_CLOSING_TAG_ERROR";
537
- case UNCLOSED_ELEMENT_ERROR: return "UNCLOSED_ELEMENT_ERROR";
538
- case RUBY_PARSE_ERROR: return "RUBY_PARSE_ERROR";
539
- case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERB_CONTROL_FLOW_SCOPE_ERROR";
540
- case MISSINGERB_END_TAG_ERROR: return "MISSINGERB_END_TAG_ERROR";
541
- case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: return "ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR";
542
- case ERB_CASE_WITH_CONDITIONS_ERROR: return "ERB_CASE_WITH_CONDITIONS_ERROR";
825
+ case UNEXPECTED_ERROR: return hb_string("UNEXPECTED_ERROR");
826
+ case UNEXPECTED_TOKEN_ERROR: return hb_string("UNEXPECTED_TOKEN_ERROR");
827
+ case MISSING_OPENING_TAG_ERROR: return hb_string("MISSING_OPENING_TAG_ERROR");
828
+ case MISSING_CLOSING_TAG_ERROR: return hb_string("MISSING_CLOSING_TAG_ERROR");
829
+ case TAG_NAMES_MISMATCH_ERROR: return hb_string("TAG_NAMES_MISMATCH_ERROR");
830
+ case VOID_ELEMENT_CLOSING_TAG_ERROR: return hb_string("VOID_ELEMENT_CLOSING_TAG_ERROR");
831
+ case UNCLOSED_ELEMENT_ERROR: return hb_string("UNCLOSED_ELEMENT_ERROR");
832
+ case RUBY_PARSE_ERROR: return hb_string("RUBY_PARSE_ERROR");
833
+ case ERB_CONTROL_FLOW_SCOPE_ERROR: return hb_string("ERB_CONTROL_FLOW_SCOPE_ERROR");
834
+ case MISSING_ERB_END_TAG_ERROR: return hb_string("MISSING_ERB_END_TAG_ERROR");
835
+ case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: return hb_string("ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR");
836
+ case ERB_CASE_WITH_CONDITIONS_ERROR: return hb_string("ERB_CASE_WITH_CONDITIONS_ERROR");
837
+ case CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR: return hb_string("CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR");
838
+ case CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR: return hb_string("CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR");
839
+ case INVALID_COMMENT_CLOSING_TAG_ERROR: return hb_string("INVALID_COMMENT_CLOSING_TAG_ERROR");
840
+ case OMITTED_CLOSING_TAG_ERROR: return hb_string("OMITTED_CLOSING_TAG_ERROR");
841
+ case UNCLOSED_OPEN_TAG_ERROR: return hb_string("UNCLOSED_OPEN_TAG_ERROR");
842
+ case UNCLOSED_CLOSE_TAG_ERROR: return hb_string("UNCLOSED_CLOSE_TAG_ERROR");
843
+ case UNCLOSED_QUOTE_ERROR: return hb_string("UNCLOSED_QUOTE_ERROR");
844
+ case MISSING_ATTRIBUTE_VALUE_ERROR: return hb_string("MISSING_ATTRIBUTE_VALUE_ERROR");
845
+ case UNCLOSED_ERB_TAG_ERROR: return hb_string("UNCLOSED_ERB_TAG_ERROR");
846
+ case STRAY_ERB_CLOSING_TAG_ERROR: return hb_string("STRAY_ERB_CLOSING_TAG_ERROR");
847
+ case NESTED_ERB_TAG_ERROR: return hb_string("NESTED_ERB_TAG_ERROR");
543
848
  }
544
849
 
545
- return "Unknown error_type_T";
850
+ return hb_string("Unknown error_type_T");
546
851
  }
547
852
 
548
- const char* error_human_type(ERROR_T* error) {
853
+ hb_string_T error_human_type(ERROR_T* error) {
549
854
  switch (error->type) {
550
- case UNEXPECTED_ERROR: return "UnexpectedError";
551
- case UNEXPECTED_TOKEN_ERROR: return "UnexpectedTokenError";
552
- case MISSING_OPENING_TAG_ERROR: return "MissingOpeningTagError";
553
- case MISSING_CLOSING_TAG_ERROR: return "MissingClosingTagError";
554
- case TAG_NAMES_MISMATCH_ERROR: return "TagNamesMismatchError";
555
- case QUOTES_MISMATCH_ERROR: return "QuotesMismatchError";
556
- case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VoidElementClosingTagError";
557
- case UNCLOSED_ELEMENT_ERROR: return "UnclosedElementError";
558
- case RUBY_PARSE_ERROR: return "RubyParseError";
559
- case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERBControlFlowScopeError";
560
- case MISSINGERB_END_TAG_ERROR: return "MissingERBEndTagError";
561
- case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: return "ERBMultipleBlocksInTagError";
562
- case ERB_CASE_WITH_CONDITIONS_ERROR: return "ERBCaseWithConditionsError";
855
+ case UNEXPECTED_ERROR: return hb_string("UnexpectedError");
856
+ case UNEXPECTED_TOKEN_ERROR: return hb_string("UnexpectedTokenError");
857
+ case MISSING_OPENING_TAG_ERROR: return hb_string("MissingOpeningTagError");
858
+ case MISSING_CLOSING_TAG_ERROR: return hb_string("MissingClosingTagError");
859
+ case TAG_NAMES_MISMATCH_ERROR: return hb_string("TagNamesMismatchError");
860
+ case VOID_ELEMENT_CLOSING_TAG_ERROR: return hb_string("VoidElementClosingTagError");
861
+ case UNCLOSED_ELEMENT_ERROR: return hb_string("UnclosedElementError");
862
+ case RUBY_PARSE_ERROR: return hb_string("RubyParseError");
863
+ case ERB_CONTROL_FLOW_SCOPE_ERROR: return hb_string("ERBControlFlowScopeError");
864
+ case MISSING_ERB_END_TAG_ERROR: return hb_string("MissingERBEndTagError");
865
+ case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: return hb_string("ERBMultipleBlocksInTagError");
866
+ case ERB_CASE_WITH_CONDITIONS_ERROR: return hb_string("ERBCaseWithConditionsError");
867
+ case CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR: return hb_string("ConditionalElementMultipleTagsError");
868
+ case CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR: return hb_string("ConditionalElementConditionMismatchError");
869
+ case INVALID_COMMENT_CLOSING_TAG_ERROR: return hb_string("InvalidCommentClosingTagError");
870
+ case OMITTED_CLOSING_TAG_ERROR: return hb_string("OmittedClosingTagError");
871
+ case UNCLOSED_OPEN_TAG_ERROR: return hb_string("UnclosedOpenTagError");
872
+ case UNCLOSED_CLOSE_TAG_ERROR: return hb_string("UnclosedCloseTagError");
873
+ case UNCLOSED_QUOTE_ERROR: return hb_string("UnclosedQuoteError");
874
+ case MISSING_ATTRIBUTE_VALUE_ERROR: return hb_string("MissingAttributeValueError");
875
+ case UNCLOSED_ERB_TAG_ERROR: return hb_string("UnclosedERBTagError");
876
+ case STRAY_ERB_CLOSING_TAG_ERROR: return hb_string("StrayERBClosingTagError");
877
+ case NESTED_ERB_TAG_ERROR: return hb_string("NestedERBTagError");
563
878
  }
564
879
 
565
- return "Unknown error_type_T";
880
+ return hb_string("Unknown error_type_T");
566
881
  }
567
882
 
568
- void error_free_base_error(ERROR_T* error) {
883
+ void error_free_base_error(ERROR_T* error, hb_allocator_T* allocator) {
569
884
  if (error == NULL) { return; }
570
885
 
571
- if (error->message != NULL) { free(error->message); }
886
+ if (!hb_string_is_null(error->message)) { hb_allocator_dealloc(allocator, error->message.data); }
572
887
 
573
- free(error);
888
+ hb_allocator_dealloc(allocator, error);
574
889
  }
575
890
 
576
- static void error_free_unexpected_error(UNEXPECTED_ERROR_T* unexpected_error) {
577
- if (unexpected_error->description != NULL) { free((char*) unexpected_error->description); }
578
- if (unexpected_error->expected != NULL) { free((char*) unexpected_error->expected); }
579
- if (unexpected_error->found != NULL) { free((char*) unexpected_error->found); }
891
+ static void error_free_unexpected_error(UNEXPECTED_ERROR_T* unexpected_error, hb_allocator_T* allocator) {
892
+ if (unexpected_error->description.data != NULL) { hb_allocator_dealloc(allocator, unexpected_error->description.data); }
893
+ if (unexpected_error->expected.data != NULL) { hb_allocator_dealloc(allocator, unexpected_error->expected.data); }
894
+ if (unexpected_error->found.data != NULL) { hb_allocator_dealloc(allocator, unexpected_error->found.data); }
580
895
 
581
- error_free_base_error(&unexpected_error->base);
896
+ error_free_base_error(&unexpected_error->base, allocator);
582
897
  }
583
898
 
584
- static void error_free_unexpected_token_error(UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error) {
899
+ static void error_free_unexpected_token_error(UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error, hb_allocator_T* allocator) {
585
900
  // token_type_T is part of struct
586
- if (unexpected_token_error->found != NULL) { token_free(unexpected_token_error->found); }
901
+ if (unexpected_token_error->found != NULL) { token_free(unexpected_token_error->found, allocator); }
587
902
 
588
- error_free_base_error(&unexpected_token_error->base);
903
+ error_free_base_error(&unexpected_token_error->base, allocator);
589
904
  }
590
905
 
591
- static void error_free_missing_opening_tag_error(MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error) {
592
- if (missing_opening_tag_error->closing_tag != NULL) { token_free(missing_opening_tag_error->closing_tag); }
906
+ static void error_free_missing_opening_tag_error(MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error, hb_allocator_T* allocator) {
907
+ if (missing_opening_tag_error->closing_tag != NULL) { token_free(missing_opening_tag_error->closing_tag, allocator); }
593
908
 
594
- error_free_base_error(&missing_opening_tag_error->base);
909
+ error_free_base_error(&missing_opening_tag_error->base, allocator);
595
910
  }
596
911
 
597
- static void error_free_missing_closing_tag_error(MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error) {
598
- if (missing_closing_tag_error->opening_tag != NULL) { token_free(missing_closing_tag_error->opening_tag); }
912
+ static void error_free_missing_closing_tag_error(MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error, hb_allocator_T* allocator) {
913
+ if (missing_closing_tag_error->opening_tag != NULL) { token_free(missing_closing_tag_error->opening_tag, allocator); }
599
914
 
600
- error_free_base_error(&missing_closing_tag_error->base);
915
+ error_free_base_error(&missing_closing_tag_error->base, allocator);
601
916
  }
602
917
 
603
- static void error_free_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error) {
604
- if (tag_names_mismatch_error->opening_tag != NULL) { token_free(tag_names_mismatch_error->opening_tag); }
605
- if (tag_names_mismatch_error->closing_tag != NULL) { token_free(tag_names_mismatch_error->closing_tag); }
918
+ static void error_free_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error, hb_allocator_T* allocator) {
919
+ if (tag_names_mismatch_error->opening_tag != NULL) { token_free(tag_names_mismatch_error->opening_tag, allocator); }
920
+ if (tag_names_mismatch_error->closing_tag != NULL) { token_free(tag_names_mismatch_error->closing_tag, allocator); }
606
921
 
607
- error_free_base_error(&tag_names_mismatch_error->base);
922
+ error_free_base_error(&tag_names_mismatch_error->base, allocator);
608
923
  }
609
924
 
610
- static void error_free_quotes_mismatch_error(QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error) {
611
- if (quotes_mismatch_error->opening_quote != NULL) { token_free(quotes_mismatch_error->opening_quote); }
612
- if (quotes_mismatch_error->closing_quote != NULL) { token_free(quotes_mismatch_error->closing_quote); }
925
+ static void error_free_void_element_closing_tag_error(VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error, hb_allocator_T* allocator) {
926
+ if (void_element_closing_tag_error->tag_name != NULL) { token_free(void_element_closing_tag_error->tag_name, allocator); }
927
+ if (void_element_closing_tag_error->expected.data != NULL) { hb_allocator_dealloc(allocator, void_element_closing_tag_error->expected.data); }
928
+ if (void_element_closing_tag_error->found.data != NULL) { hb_allocator_dealloc(allocator, void_element_closing_tag_error->found.data); }
613
929
 
614
- error_free_base_error(&quotes_mismatch_error->base);
930
+ error_free_base_error(&void_element_closing_tag_error->base, allocator);
615
931
  }
616
932
 
617
- static void error_free_void_element_closing_tag_error(VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error) {
618
- if (void_element_closing_tag_error->tag_name != NULL) { token_free(void_element_closing_tag_error->tag_name); }
619
- if (void_element_closing_tag_error->expected != NULL) { free((char*) void_element_closing_tag_error->expected); }
620
- if (void_element_closing_tag_error->found != NULL) { free((char*) void_element_closing_tag_error->found); }
933
+ static void error_free_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error, hb_allocator_T* allocator) {
934
+ if (unclosed_element_error->opening_tag != NULL) { token_free(unclosed_element_error->opening_tag, allocator); }
621
935
 
622
- error_free_base_error(&void_element_closing_tag_error->base);
936
+ error_free_base_error(&unclosed_element_error->base, allocator);
623
937
  }
624
938
 
625
- static void error_free_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error) {
626
- if (unclosed_element_error->opening_tag != NULL) { token_free(unclosed_element_error->opening_tag); }
939
+ static void error_free_ruby_parse_error(RUBY_PARSE_ERROR_T* ruby_parse_error, hb_allocator_T* allocator) {
940
+ if (ruby_parse_error->error_message.data != NULL) { hb_allocator_dealloc(allocator, ruby_parse_error->error_message.data); }
941
+ if (ruby_parse_error->diagnostic_id.data != NULL) { hb_allocator_dealloc(allocator, ruby_parse_error->diagnostic_id.data); }
942
+ if (ruby_parse_error->level.data != NULL) { hb_allocator_dealloc(allocator, ruby_parse_error->level.data); }
627
943
 
628
- error_free_base_error(&unclosed_element_error->base);
944
+ error_free_base_error(&ruby_parse_error->base, allocator);
629
945
  }
630
946
 
631
- static void error_free_ruby_parse_error(RUBY_PARSE_ERROR_T* ruby_parse_error) {
632
- if (ruby_parse_error->error_message != NULL) { free((char*) ruby_parse_error->error_message); }
633
- if (ruby_parse_error->diagnostic_id != NULL) { free((char*) ruby_parse_error->diagnostic_id); }
634
- if (ruby_parse_error->level != NULL) { free((char*) ruby_parse_error->level); }
947
+ static void error_free_erb_control_flow_scope_error(ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error, hb_allocator_T* allocator) {
948
+ if (erb_control_flow_scope_error->keyword.data != NULL) { hb_allocator_dealloc(allocator, erb_control_flow_scope_error->keyword.data); }
635
949
 
636
- error_free_base_error(&ruby_parse_error->base);
950
+ error_free_base_error(&erb_control_flow_scope_error->base, allocator);
637
951
  }
638
952
 
639
- static void error_free_erb_control_flow_scope_error(ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error) {
640
- if (erb_control_flow_scope_error->keyword != NULL) { free((char*) erb_control_flow_scope_error->keyword); }
953
+ static void error_free_missing_erb_end_tag_error(MISSING_ERB_END_TAG_ERROR_T* missing_erb_end_tag_error, hb_allocator_T* allocator) {
954
+ if (missing_erb_end_tag_error->keyword.data != NULL) { hb_allocator_dealloc(allocator, missing_erb_end_tag_error->keyword.data); }
641
955
 
642
- error_free_base_error(&erb_control_flow_scope_error->base);
956
+ error_free_base_error(&missing_erb_end_tag_error->base, allocator);
643
957
  }
644
958
 
645
- static void error_free_missingerb_end_tag_error(MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error) {
646
- if (missingerb_end_tag_error->keyword != NULL) { free((char*) missingerb_end_tag_error->keyword); }
959
+ static void error_free_erb_multiple_blocks_in_tag_error(ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error, hb_allocator_T* allocator) {
960
+ /* no ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T specific fields to free up */
647
961
 
648
- error_free_base_error(&missingerb_end_tag_error->base);
962
+ error_free_base_error(&erb_multiple_blocks_in_tag_error->base, allocator);
649
963
  }
650
964
 
651
- static void error_free_erb_multiple_blocks_in_tag_error(ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error) {
652
- /* no ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T specific fields to free up */
965
+ static void error_free_erb_case_with_conditions_error(ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error, hb_allocator_T* allocator) {
966
+ /* no ERB_CASE_WITH_CONDITIONS_ERROR_T specific fields to free up */
653
967
 
654
- error_free_base_error(&erb_multiple_blocks_in_tag_error->base);
968
+ error_free_base_error(&erb_case_with_conditions_error->base, allocator);
655
969
  }
656
970
 
657
- static void error_free_erb_case_with_conditions_error(ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error) {
658
- /* no ERB_CASE_WITH_CONDITIONS_ERROR_T specific fields to free up */
971
+ static void error_free_conditional_element_multiple_tags_error(CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T* conditional_element_multiple_tags_error, hb_allocator_T* allocator) {
972
+ // size_t is part of struct
973
+ // size_t is part of struct
974
+
975
+ error_free_base_error(&conditional_element_multiple_tags_error->base, allocator);
976
+ }
977
+
978
+ static void error_free_conditional_element_condition_mismatch_error(CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T* conditional_element_condition_mismatch_error, hb_allocator_T* allocator) {
979
+ if (conditional_element_condition_mismatch_error->tag_name.data != NULL) { hb_allocator_dealloc(allocator, conditional_element_condition_mismatch_error->tag_name.data); }
980
+ if (conditional_element_condition_mismatch_error->open_condition.data != NULL) { hb_allocator_dealloc(allocator, conditional_element_condition_mismatch_error->open_condition.data); }
981
+ // size_t is part of struct
982
+ // size_t is part of struct
983
+ if (conditional_element_condition_mismatch_error->close_condition.data != NULL) { hb_allocator_dealloc(allocator, conditional_element_condition_mismatch_error->close_condition.data); }
984
+ // size_t is part of struct
985
+ // size_t is part of struct
986
+
987
+ error_free_base_error(&conditional_element_condition_mismatch_error->base, allocator);
988
+ }
989
+
990
+ static void error_free_invalid_comment_closing_tag_error(INVALID_COMMENT_CLOSING_TAG_ERROR_T* invalid_comment_closing_tag_error, hb_allocator_T* allocator) {
991
+ if (invalid_comment_closing_tag_error->closing_tag != NULL) { token_free(invalid_comment_closing_tag_error->closing_tag, allocator); }
992
+
993
+ error_free_base_error(&invalid_comment_closing_tag_error->base, allocator);
994
+ }
995
+
996
+ static void error_free_omitted_closing_tag_error(OMITTED_CLOSING_TAG_ERROR_T* omitted_closing_tag_error, hb_allocator_T* allocator) {
997
+ if (omitted_closing_tag_error->opening_tag != NULL) { token_free(omitted_closing_tag_error->opening_tag, allocator); }
998
+ // position_T is part of struct
999
+
1000
+ error_free_base_error(&omitted_closing_tag_error->base, allocator);
1001
+ }
1002
+
1003
+ static void error_free_unclosed_open_tag_error(UNCLOSED_OPEN_TAG_ERROR_T* unclosed_open_tag_error, hb_allocator_T* allocator) {
1004
+ if (unclosed_open_tag_error->tag_name != NULL) { token_free(unclosed_open_tag_error->tag_name, allocator); }
1005
+
1006
+ error_free_base_error(&unclosed_open_tag_error->base, allocator);
1007
+ }
1008
+
1009
+ static void error_free_unclosed_close_tag_error(UNCLOSED_CLOSE_TAG_ERROR_T* unclosed_close_tag_error, hb_allocator_T* allocator) {
1010
+ if (unclosed_close_tag_error->tag_name != NULL) { token_free(unclosed_close_tag_error->tag_name, allocator); }
1011
+
1012
+ error_free_base_error(&unclosed_close_tag_error->base, allocator);
1013
+ }
1014
+
1015
+ static void error_free_unclosed_quote_error(UNCLOSED_QUOTE_ERROR_T* unclosed_quote_error, hb_allocator_T* allocator) {
1016
+ if (unclosed_quote_error->opening_quote != NULL) { token_free(unclosed_quote_error->opening_quote, allocator); }
1017
+
1018
+ error_free_base_error(&unclosed_quote_error->base, allocator);
1019
+ }
1020
+
1021
+ static void error_free_missing_attribute_value_error(MISSING_ATTRIBUTE_VALUE_ERROR_T* missing_attribute_value_error, hb_allocator_T* allocator) {
1022
+ if (missing_attribute_value_error->attribute_name.data != NULL) { hb_allocator_dealloc(allocator, missing_attribute_value_error->attribute_name.data); }
1023
+
1024
+ error_free_base_error(&missing_attribute_value_error->base, allocator);
1025
+ }
1026
+
1027
+ static void error_free_unclosed_erb_tag_error(UNCLOSED_ERB_TAG_ERROR_T* unclosed_erb_tag_error, hb_allocator_T* allocator) {
1028
+ if (unclosed_erb_tag_error->opening_tag != NULL) { token_free(unclosed_erb_tag_error->opening_tag, allocator); }
1029
+
1030
+ error_free_base_error(&unclosed_erb_tag_error->base, allocator);
1031
+ }
1032
+
1033
+ static void error_free_stray_erb_closing_tag_error(STRAY_ERB_CLOSING_TAG_ERROR_T* stray_erb_closing_tag_error, hb_allocator_T* allocator) {
1034
+ /* no STRAY_ERB_CLOSING_TAG_ERROR_T specific fields to free up */
1035
+
1036
+ error_free_base_error(&stray_erb_closing_tag_error->base, allocator);
1037
+ }
1038
+
1039
+ static void error_free_nested_erb_tag_error(NESTED_ERB_TAG_ERROR_T* nested_erb_tag_error, hb_allocator_T* allocator) {
1040
+ if (nested_erb_tag_error->opening_tag != NULL) { token_free(nested_erb_tag_error->opening_tag, allocator); }
1041
+ // size_t is part of struct
1042
+ // size_t is part of struct
659
1043
 
660
- error_free_base_error(&erb_case_with_conditions_error->base);
1044
+ error_free_base_error(&nested_erb_tag_error->base, allocator);
661
1045
  }
662
1046
 
663
- void error_free(ERROR_T* error) {
1047
+ void error_free(ERROR_T* error, hb_allocator_T* allocator) {
664
1048
  if (!error) { return; }
665
1049
 
666
1050
  switch (error->type) {
667
- case UNEXPECTED_ERROR: error_free_unexpected_error((UNEXPECTED_ERROR_T*) error); break;
668
- case UNEXPECTED_TOKEN_ERROR: error_free_unexpected_token_error((UNEXPECTED_TOKEN_ERROR_T*) error); break;
669
- case MISSING_OPENING_TAG_ERROR: error_free_missing_opening_tag_error((MISSING_OPENING_TAG_ERROR_T*) error); break;
670
- case MISSING_CLOSING_TAG_ERROR: error_free_missing_closing_tag_error((MISSING_CLOSING_TAG_ERROR_T*) error); break;
671
- case TAG_NAMES_MISMATCH_ERROR: error_free_tag_names_mismatch_error((TAG_NAMES_MISMATCH_ERROR_T*) error); break;
672
- case QUOTES_MISMATCH_ERROR: error_free_quotes_mismatch_error((QUOTES_MISMATCH_ERROR_T*) error); break;
673
- case VOID_ELEMENT_CLOSING_TAG_ERROR: error_free_void_element_closing_tag_error((VOID_ELEMENT_CLOSING_TAG_ERROR_T*) error); break;
674
- case UNCLOSED_ELEMENT_ERROR: error_free_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error); break;
675
- case RUBY_PARSE_ERROR: error_free_ruby_parse_error((RUBY_PARSE_ERROR_T*) error); break;
676
- case ERB_CONTROL_FLOW_SCOPE_ERROR: error_free_erb_control_flow_scope_error((ERB_CONTROL_FLOW_SCOPE_ERROR_T*) error); break;
677
- case MISSINGERB_END_TAG_ERROR: error_free_missingerb_end_tag_error((MISSINGERB_END_TAG_ERROR_T*) error); break;
678
- case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: error_free_erb_multiple_blocks_in_tag_error((ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T*) error); break;
679
- case ERB_CASE_WITH_CONDITIONS_ERROR: error_free_erb_case_with_conditions_error((ERB_CASE_WITH_CONDITIONS_ERROR_T*) error); break;
1051
+ case UNEXPECTED_ERROR: error_free_unexpected_error((UNEXPECTED_ERROR_T*) error, allocator); break;
1052
+ case UNEXPECTED_TOKEN_ERROR: error_free_unexpected_token_error((UNEXPECTED_TOKEN_ERROR_T*) error, allocator); break;
1053
+ case MISSING_OPENING_TAG_ERROR: error_free_missing_opening_tag_error((MISSING_OPENING_TAG_ERROR_T*) error, allocator); break;
1054
+ case MISSING_CLOSING_TAG_ERROR: error_free_missing_closing_tag_error((MISSING_CLOSING_TAG_ERROR_T*) error, allocator); break;
1055
+ case TAG_NAMES_MISMATCH_ERROR: error_free_tag_names_mismatch_error((TAG_NAMES_MISMATCH_ERROR_T*) error, allocator); break;
1056
+ case VOID_ELEMENT_CLOSING_TAG_ERROR: error_free_void_element_closing_tag_error((VOID_ELEMENT_CLOSING_TAG_ERROR_T*) error, allocator); break;
1057
+ case UNCLOSED_ELEMENT_ERROR: error_free_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error, allocator); break;
1058
+ case RUBY_PARSE_ERROR: error_free_ruby_parse_error((RUBY_PARSE_ERROR_T*) error, allocator); break;
1059
+ case ERB_CONTROL_FLOW_SCOPE_ERROR: error_free_erb_control_flow_scope_error((ERB_CONTROL_FLOW_SCOPE_ERROR_T*) error, allocator); break;
1060
+ case MISSING_ERB_END_TAG_ERROR: error_free_missing_erb_end_tag_error((MISSING_ERB_END_TAG_ERROR_T*) error, allocator); break;
1061
+ case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: error_free_erb_multiple_blocks_in_tag_error((ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T*) error, allocator); break;
1062
+ case ERB_CASE_WITH_CONDITIONS_ERROR: error_free_erb_case_with_conditions_error((ERB_CASE_WITH_CONDITIONS_ERROR_T*) error, allocator); break;
1063
+ case CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR: error_free_conditional_element_multiple_tags_error((CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T*) error, allocator); break;
1064
+ case CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR: error_free_conditional_element_condition_mismatch_error((CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T*) error, allocator); break;
1065
+ case INVALID_COMMENT_CLOSING_TAG_ERROR: error_free_invalid_comment_closing_tag_error((INVALID_COMMENT_CLOSING_TAG_ERROR_T*) error, allocator); break;
1066
+ case OMITTED_CLOSING_TAG_ERROR: error_free_omitted_closing_tag_error((OMITTED_CLOSING_TAG_ERROR_T*) error, allocator); break;
1067
+ case UNCLOSED_OPEN_TAG_ERROR: error_free_unclosed_open_tag_error((UNCLOSED_OPEN_TAG_ERROR_T*) error, allocator); break;
1068
+ case UNCLOSED_CLOSE_TAG_ERROR: error_free_unclosed_close_tag_error((UNCLOSED_CLOSE_TAG_ERROR_T*) error, allocator); break;
1069
+ case UNCLOSED_QUOTE_ERROR: error_free_unclosed_quote_error((UNCLOSED_QUOTE_ERROR_T*) error, allocator); break;
1070
+ case MISSING_ATTRIBUTE_VALUE_ERROR: error_free_missing_attribute_value_error((MISSING_ATTRIBUTE_VALUE_ERROR_T*) error, allocator); break;
1071
+ case UNCLOSED_ERB_TAG_ERROR: error_free_unclosed_erb_tag_error((UNCLOSED_ERB_TAG_ERROR_T*) error, allocator); break;
1072
+ case STRAY_ERB_CLOSING_TAG_ERROR: error_free_stray_erb_closing_tag_error((STRAY_ERB_CLOSING_TAG_ERROR_T*) error, allocator); break;
1073
+ case NESTED_ERB_TAG_ERROR: error_free_nested_erb_tag_error((NESTED_ERB_TAG_ERROR_T*) error, allocator); break;
680
1074
  }
681
1075
  }
682
1076
 
1077
+ #ifndef HERB_EXCLUDE_PRETTYPRINT
1078
+
683
1079
  void error_pretty_print_array(
684
1080
  const char* name, hb_array_T* array, const size_t indent, const size_t relative_indent, const bool last_property,
685
1081
  hb_buffer_T* buffer
@@ -728,30 +1124,30 @@ static void error_pretty_print_unexpected_error(UNEXPECTED_ERROR_T* error, const
728
1124
  if (!error) { return; }
729
1125
 
730
1126
  hb_buffer_append(buffer, "@ ");
731
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1127
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
732
1128
  hb_buffer_append(buffer, " ");
733
1129
 
734
1130
  pretty_print_location(error->base.location, buffer);
735
1131
  hb_buffer_append(buffer, "\n");
736
1132
 
737
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
738
- pretty_print_quoted_property(hb_string("description"), hb_string(error->description), indent, relative_indent, false, buffer);
739
- pretty_print_quoted_property(hb_string("expected"), hb_string(error->expected), indent, relative_indent, false, buffer);
740
- pretty_print_quoted_property(hb_string("found"), hb_string(error->found), indent, relative_indent, true, buffer);
1133
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1134
+ pretty_print_quoted_property(hb_string("description"), error->description, indent, relative_indent, false, buffer);
1135
+ pretty_print_quoted_property(hb_string("expected"), error->expected, indent, relative_indent, false, buffer);
1136
+ pretty_print_quoted_property(hb_string("found"), error->found, indent, relative_indent, true, buffer);
741
1137
  }
742
1138
 
743
1139
  static void error_pretty_print_unexpected_token_error(UNEXPECTED_TOKEN_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
744
1140
  if (!error) { return; }
745
1141
 
746
1142
  hb_buffer_append(buffer, "@ ");
747
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1143
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
748
1144
  hb_buffer_append(buffer, " ");
749
1145
 
750
1146
  pretty_print_location(error->base.location, buffer);
751
1147
  hb_buffer_append(buffer, "\n");
752
1148
 
753
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
754
- pretty_print_property(hb_string(token_type_to_string(error->expected_type)), hb_string("expected_type"), indent, relative_indent, false, buffer);
1149
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1150
+ pretty_print_property(token_type_to_string(error->expected_type), hb_string("expected_type"), indent, relative_indent, false, buffer);
755
1151
  pretty_print_token_property(error->found, hb_string("found"), indent, relative_indent, true, buffer);
756
1152
  }
757
1153
 
@@ -759,13 +1155,13 @@ static void error_pretty_print_missing_opening_tag_error(MISSING_OPENING_TAG_ERR
759
1155
  if (!error) { return; }
760
1156
 
761
1157
  hb_buffer_append(buffer, "@ ");
762
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1158
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
763
1159
  hb_buffer_append(buffer, " ");
764
1160
 
765
1161
  pretty_print_location(error->base.location, buffer);
766
1162
  hb_buffer_append(buffer, "\n");
767
1163
 
768
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
1164
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
769
1165
  pretty_print_token_property(error->closing_tag, hb_string("closing_tag"), indent, relative_indent, true, buffer);
770
1166
  }
771
1167
 
@@ -773,13 +1169,13 @@ static void error_pretty_print_missing_closing_tag_error(MISSING_CLOSING_TAG_ERR
773
1169
  if (!error) { return; }
774
1170
 
775
1171
  hb_buffer_append(buffer, "@ ");
776
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1172
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
777
1173
  hb_buffer_append(buffer, " ");
778
1174
 
779
1175
  pretty_print_location(error->base.location, buffer);
780
1176
  hb_buffer_append(buffer, "\n");
781
1177
 
782
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
1178
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
783
1179
  pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, true, buffer);
784
1180
  }
785
1181
 
@@ -787,130 +1183,278 @@ static void error_pretty_print_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR
787
1183
  if (!error) { return; }
788
1184
 
789
1185
  hb_buffer_append(buffer, "@ ");
790
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1186
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
791
1187
  hb_buffer_append(buffer, " ");
792
1188
 
793
1189
  pretty_print_location(error->base.location, buffer);
794
1190
  hb_buffer_append(buffer, "\n");
795
1191
 
796
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
1192
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
797
1193
  pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, false, buffer);
798
1194
  pretty_print_token_property(error->closing_tag, hb_string("closing_tag"), indent, relative_indent, true, buffer);
799
1195
  }
800
1196
 
801
- static void error_pretty_print_quotes_mismatch_error(QUOTES_MISMATCH_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1197
+ 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, hb_buffer_T* buffer) {
802
1198
  if (!error) { return; }
803
1199
 
804
1200
  hb_buffer_append(buffer, "@ ");
805
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1201
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
806
1202
  hb_buffer_append(buffer, " ");
807
1203
 
808
1204
  pretty_print_location(error->base.location, buffer);
809
1205
  hb_buffer_append(buffer, "\n");
810
1206
 
811
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
812
- pretty_print_token_property(error->opening_quote, hb_string("opening_quote"), indent, relative_indent, false, buffer);
813
- pretty_print_token_property(error->closing_quote, hb_string("closing_quote"), indent, relative_indent, true, buffer);
1207
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1208
+ pretty_print_token_property(error->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
1209
+ pretty_print_quoted_property(hb_string("expected"), error->expected, indent, relative_indent, false, buffer);
1210
+ pretty_print_quoted_property(hb_string("found"), error->found, indent, relative_indent, true, buffer);
814
1211
  }
815
1212
 
816
- 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, hb_buffer_T* buffer) {
1213
+ static void error_pretty_print_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
817
1214
  if (!error) { return; }
818
1215
 
819
1216
  hb_buffer_append(buffer, "@ ");
820
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1217
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
821
1218
  hb_buffer_append(buffer, " ");
822
1219
 
823
1220
  pretty_print_location(error->base.location, buffer);
824
1221
  hb_buffer_append(buffer, "\n");
825
1222
 
826
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
827
- pretty_print_token_property(error->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
828
- pretty_print_quoted_property(hb_string("expected"), hb_string(error->expected), indent, relative_indent, false, buffer);
829
- pretty_print_quoted_property(hb_string("found"), hb_string(error->found), indent, relative_indent, true, buffer);
1223
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1224
+ pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, true, buffer);
830
1225
  }
831
1226
 
832
- static void error_pretty_print_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1227
+ static void error_pretty_print_ruby_parse_error(RUBY_PARSE_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
833
1228
  if (!error) { return; }
834
1229
 
835
1230
  hb_buffer_append(buffer, "@ ");
836
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1231
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
837
1232
  hb_buffer_append(buffer, " ");
838
1233
 
839
1234
  pretty_print_location(error->base.location, buffer);
840
1235
  hb_buffer_append(buffer, "\n");
841
1236
 
842
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
843
- pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, true, buffer);
1237
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1238
+ pretty_print_quoted_property(hb_string("error_message"), error->error_message, indent, relative_indent, false, buffer);
1239
+ pretty_print_quoted_property(hb_string("diagnostic_id"), error->diagnostic_id, indent, relative_indent, false, buffer);
1240
+ pretty_print_quoted_property(hb_string("level"), error->level, indent, relative_indent, true, buffer);
844
1241
  }
845
1242
 
846
- static void error_pretty_print_ruby_parse_error(RUBY_PARSE_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1243
+ static void error_pretty_print_erb_control_flow_scope_error(ERB_CONTROL_FLOW_SCOPE_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
847
1244
  if (!error) { return; }
848
1245
 
849
1246
  hb_buffer_append(buffer, "@ ");
850
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1247
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
851
1248
  hb_buffer_append(buffer, " ");
852
1249
 
853
1250
  pretty_print_location(error->base.location, buffer);
854
1251
  hb_buffer_append(buffer, "\n");
855
1252
 
856
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
857
- pretty_print_quoted_property(hb_string("error_message"), hb_string(error->error_message), indent, relative_indent, false, buffer);
858
- pretty_print_quoted_property(hb_string("diagnostic_id"), hb_string(error->diagnostic_id), indent, relative_indent, false, buffer);
859
- pretty_print_quoted_property(hb_string("level"), hb_string(error->level), indent, relative_indent, true, buffer);
1253
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1254
+ pretty_print_quoted_property(hb_string("keyword"), error->keyword, indent, relative_indent, true, buffer);
860
1255
  }
861
1256
 
862
- static void error_pretty_print_erb_control_flow_scope_error(ERB_CONTROL_FLOW_SCOPE_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1257
+ static void error_pretty_print_missing_erb_end_tag_error(MISSING_ERB_END_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
863
1258
  if (!error) { return; }
864
1259
 
865
1260
  hb_buffer_append(buffer, "@ ");
866
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1261
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
867
1262
  hb_buffer_append(buffer, " ");
868
1263
 
869
1264
  pretty_print_location(error->base.location, buffer);
870
1265
  hb_buffer_append(buffer, "\n");
871
1266
 
872
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
873
- pretty_print_quoted_property(hb_string("keyword"), hb_string(error->keyword), indent, relative_indent, true, buffer);
1267
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1268
+ pretty_print_quoted_property(hb_string("keyword"), error->keyword, indent, relative_indent, true, buffer);
874
1269
  }
875
1270
 
876
- static void error_pretty_print_missingerb_end_tag_error(MISSINGERB_END_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1271
+ static void error_pretty_print_erb_multiple_blocks_in_tag_error(ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
877
1272
  if (!error) { return; }
878
1273
 
879
1274
  hb_buffer_append(buffer, "@ ");
880
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1275
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
881
1276
  hb_buffer_append(buffer, " ");
882
1277
 
883
1278
  pretty_print_location(error->base.location, buffer);
884
1279
  hb_buffer_append(buffer, "\n");
885
1280
 
886
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
887
- pretty_print_quoted_property(hb_string("keyword"), hb_string(error->keyword), indent, relative_indent, true, buffer);
1281
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, true, buffer);
888
1282
  }
889
1283
 
890
- static void error_pretty_print_erb_multiple_blocks_in_tag_error(ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1284
+ static void error_pretty_print_erb_case_with_conditions_error(ERB_CASE_WITH_CONDITIONS_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
891
1285
  if (!error) { return; }
892
1286
 
893
1287
  hb_buffer_append(buffer, "@ ");
894
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1288
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
895
1289
  hb_buffer_append(buffer, " ");
896
1290
 
897
1291
  pretty_print_location(error->base.location, buffer);
898
1292
  hb_buffer_append(buffer, "\n");
899
1293
 
900
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, true, buffer);
1294
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, true, buffer);
901
1295
  }
902
1296
 
903
- static void error_pretty_print_erb_case_with_conditions_error(ERB_CASE_WITH_CONDITIONS_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1297
+ static void error_pretty_print_conditional_element_multiple_tags_error(CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
904
1298
  if (!error) { return; }
905
1299
 
906
1300
  hb_buffer_append(buffer, "@ ");
907
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1301
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
908
1302
  hb_buffer_append(buffer, " ");
909
1303
 
910
1304
  pretty_print_location(error->base.location, buffer);
911
1305
  hb_buffer_append(buffer, "\n");
912
1306
 
913
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, true, buffer);
1307
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1308
+ pretty_print_size_t_property(error->line, hb_string("line"), indent, relative_indent, false, buffer);
1309
+ pretty_print_size_t_property(error->column, hb_string("column"), indent, relative_indent, true, buffer);
1310
+ }
1311
+
1312
+ static void error_pretty_print_conditional_element_condition_mismatch_error(CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1313
+ if (!error) { return; }
1314
+
1315
+ hb_buffer_append(buffer, "@ ");
1316
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1317
+ hb_buffer_append(buffer, " ");
1318
+
1319
+ pretty_print_location(error->base.location, buffer);
1320
+ hb_buffer_append(buffer, "\n");
1321
+
1322
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1323
+ pretty_print_quoted_property(hb_string("tag_name"), error->tag_name, indent, relative_indent, false, buffer);
1324
+ pretty_print_quoted_property(hb_string("open_condition"), error->open_condition, indent, relative_indent, false, buffer);
1325
+ pretty_print_size_t_property(error->open_line, hb_string("open_line"), indent, relative_indent, false, buffer);
1326
+ pretty_print_size_t_property(error->open_column, hb_string("open_column"), indent, relative_indent, false, buffer);
1327
+ pretty_print_quoted_property(hb_string("close_condition"), error->close_condition, indent, relative_indent, false, buffer);
1328
+ pretty_print_size_t_property(error->close_line, hb_string("close_line"), indent, relative_indent, false, buffer);
1329
+ pretty_print_size_t_property(error->close_column, hb_string("close_column"), indent, relative_indent, true, buffer);
1330
+ }
1331
+
1332
+ static void error_pretty_print_invalid_comment_closing_tag_error(INVALID_COMMENT_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1333
+ if (!error) { return; }
1334
+
1335
+ hb_buffer_append(buffer, "@ ");
1336
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1337
+ hb_buffer_append(buffer, " ");
1338
+
1339
+ pretty_print_location(error->base.location, buffer);
1340
+ hb_buffer_append(buffer, "\n");
1341
+
1342
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1343
+ pretty_print_token_property(error->closing_tag, hb_string("closing_tag"), indent, relative_indent, true, buffer);
1344
+ }
1345
+
1346
+ static void error_pretty_print_omitted_closing_tag_error(OMITTED_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1347
+ if (!error) { return; }
1348
+
1349
+ hb_buffer_append(buffer, "@ ");
1350
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1351
+ hb_buffer_append(buffer, " ");
1352
+
1353
+ pretty_print_location(error->base.location, buffer);
1354
+ hb_buffer_append(buffer, "\n");
1355
+
1356
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1357
+ pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, false, buffer);
1358
+ pretty_print_position_property(&error->insertion_point, hb_string("insertion_point"), indent, relative_indent, true, buffer);
1359
+ }
1360
+
1361
+ static void error_pretty_print_unclosed_open_tag_error(UNCLOSED_OPEN_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1362
+ if (!error) { return; }
1363
+
1364
+ hb_buffer_append(buffer, "@ ");
1365
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1366
+ hb_buffer_append(buffer, " ");
1367
+
1368
+ pretty_print_location(error->base.location, buffer);
1369
+ hb_buffer_append(buffer, "\n");
1370
+
1371
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1372
+ pretty_print_token_property(error->tag_name, hb_string("tag_name"), indent, relative_indent, true, buffer);
1373
+ }
1374
+
1375
+ static void error_pretty_print_unclosed_close_tag_error(UNCLOSED_CLOSE_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1376
+ if (!error) { return; }
1377
+
1378
+ hb_buffer_append(buffer, "@ ");
1379
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1380
+ hb_buffer_append(buffer, " ");
1381
+
1382
+ pretty_print_location(error->base.location, buffer);
1383
+ hb_buffer_append(buffer, "\n");
1384
+
1385
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1386
+ pretty_print_token_property(error->tag_name, hb_string("tag_name"), indent, relative_indent, true, buffer);
1387
+ }
1388
+
1389
+ static void error_pretty_print_unclosed_quote_error(UNCLOSED_QUOTE_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1390
+ if (!error) { return; }
1391
+
1392
+ hb_buffer_append(buffer, "@ ");
1393
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1394
+ hb_buffer_append(buffer, " ");
1395
+
1396
+ pretty_print_location(error->base.location, buffer);
1397
+ hb_buffer_append(buffer, "\n");
1398
+
1399
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1400
+ pretty_print_token_property(error->opening_quote, hb_string("opening_quote"), indent, relative_indent, true, buffer);
1401
+ }
1402
+
1403
+ static void error_pretty_print_missing_attribute_value_error(MISSING_ATTRIBUTE_VALUE_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1404
+ if (!error) { return; }
1405
+
1406
+ hb_buffer_append(buffer, "@ ");
1407
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1408
+ hb_buffer_append(buffer, " ");
1409
+
1410
+ pretty_print_location(error->base.location, buffer);
1411
+ hb_buffer_append(buffer, "\n");
1412
+
1413
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1414
+ pretty_print_quoted_property(hb_string("attribute_name"), error->attribute_name, indent, relative_indent, true, buffer);
1415
+ }
1416
+
1417
+ static void error_pretty_print_unclosed_erb_tag_error(UNCLOSED_ERB_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1418
+ if (!error) { return; }
1419
+
1420
+ hb_buffer_append(buffer, "@ ");
1421
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1422
+ hb_buffer_append(buffer, " ");
1423
+
1424
+ pretty_print_location(error->base.location, buffer);
1425
+ hb_buffer_append(buffer, "\n");
1426
+
1427
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1428
+ pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, true, buffer);
1429
+ }
1430
+
1431
+ static void error_pretty_print_stray_erb_closing_tag_error(STRAY_ERB_CLOSING_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1432
+ if (!error) { return; }
1433
+
1434
+ hb_buffer_append(buffer, "@ ");
1435
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1436
+ hb_buffer_append(buffer, " ");
1437
+
1438
+ pretty_print_location(error->base.location, buffer);
1439
+ hb_buffer_append(buffer, "\n");
1440
+
1441
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, true, buffer);
1442
+ }
1443
+
1444
+ static void error_pretty_print_nested_erb_tag_error(NESTED_ERB_TAG_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1445
+ if (!error) { return; }
1446
+
1447
+ hb_buffer_append(buffer, "@ ");
1448
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1449
+ hb_buffer_append(buffer, " ");
1450
+
1451
+ pretty_print_location(error->base.location, buffer);
1452
+ hb_buffer_append(buffer, "\n");
1453
+
1454
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1455
+ pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, false, buffer);
1456
+ pretty_print_size_t_property(error->nested_tag_line, hb_string("nested_tag_line"), indent, relative_indent, false, buffer);
1457
+ pretty_print_size_t_property(error->nested_tag_column, hb_string("nested_tag_column"), indent, relative_indent, true, buffer);
914
1458
  }
915
1459
 
916
1460
  void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
@@ -922,13 +1466,25 @@ void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relati
922
1466
  case MISSING_OPENING_TAG_ERROR: error_pretty_print_missing_opening_tag_error((MISSING_OPENING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
923
1467
  case MISSING_CLOSING_TAG_ERROR: error_pretty_print_missing_closing_tag_error((MISSING_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
924
1468
  case TAG_NAMES_MISMATCH_ERROR: error_pretty_print_tag_names_mismatch_error((TAG_NAMES_MISMATCH_ERROR_T*) error, indent, relative_indent, buffer); break;
925
- case QUOTES_MISMATCH_ERROR: error_pretty_print_quotes_mismatch_error((QUOTES_MISMATCH_ERROR_T*) error, indent, relative_indent, buffer); break;
926
1469
  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;
927
1470
  case UNCLOSED_ELEMENT_ERROR: error_pretty_print_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error, indent, relative_indent, buffer); break;
928
1471
  case RUBY_PARSE_ERROR: error_pretty_print_ruby_parse_error((RUBY_PARSE_ERROR_T*) error, indent, relative_indent, buffer); break;
929
1472
  case ERB_CONTROL_FLOW_SCOPE_ERROR: error_pretty_print_erb_control_flow_scope_error((ERB_CONTROL_FLOW_SCOPE_ERROR_T*) error, indent, relative_indent, buffer); break;
930
- case MISSINGERB_END_TAG_ERROR: error_pretty_print_missingerb_end_tag_error((MISSINGERB_END_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1473
+ case MISSING_ERB_END_TAG_ERROR: error_pretty_print_missing_erb_end_tag_error((MISSING_ERB_END_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
931
1474
  case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: error_pretty_print_erb_multiple_blocks_in_tag_error((ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
932
1475
  case ERB_CASE_WITH_CONDITIONS_ERROR: error_pretty_print_erb_case_with_conditions_error((ERB_CASE_WITH_CONDITIONS_ERROR_T*) error, indent, relative_indent, buffer); break;
1476
+ case CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR: error_pretty_print_conditional_element_multiple_tags_error((CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T*) error, indent, relative_indent, buffer); break;
1477
+ case CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR: error_pretty_print_conditional_element_condition_mismatch_error((CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T*) error, indent, relative_indent, buffer); break;
1478
+ case INVALID_COMMENT_CLOSING_TAG_ERROR: error_pretty_print_invalid_comment_closing_tag_error((INVALID_COMMENT_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1479
+ case OMITTED_CLOSING_TAG_ERROR: error_pretty_print_omitted_closing_tag_error((OMITTED_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1480
+ case UNCLOSED_OPEN_TAG_ERROR: error_pretty_print_unclosed_open_tag_error((UNCLOSED_OPEN_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1481
+ case UNCLOSED_CLOSE_TAG_ERROR: error_pretty_print_unclosed_close_tag_error((UNCLOSED_CLOSE_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1482
+ case UNCLOSED_QUOTE_ERROR: error_pretty_print_unclosed_quote_error((UNCLOSED_QUOTE_ERROR_T*) error, indent, relative_indent, buffer); break;
1483
+ case MISSING_ATTRIBUTE_VALUE_ERROR: error_pretty_print_missing_attribute_value_error((MISSING_ATTRIBUTE_VALUE_ERROR_T*) error, indent, relative_indent, buffer); break;
1484
+ case UNCLOSED_ERB_TAG_ERROR: error_pretty_print_unclosed_erb_tag_error((UNCLOSED_ERB_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1485
+ case STRAY_ERB_CLOSING_TAG_ERROR: error_pretty_print_stray_erb_closing_tag_error((STRAY_ERB_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1486
+ case NESTED_ERB_TAG_ERROR: error_pretty_print_nested_erb_tag_error((NESTED_ERB_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
933
1487
  }
934
1488
  }
1489
+
1490
+ #endif