@herb-tools/node 0.8.9 → 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 (174) 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 +419 -71
  9. package/extension/error_helpers.h +14 -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} +79 -31
  38. package/extension/libherb/{analyze_helpers.h → analyze/helpers.h} +22 -17
  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 +1100 -507
  54. package/extension/libherb/errors.h +155 -54
  55. package/extension/libherb/extract.c +148 -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} +22 -17
  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 +155 -54
  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/string.h +11 -0
  108. package/extension/libherb/include/util.h +6 -3
  109. package/extension/libherb/include/version.h +1 -1
  110. package/extension/libherb/io.c +3 -2
  111. package/extension/libherb/io.h +3 -1
  112. package/extension/libherb/lex_helpers.h +29 -0
  113. package/extension/libherb/lexer.c +42 -30
  114. package/extension/libherb/lexer.h +1 -1
  115. package/extension/libherb/lexer_peek_helpers.c +12 -74
  116. package/extension/libherb/lexer_peek_helpers.h +87 -13
  117. package/extension/libherb/lexer_struct.h +2 -0
  118. package/extension/libherb/location.c +2 -2
  119. package/extension/libherb/location.h +2 -1
  120. package/extension/libherb/main.c +79 -66
  121. package/extension/libherb/parser.c +784 -247
  122. package/extension/libherb/parser.h +27 -2
  123. package/extension/libherb/parser_helpers.c +110 -23
  124. package/extension/libherb/parser_helpers.h +19 -3
  125. package/extension/libherb/parser_match_tags.c +110 -49
  126. package/extension/libherb/pretty_print.c +29 -24
  127. package/extension/libherb/pretty_print.h +10 -5
  128. package/extension/libherb/prism_context.h +45 -0
  129. package/extension/libherb/prism_helpers.c +30 -27
  130. package/extension/libherb/prism_helpers.h +10 -7
  131. package/extension/libherb/prism_serialized.h +12 -0
  132. package/extension/libherb/ruby_parser.c +2 -0
  133. package/extension/libherb/token.c +151 -66
  134. package/extension/libherb/token.h +16 -4
  135. package/extension/libherb/token_matchers.c +0 -1
  136. package/extension/libherb/token_struct.h +10 -3
  137. package/extension/libherb/utf8.c +7 -6
  138. package/extension/libherb/utf8.h +2 -1
  139. package/extension/libherb/util/hb_allocator.c +341 -0
  140. package/extension/libherb/util/hb_allocator.h +78 -0
  141. package/extension/libherb/util/hb_arena.c +81 -56
  142. package/extension/libherb/util/hb_arena.h +6 -1
  143. package/extension/libherb/util/hb_arena_debug.c +32 -17
  144. package/extension/libherb/util/hb_arena_debug.h +12 -1
  145. package/extension/libherb/util/hb_array.c +30 -15
  146. package/extension/libherb/util/hb_array.h +7 -3
  147. package/extension/libherb/util/hb_buffer.c +17 -21
  148. package/extension/libherb/util/hb_buffer.h +6 -4
  149. package/extension/libherb/util/hb_foreach.h +79 -0
  150. package/extension/libherb/util/hb_narray.c +22 -7
  151. package/extension/libherb/util/hb_narray.h +8 -4
  152. package/extension/libherb/util/hb_string.c +49 -35
  153. package/extension/libherb/util/hb_string.h +56 -9
  154. package/extension/libherb/util/string.h +11 -0
  155. package/extension/libherb/util.c +21 -11
  156. package/extension/libherb/util.h +6 -3
  157. package/extension/libherb/version.h +1 -1
  158. package/extension/libherb/visitor.c +48 -1
  159. package/extension/nodes.cpp +451 -6
  160. package/extension/nodes.h +8 -1
  161. package/extension/prism/include/prism/ast.h +4 -4
  162. package/extension/prism/include/prism/version.h +2 -2
  163. package/extension/prism/src/prism.c +1 -1
  164. package/package.json +12 -8
  165. package/src/node-backend.ts +11 -1
  166. package/dist/types/index-cjs.d.cts +0 -1
  167. package/extension/libherb/analyze.c +0 -1594
  168. package/extension/libherb/element_source.c +0 -12
  169. package/extension/libherb/include/util/hb_system.h +0 -9
  170. package/extension/libherb/util/hb_system.c +0 -30
  171. package/extension/libherb/util/hb_system.h +0 -9
  172. package/src/index-cjs.cts +0 -22
  173. /package/dist/types/{index-esm.d.mts → index.d.ts} +0 -0
  174. /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.9/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,635 +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
+ );
136
+
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);
152
139
 
153
- missing_opening_tag_error->closing_tag = token_copy(closing_tag);
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
+ );
173
+
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);
195
177
 
196
- missing_closing_tag_error->opening_tag = token_copy(opening_tag);
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));
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));
248
225
  }
249
226
 
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);
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));
259
229
 
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;
288
- }
289
-
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
- }
293
-
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);
286
+
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);
376
299
 
377
- unclosed_element_error->opening_tag = token_copy(opening_tag);
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);
417
322
 
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);
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
+ );
331
+
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);
491
388
 
492
- missingerb_end_tag_error->keyword = herb_strdup(keyword);
493
- return missingerb_end_tag_error;
389
+ char message[219];
390
+ snprintf(
391
+ message,
392
+ sizeof(message),
393
+ message_template,
394
+ truncated_c_string_0 ? truncated_c_string_0 : ""
395
+ );
396
+
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));
422
+ }
423
+
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; }
428
+
429
+ error_init(&erb_case_with_conditions_error->base, ERB_CASE_WITH_CONDITIONS_ERROR, start, end);
430
+
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);
432
+
433
+ return erb_case_with_conditions_error;
434
+ }
435
+
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));
691
+ }
692
+
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));
512
724
  }
513
725
 
514
- const char* error_type_to_string(ERROR_T* error) {
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) {
515
824
  switch (error->type) {
516
- case UNEXPECTED_ERROR: return "UNEXPECTED_ERROR";
517
- case UNEXPECTED_TOKEN_ERROR: return "UNEXPECTED_TOKEN_ERROR";
518
- case MISSING_OPENING_TAG_ERROR: return "MISSING_OPENING_TAG_ERROR";
519
- case MISSING_CLOSING_TAG_ERROR: return "MISSING_CLOSING_TAG_ERROR";
520
- case TAG_NAMES_MISMATCH_ERROR: return "TAG_NAMES_MISMATCH_ERROR";
521
- case QUOTES_MISMATCH_ERROR: return "QUOTES_MISMATCH_ERROR";
522
- case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VOID_ELEMENT_CLOSING_TAG_ERROR";
523
- case UNCLOSED_ELEMENT_ERROR: return "UNCLOSED_ELEMENT_ERROR";
524
- case RUBY_PARSE_ERROR: return "RUBY_PARSE_ERROR";
525
- case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERB_CONTROL_FLOW_SCOPE_ERROR";
526
- case MISSINGERB_END_TAG_ERROR: return "MISSINGERB_END_TAG_ERROR";
527
- case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: return "ERB_MULTIPLE_BLOCKS_IN_TAG_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");
528
848
  }
529
849
 
530
- return "Unknown error_type_T";
850
+ return hb_string("Unknown error_type_T");
531
851
  }
532
852
 
533
- const char* error_human_type(ERROR_T* error) {
853
+ hb_string_T error_human_type(ERROR_T* error) {
534
854
  switch (error->type) {
535
- case UNEXPECTED_ERROR: return "UnexpectedError";
536
- case UNEXPECTED_TOKEN_ERROR: return "UnexpectedTokenError";
537
- case MISSING_OPENING_TAG_ERROR: return "MissingOpeningTagError";
538
- case MISSING_CLOSING_TAG_ERROR: return "MissingClosingTagError";
539
- case TAG_NAMES_MISMATCH_ERROR: return "TagNamesMismatchError";
540
- case QUOTES_MISMATCH_ERROR: return "QuotesMismatchError";
541
- case VOID_ELEMENT_CLOSING_TAG_ERROR: return "VoidElementClosingTagError";
542
- case UNCLOSED_ELEMENT_ERROR: return "UnclosedElementError";
543
- case RUBY_PARSE_ERROR: return "RubyParseError";
544
- case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERBControlFlowScopeError";
545
- case MISSINGERB_END_TAG_ERROR: return "MissingERBEndTagError";
546
- case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: return "ERBMultipleBlocksInTagError";
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");
547
878
  }
548
879
 
549
- return "Unknown error_type_T";
880
+ return hb_string("Unknown error_type_T");
550
881
  }
551
882
 
552
- void error_free_base_error(ERROR_T* error) {
883
+ void error_free_base_error(ERROR_T* error, hb_allocator_T* allocator) {
553
884
  if (error == NULL) { return; }
554
885
 
555
- if (error->message != NULL) { free(error->message); }
886
+ if (!hb_string_is_null(error->message)) { hb_allocator_dealloc(allocator, error->message.data); }
556
887
 
557
- free(error);
888
+ hb_allocator_dealloc(allocator, error);
558
889
  }
559
890
 
560
- static void error_free_unexpected_error(UNEXPECTED_ERROR_T* unexpected_error) {
561
- if (unexpected_error->description != NULL) { free((char*) unexpected_error->description); }
562
- if (unexpected_error->expected != NULL) { free((char*) unexpected_error->expected); }
563
- 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); }
564
895
 
565
- error_free_base_error(&unexpected_error->base);
896
+ error_free_base_error(&unexpected_error->base, allocator);
566
897
  }
567
898
 
568
- 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) {
569
900
  // token_type_T is part of struct
570
- 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); }
571
902
 
572
- error_free_base_error(&unexpected_token_error->base);
903
+ error_free_base_error(&unexpected_token_error->base, allocator);
573
904
  }
574
905
 
575
- static void error_free_missing_opening_tag_error(MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error) {
576
- 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); }
577
908
 
578
- error_free_base_error(&missing_opening_tag_error->base);
909
+ error_free_base_error(&missing_opening_tag_error->base, allocator);
579
910
  }
580
911
 
581
- static void error_free_missing_closing_tag_error(MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error) {
582
- 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); }
583
914
 
584
- error_free_base_error(&missing_closing_tag_error->base);
915
+ error_free_base_error(&missing_closing_tag_error->base, allocator);
585
916
  }
586
917
 
587
- static void error_free_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error) {
588
- if (tag_names_mismatch_error->opening_tag != NULL) { token_free(tag_names_mismatch_error->opening_tag); }
589
- 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); }
590
921
 
591
- error_free_base_error(&tag_names_mismatch_error->base);
922
+ error_free_base_error(&tag_names_mismatch_error->base, allocator);
592
923
  }
593
924
 
594
- static void error_free_quotes_mismatch_error(QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error) {
595
- if (quotes_mismatch_error->opening_quote != NULL) { token_free(quotes_mismatch_error->opening_quote); }
596
- 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); }
597
929
 
598
- error_free_base_error(&quotes_mismatch_error->base);
930
+ error_free_base_error(&void_element_closing_tag_error->base, allocator);
599
931
  }
600
932
 
601
- static void error_free_void_element_closing_tag_error(VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error) {
602
- if (void_element_closing_tag_error->tag_name != NULL) { token_free(void_element_closing_tag_error->tag_name); }
603
- if (void_element_closing_tag_error->expected != NULL) { free((char*) void_element_closing_tag_error->expected); }
604
- 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); }
605
935
 
606
- error_free_base_error(&void_element_closing_tag_error->base);
936
+ error_free_base_error(&unclosed_element_error->base, allocator);
607
937
  }
608
938
 
609
- static void error_free_unclosed_element_error(UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error) {
610
- 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); }
611
943
 
612
- error_free_base_error(&unclosed_element_error->base);
944
+ error_free_base_error(&ruby_parse_error->base, allocator);
613
945
  }
614
946
 
615
- static void error_free_ruby_parse_error(RUBY_PARSE_ERROR_T* ruby_parse_error) {
616
- if (ruby_parse_error->error_message != NULL) { free((char*) ruby_parse_error->error_message); }
617
- if (ruby_parse_error->diagnostic_id != NULL) { free((char*) ruby_parse_error->diagnostic_id); }
618
- 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); }
619
949
 
620
- error_free_base_error(&ruby_parse_error->base);
950
+ error_free_base_error(&erb_control_flow_scope_error->base, allocator);
621
951
  }
622
952
 
623
- static void error_free_erb_control_flow_scope_error(ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error) {
624
- 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); }
625
955
 
626
- error_free_base_error(&erb_control_flow_scope_error->base);
956
+ error_free_base_error(&missing_erb_end_tag_error->base, allocator);
627
957
  }
628
958
 
629
- static void error_free_missingerb_end_tag_error(MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error) {
630
- 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 */
631
961
 
632
- error_free_base_error(&missingerb_end_tag_error->base);
962
+ error_free_base_error(&erb_multiple_blocks_in_tag_error->base, allocator);
633
963
  }
634
964
 
635
- static void error_free_erb_multiple_blocks_in_tag_error(ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error) {
636
- /* 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 */
967
+
968
+ error_free_base_error(&erb_case_with_conditions_error->base, allocator);
969
+ }
970
+
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
637
974
 
638
- error_free_base_error(&erb_multiple_blocks_in_tag_error->base);
975
+ error_free_base_error(&conditional_element_multiple_tags_error->base, allocator);
639
976
  }
640
977
 
641
- void error_free(ERROR_T* error) {
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
1043
+
1044
+ error_free_base_error(&nested_erb_tag_error->base, allocator);
1045
+ }
1046
+
1047
+ void error_free(ERROR_T* error, hb_allocator_T* allocator) {
642
1048
  if (!error) { return; }
643
1049
 
644
1050
  switch (error->type) {
645
- case UNEXPECTED_ERROR: error_free_unexpected_error((UNEXPECTED_ERROR_T*) error); break;
646
- case UNEXPECTED_TOKEN_ERROR: error_free_unexpected_token_error((UNEXPECTED_TOKEN_ERROR_T*) error); break;
647
- case MISSING_OPENING_TAG_ERROR: error_free_missing_opening_tag_error((MISSING_OPENING_TAG_ERROR_T*) error); break;
648
- case MISSING_CLOSING_TAG_ERROR: error_free_missing_closing_tag_error((MISSING_CLOSING_TAG_ERROR_T*) error); break;
649
- case TAG_NAMES_MISMATCH_ERROR: error_free_tag_names_mismatch_error((TAG_NAMES_MISMATCH_ERROR_T*) error); break;
650
- case QUOTES_MISMATCH_ERROR: error_free_quotes_mismatch_error((QUOTES_MISMATCH_ERROR_T*) error); break;
651
- case VOID_ELEMENT_CLOSING_TAG_ERROR: error_free_void_element_closing_tag_error((VOID_ELEMENT_CLOSING_TAG_ERROR_T*) error); break;
652
- case UNCLOSED_ELEMENT_ERROR: error_free_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error); break;
653
- case RUBY_PARSE_ERROR: error_free_ruby_parse_error((RUBY_PARSE_ERROR_T*) error); break;
654
- case ERB_CONTROL_FLOW_SCOPE_ERROR: error_free_erb_control_flow_scope_error((ERB_CONTROL_FLOW_SCOPE_ERROR_T*) error); break;
655
- case MISSINGERB_END_TAG_ERROR: error_free_missingerb_end_tag_error((MISSINGERB_END_TAG_ERROR_T*) error); break;
656
- case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: error_free_erb_multiple_blocks_in_tag_error((ERB_MULTIPLE_BLOCKS_IN_TAG_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;
657
1074
  }
658
1075
  }
659
1076
 
1077
+ #ifndef HERB_EXCLUDE_PRETTYPRINT
1078
+
660
1079
  void error_pretty_print_array(
661
1080
  const char* name, hb_array_T* array, const size_t indent, const size_t relative_indent, const bool last_property,
662
1081
  hb_buffer_T* buffer
@@ -705,30 +1124,30 @@ static void error_pretty_print_unexpected_error(UNEXPECTED_ERROR_T* error, const
705
1124
  if (!error) { return; }
706
1125
 
707
1126
  hb_buffer_append(buffer, "@ ");
708
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1127
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
709
1128
  hb_buffer_append(buffer, " ");
710
1129
 
711
1130
  pretty_print_location(error->base.location, buffer);
712
1131
  hb_buffer_append(buffer, "\n");
713
1132
 
714
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
715
- pretty_print_quoted_property(hb_string("description"), hb_string(error->description), indent, relative_indent, false, buffer);
716
- pretty_print_quoted_property(hb_string("expected"), hb_string(error->expected), indent, relative_indent, false, buffer);
717
- 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);
718
1137
  }
719
1138
 
720
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) {
721
1140
  if (!error) { return; }
722
1141
 
723
1142
  hb_buffer_append(buffer, "@ ");
724
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1143
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
725
1144
  hb_buffer_append(buffer, " ");
726
1145
 
727
1146
  pretty_print_location(error->base.location, buffer);
728
1147
  hb_buffer_append(buffer, "\n");
729
1148
 
730
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
731
- 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);
732
1151
  pretty_print_token_property(error->found, hb_string("found"), indent, relative_indent, true, buffer);
733
1152
  }
734
1153
 
@@ -736,13 +1155,13 @@ static void error_pretty_print_missing_opening_tag_error(MISSING_OPENING_TAG_ERR
736
1155
  if (!error) { return; }
737
1156
 
738
1157
  hb_buffer_append(buffer, "@ ");
739
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1158
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
740
1159
  hb_buffer_append(buffer, " ");
741
1160
 
742
1161
  pretty_print_location(error->base.location, buffer);
743
1162
  hb_buffer_append(buffer, "\n");
744
1163
 
745
- 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);
746
1165
  pretty_print_token_property(error->closing_tag, hb_string("closing_tag"), indent, relative_indent, true, buffer);
747
1166
  }
748
1167
 
@@ -750,13 +1169,13 @@ static void error_pretty_print_missing_closing_tag_error(MISSING_CLOSING_TAG_ERR
750
1169
  if (!error) { return; }
751
1170
 
752
1171
  hb_buffer_append(buffer, "@ ");
753
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1172
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
754
1173
  hb_buffer_append(buffer, " ");
755
1174
 
756
1175
  pretty_print_location(error->base.location, buffer);
757
1176
  hb_buffer_append(buffer, "\n");
758
1177
 
759
- 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);
760
1179
  pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, true, buffer);
761
1180
  }
762
1181
 
@@ -764,117 +1183,278 @@ static void error_pretty_print_tag_names_mismatch_error(TAG_NAMES_MISMATCH_ERROR
764
1183
  if (!error) { return; }
765
1184
 
766
1185
  hb_buffer_append(buffer, "@ ");
767
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1186
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
768
1187
  hb_buffer_append(buffer, " ");
769
1188
 
770
1189
  pretty_print_location(error->base.location, buffer);
771
1190
  hb_buffer_append(buffer, "\n");
772
1191
 
773
- 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);
774
1193
  pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), indent, relative_indent, false, buffer);
775
1194
  pretty_print_token_property(error->closing_tag, hb_string("closing_tag"), indent, relative_indent, true, buffer);
776
1195
  }
777
1196
 
778
- 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) {
1198
+ if (!error) { return; }
1199
+
1200
+ hb_buffer_append(buffer, "@ ");
1201
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1202
+ hb_buffer_append(buffer, " ");
1203
+
1204
+ pretty_print_location(error->base.location, buffer);
1205
+ hb_buffer_append(buffer, "\n");
1206
+
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);
1211
+ }
1212
+
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) {
779
1214
  if (!error) { return; }
780
1215
 
781
1216
  hb_buffer_append(buffer, "@ ");
782
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1217
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
783
1218
  hb_buffer_append(buffer, " ");
784
1219
 
785
1220
  pretty_print_location(error->base.location, buffer);
786
1221
  hb_buffer_append(buffer, "\n");
787
1222
 
788
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
789
- pretty_print_token_property(error->opening_quote, hb_string("opening_quote"), indent, relative_indent, false, buffer);
790
- pretty_print_token_property(error->closing_quote, hb_string("closing_quote"), 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);
791
1225
  }
792
1226
 
793
- 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) {
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) {
794
1228
  if (!error) { return; }
795
1229
 
796
1230
  hb_buffer_append(buffer, "@ ");
797
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1231
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
798
1232
  hb_buffer_append(buffer, " ");
799
1233
 
800
1234
  pretty_print_location(error->base.location, buffer);
801
1235
  hb_buffer_append(buffer, "\n");
802
1236
 
803
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
804
- pretty_print_token_property(error->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
805
- pretty_print_quoted_property(hb_string("expected"), hb_string(error->expected), indent, relative_indent, false, buffer);
806
- pretty_print_quoted_property(hb_string("found"), hb_string(error->found), 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);
807
1241
  }
808
1242
 
809
- 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) {
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) {
810
1244
  if (!error) { return; }
811
1245
 
812
1246
  hb_buffer_append(buffer, "@ ");
813
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1247
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
814
1248
  hb_buffer_append(buffer, " ");
815
1249
 
816
1250
  pretty_print_location(error->base.location, buffer);
817
1251
  hb_buffer_append(buffer, "\n");
818
1252
 
819
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
820
- pretty_print_token_property(error->opening_tag, hb_string("opening_tag"), 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);
821
1255
  }
822
1256
 
823
- 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) {
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) {
824
1258
  if (!error) { return; }
825
1259
 
826
1260
  hb_buffer_append(buffer, "@ ");
827
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1261
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
828
1262
  hb_buffer_append(buffer, " ");
829
1263
 
830
1264
  pretty_print_location(error->base.location, buffer);
831
1265
  hb_buffer_append(buffer, "\n");
832
1266
 
833
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
834
- pretty_print_quoted_property(hb_string("error_message"), hb_string(error->error_message), indent, relative_indent, false, buffer);
835
- pretty_print_quoted_property(hb_string("diagnostic_id"), hb_string(error->diagnostic_id), indent, relative_indent, false, buffer);
836
- pretty_print_quoted_property(hb_string("level"), hb_string(error->level), 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);
837
1269
  }
838
1270
 
839
- 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) {
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) {
840
1272
  if (!error) { return; }
841
1273
 
842
1274
  hb_buffer_append(buffer, "@ ");
843
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1275
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
844
1276
  hb_buffer_append(buffer, " ");
845
1277
 
846
1278
  pretty_print_location(error->base.location, buffer);
847
1279
  hb_buffer_append(buffer, "\n");
848
1280
 
849
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
850
- 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);
851
1282
  }
852
1283
 
853
- 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) {
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) {
854
1285
  if (!error) { return; }
855
1286
 
856
1287
  hb_buffer_append(buffer, "@ ");
857
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1288
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
858
1289
  hb_buffer_append(buffer, " ");
859
1290
 
860
1291
  pretty_print_location(error->base.location, buffer);
861
1292
  hb_buffer_append(buffer, "\n");
862
1293
 
863
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, false, buffer);
864
- pretty_print_quoted_property(hb_string("keyword"), hb_string(error->keyword), indent, relative_indent, true, buffer);
1294
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, true, buffer);
865
1295
  }
866
1296
 
867
- 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) {
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) {
1298
+ if (!error) { return; }
1299
+
1300
+ hb_buffer_append(buffer, "@ ");
1301
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1302
+ hb_buffer_append(buffer, " ");
1303
+
1304
+ pretty_print_location(error->base.location, buffer);
1305
+ hb_buffer_append(buffer, "\n");
1306
+
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) {
868
1313
  if (!error) { return; }
869
1314
 
870
1315
  hb_buffer_append(buffer, "@ ");
871
- hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
1316
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
872
1317
  hb_buffer_append(buffer, " ");
873
1318
 
874
1319
  pretty_print_location(error->base.location, buffer);
875
1320
  hb_buffer_append(buffer, "\n");
876
1321
 
877
- pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, true, buffer);
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);
878
1458
  }
879
1459
 
880
1460
  void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
@@ -886,12 +1466,25 @@ void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relati
886
1466
  case MISSING_OPENING_TAG_ERROR: error_pretty_print_missing_opening_tag_error((MISSING_OPENING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
887
1467
  case MISSING_CLOSING_TAG_ERROR: error_pretty_print_missing_closing_tag_error((MISSING_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
888
1468
  case TAG_NAMES_MISMATCH_ERROR: error_pretty_print_tag_names_mismatch_error((TAG_NAMES_MISMATCH_ERROR_T*) error, indent, relative_indent, buffer); break;
889
- case QUOTES_MISMATCH_ERROR: error_pretty_print_quotes_mismatch_error((QUOTES_MISMATCH_ERROR_T*) error, indent, relative_indent, buffer); break;
890
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;
891
1470
  case UNCLOSED_ELEMENT_ERROR: error_pretty_print_unclosed_element_error((UNCLOSED_ELEMENT_ERROR_T*) error, indent, relative_indent, buffer); break;
892
1471
  case RUBY_PARSE_ERROR: error_pretty_print_ruby_parse_error((RUBY_PARSE_ERROR_T*) error, indent, relative_indent, buffer); break;
893
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;
894
- 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;
895
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;
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;
896
1487
  }
897
1488
  }
1489
+
1490
+ #endif