herb 0.7.2-arm-linux-musl → 0.7.4-arm-linux-musl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +2 -0
- data/README.md +1 -1
- data/Rakefile +46 -1
- data/config.yml +714 -0
- data/ext/herb/extconf.rb +2 -1
- data/ext/herb/nodes.c +1 -1
- data/herb.gemspec +3 -0
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/engine.rb +8 -1
- data/lib/herb/version.rb +1 -1
- data/src/analyze.c +5 -9
- data/src/analyze_helpers.c +17 -6
- data/src/herb.c +2 -2
- data/src/include/parser.h +2 -2
- data/src/include/pretty_print.h +1 -1
- data/src/include/version.h +1 -1
- data/src/parser.c +3 -2
- data/src/pretty_print.c +1 -1
- data/templates/ext/herb/error_helpers.c.erb +85 -0
- data/templates/ext/herb/error_helpers.h.erb +12 -0
- data/templates/ext/herb/nodes.c.erb +90 -0
- data/templates/ext/herb/nodes.h.erb +9 -0
- data/templates/javascript/packages/core/src/errors.ts.erb +193 -0
- data/templates/javascript/packages/core/src/node-type-guards.ts.erb +325 -0
- data/templates/javascript/packages/core/src/nodes.ts.erb +414 -0
- data/templates/javascript/packages/core/src/visitor.ts.erb +29 -0
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +113 -0
- data/templates/javascript/packages/node/extension/error_helpers.h.erb +17 -0
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +111 -0
- data/templates/javascript/packages/node/extension/nodes.h.erb +17 -0
- data/templates/lib/herb/ast/nodes.rb.erb +117 -0
- data/templates/lib/herb/errors.rb.erb +106 -0
- data/templates/lib/herb/visitor.rb.erb +28 -0
- data/templates/sig/serialized_ast_errors.rbs.erb +10 -0
- data/templates/sig/serialized_ast_nodes.rbs.erb +10 -0
- data/templates/src/ast_nodes.c.erb +145 -0
- data/templates/src/ast_pretty_print.c.erb +97 -0
- data/templates/src/errors.c.erb +245 -0
- data/templates/src/include/ast_nodes.h.erb +46 -0
- data/templates/src/include/ast_pretty_print.h.erb +14 -0
- data/templates/src/include/errors.h.erb +58 -0
- data/templates/src/visitor.c.erb +47 -0
- data/templates/template.rb +406 -0
- data/templates/wasm/error_helpers.cpp.erb +93 -0
- data/templates/wasm/error_helpers.h.erb +15 -0
- data/templates/wasm/nodes.cpp.erb +79 -0
- data/templates/wasm/nodes.h.erb +15 -0
- data/vendor/prism/Rakefile +75 -0
- data/vendor/prism/config.yml +4713 -0
- data/vendor/prism/include/prism/ast.h +8190 -0
- data/vendor/prism/include/prism/defines.h +260 -0
- data/vendor/prism/include/prism/diagnostic.h +455 -0
- data/vendor/prism/include/prism/encoding.h +283 -0
- data/vendor/prism/include/prism/node.h +129 -0
- data/vendor/prism/include/prism/options.h +482 -0
- data/vendor/prism/include/prism/pack.h +163 -0
- data/vendor/prism/include/prism/parser.h +933 -0
- data/vendor/prism/include/prism/prettyprint.h +34 -0
- data/vendor/prism/include/prism/regexp.h +43 -0
- data/vendor/prism/include/prism/static_literals.h +121 -0
- data/vendor/prism/include/prism/util/pm_buffer.h +236 -0
- data/vendor/prism/include/prism/util/pm_char.h +204 -0
- data/vendor/prism/include/prism/util/pm_constant_pool.h +218 -0
- data/vendor/prism/include/prism/util/pm_integer.h +130 -0
- data/vendor/prism/include/prism/util/pm_list.h +103 -0
- data/vendor/prism/include/prism/util/pm_memchr.h +29 -0
- data/vendor/prism/include/prism/util/pm_newline_list.h +113 -0
- data/vendor/prism/include/prism/util/pm_string.h +200 -0
- data/vendor/prism/include/prism/util/pm_strncasecmp.h +32 -0
- data/vendor/prism/include/prism/util/pm_strpbrk.h +46 -0
- data/vendor/prism/include/prism/version.h +29 -0
- data/vendor/prism/include/prism.h +408 -0
- data/vendor/prism/src/diagnostic.c +848 -0
- data/vendor/prism/src/encoding.c +5235 -0
- data/vendor/prism/src/node.c +8676 -0
- data/vendor/prism/src/options.c +328 -0
- data/vendor/prism/src/pack.c +509 -0
- data/vendor/prism/src/prettyprint.c +8941 -0
- data/vendor/prism/src/prism.c +23302 -0
- data/vendor/prism/src/regexp.c +790 -0
- data/vendor/prism/src/serialize.c +2268 -0
- data/vendor/prism/src/static_literals.c +617 -0
- data/vendor/prism/src/token_type.c +703 -0
- data/vendor/prism/src/util/pm_buffer.c +357 -0
- data/vendor/prism/src/util/pm_char.c +318 -0
- data/vendor/prism/src/util/pm_constant_pool.c +342 -0
- data/vendor/prism/src/util/pm_integer.c +670 -0
- data/vendor/prism/src/util/pm_list.c +49 -0
- data/vendor/prism/src/util/pm_memchr.c +35 -0
- data/vendor/prism/src/util/pm_newline_list.c +125 -0
- data/vendor/prism/src/util/pm_string.c +383 -0
- data/vendor/prism/src/util/pm_strncasecmp.c +36 -0
- data/vendor/prism/src/util/pm_strpbrk.c +206 -0
- data/vendor/prism/templates/ext/prism/api_node.c.erb +282 -0
- data/vendor/prism/templates/include/prism/ast.h.erb +226 -0
- data/vendor/prism/templates/include/prism/diagnostic.h.erb +130 -0
- data/vendor/prism/templates/java/org/prism/AbstractNodeVisitor.java.erb +22 -0
- data/vendor/prism/templates/java/org/prism/Loader.java.erb +434 -0
- data/vendor/prism/templates/java/org/prism/Nodes.java.erb +403 -0
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +448 -0
- data/vendor/prism/templates/javascript/src/nodes.js.erb +197 -0
- data/vendor/prism/templates/javascript/src/visitor.js.erb +78 -0
- data/vendor/prism/templates/lib/prism/compiler.rb.erb +43 -0
- data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +103 -0
- data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +189 -0
- data/vendor/prism/templates/lib/prism/dsl.rb.erb +133 -0
- data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +131 -0
- data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +19 -0
- data/vendor/prism/templates/lib/prism/node.rb.erb +515 -0
- data/vendor/prism/templates/lib/prism/reflection.rb.erb +136 -0
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +602 -0
- data/vendor/prism/templates/lib/prism/visitor.rb.erb +55 -0
- data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +68 -0
- data/vendor/prism/templates/rbi/prism/node.rbi.erb +164 -0
- data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +18 -0
- data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +45 -0
- data/vendor/prism/templates/sig/prism/dsl.rbs.erb +31 -0
- data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +7 -0
- data/vendor/prism/templates/sig/prism/node.rbs.erb +132 -0
- data/vendor/prism/templates/sig/prism/visitor.rbs.erb +17 -0
- data/vendor/prism/templates/sig/prism.rbs.erb +89 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +523 -0
- data/vendor/prism/templates/src/node.c.erb +333 -0
- data/vendor/prism/templates/src/prettyprint.c.erb +166 -0
- data/vendor/prism/templates/src/serialize.c.erb +406 -0
- data/vendor/prism/templates/src/token_type.c.erb +369 -0
- data/vendor/prism/templates/template.rb +689 -0
- metadata +112 -2
@@ -0,0 +1,357 @@
|
|
1
|
+
#include "prism/util/pm_buffer.h"
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Return the size of the pm_buffer_t struct.
|
5
|
+
*/
|
6
|
+
size_t
|
7
|
+
pm_buffer_sizeof(void) {
|
8
|
+
return sizeof(pm_buffer_t);
|
9
|
+
}
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Initialize a pm_buffer_t with the given capacity.
|
13
|
+
*/
|
14
|
+
bool
|
15
|
+
pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity) {
|
16
|
+
buffer->length = 0;
|
17
|
+
buffer->capacity = capacity;
|
18
|
+
|
19
|
+
buffer->value = (char *) xmalloc(capacity);
|
20
|
+
return buffer->value != NULL;
|
21
|
+
}
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Initialize a pm_buffer_t with its default values.
|
25
|
+
*/
|
26
|
+
bool
|
27
|
+
pm_buffer_init(pm_buffer_t *buffer) {
|
28
|
+
return pm_buffer_init_capacity(buffer, 1024);
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Return the value of the buffer.
|
33
|
+
*/
|
34
|
+
char *
|
35
|
+
pm_buffer_value(const pm_buffer_t *buffer) {
|
36
|
+
return buffer->value;
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Return the length of the buffer.
|
41
|
+
*/
|
42
|
+
size_t
|
43
|
+
pm_buffer_length(const pm_buffer_t *buffer) {
|
44
|
+
return buffer->length;
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Append the given amount of space to the buffer.
|
49
|
+
*/
|
50
|
+
static inline bool
|
51
|
+
pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
|
52
|
+
size_t next_length = buffer->length + length;
|
53
|
+
|
54
|
+
if (next_length > buffer->capacity) {
|
55
|
+
if (buffer->capacity == 0) {
|
56
|
+
buffer->capacity = 1;
|
57
|
+
}
|
58
|
+
|
59
|
+
while (next_length > buffer->capacity) {
|
60
|
+
buffer->capacity *= 2;
|
61
|
+
}
|
62
|
+
|
63
|
+
buffer->value = xrealloc(buffer->value, buffer->capacity);
|
64
|
+
if (buffer->value == NULL) return false;
|
65
|
+
}
|
66
|
+
|
67
|
+
buffer->length = next_length;
|
68
|
+
return true;
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Append a generic pointer to memory to the buffer.
|
73
|
+
*/
|
74
|
+
static inline void
|
75
|
+
pm_buffer_append(pm_buffer_t *buffer, const void *source, size_t length) {
|
76
|
+
size_t cursor = buffer->length;
|
77
|
+
if (pm_buffer_append_length(buffer, length)) {
|
78
|
+
memcpy(buffer->value + cursor, source, length);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* Append the given amount of space as zeroes to the buffer.
|
84
|
+
*/
|
85
|
+
void
|
86
|
+
pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length) {
|
87
|
+
size_t cursor = buffer->length;
|
88
|
+
if (pm_buffer_append_length(buffer, length)) {
|
89
|
+
memset(buffer->value + cursor, 0, length);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
* Append a formatted string to the buffer.
|
95
|
+
*/
|
96
|
+
void
|
97
|
+
pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) {
|
98
|
+
va_list arguments;
|
99
|
+
va_start(arguments, format);
|
100
|
+
int result = vsnprintf(NULL, 0, format, arguments);
|
101
|
+
va_end(arguments);
|
102
|
+
|
103
|
+
if (result < 0) return;
|
104
|
+
size_t length = (size_t) (result + 1);
|
105
|
+
|
106
|
+
size_t cursor = buffer->length;
|
107
|
+
if (pm_buffer_append_length(buffer, length)) {
|
108
|
+
va_start(arguments, format);
|
109
|
+
vsnprintf(buffer->value + cursor, length, format, arguments);
|
110
|
+
va_end(arguments);
|
111
|
+
buffer->length--;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Append a string to the buffer.
|
117
|
+
*/
|
118
|
+
void
|
119
|
+
pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length) {
|
120
|
+
pm_buffer_append(buffer, value, length);
|
121
|
+
}
|
122
|
+
|
123
|
+
/**
|
124
|
+
* Append a list of bytes to the buffer.
|
125
|
+
*/
|
126
|
+
void
|
127
|
+
pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length) {
|
128
|
+
pm_buffer_append(buffer, (const char *) value, length);
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Append a single byte to the buffer.
|
133
|
+
*/
|
134
|
+
void
|
135
|
+
pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value) {
|
136
|
+
const void *source = &value;
|
137
|
+
pm_buffer_append(buffer, source, sizeof(uint8_t));
|
138
|
+
}
|
139
|
+
|
140
|
+
/**
|
141
|
+
* Append a 32-bit unsigned integer to the buffer as a variable-length integer.
|
142
|
+
*/
|
143
|
+
void
|
144
|
+
pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value) {
|
145
|
+
if (value < 128) {
|
146
|
+
pm_buffer_append_byte(buffer, (uint8_t) value);
|
147
|
+
} else {
|
148
|
+
uint32_t n = value;
|
149
|
+
while (n >= 128) {
|
150
|
+
pm_buffer_append_byte(buffer, (uint8_t) (n | 128));
|
151
|
+
n >>= 7;
|
152
|
+
}
|
153
|
+
pm_buffer_append_byte(buffer, (uint8_t) n);
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Append a 32-bit signed integer to the buffer as a variable-length integer.
|
159
|
+
*/
|
160
|
+
void
|
161
|
+
pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value) {
|
162
|
+
uint32_t unsigned_int = ((uint32_t)(value) << 1) ^ ((uint32_t)(value >> 31));
|
163
|
+
pm_buffer_append_varuint(buffer, unsigned_int);
|
164
|
+
}
|
165
|
+
|
166
|
+
/**
|
167
|
+
* Append a double to the buffer.
|
168
|
+
*/
|
169
|
+
void
|
170
|
+
pm_buffer_append_double(pm_buffer_t *buffer, double value) {
|
171
|
+
const void *source = &value;
|
172
|
+
pm_buffer_append(buffer, source, sizeof(double));
|
173
|
+
}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Append a unicode codepoint to the buffer.
|
177
|
+
*/
|
178
|
+
bool
|
179
|
+
pm_buffer_append_unicode_codepoint(pm_buffer_t *buffer, uint32_t value) {
|
180
|
+
if (value <= 0x7F) {
|
181
|
+
pm_buffer_append_byte(buffer, (uint8_t) value); // 0xxxxxxx
|
182
|
+
return true;
|
183
|
+
} else if (value <= 0x7FF) {
|
184
|
+
uint8_t bytes[] = {
|
185
|
+
(uint8_t) (0xC0 | ((value >> 6) & 0x3F)), // 110xxxxx
|
186
|
+
(uint8_t) (0x80 | (value & 0x3F)) // 10xxxxxx
|
187
|
+
};
|
188
|
+
|
189
|
+
pm_buffer_append_bytes(buffer, bytes, 2);
|
190
|
+
return true;
|
191
|
+
} else if (value <= 0xFFFF) {
|
192
|
+
uint8_t bytes[] = {
|
193
|
+
(uint8_t) (0xE0 | ((value >> 12) & 0x3F)), // 1110xxxx
|
194
|
+
(uint8_t) (0x80 | ((value >> 6) & 0x3F)), // 10xxxxxx
|
195
|
+
(uint8_t) (0x80 | (value & 0x3F)) // 10xxxxxx
|
196
|
+
};
|
197
|
+
|
198
|
+
pm_buffer_append_bytes(buffer, bytes, 3);
|
199
|
+
return true;
|
200
|
+
} else if (value <= 0x10FFFF) {
|
201
|
+
uint8_t bytes[] = {
|
202
|
+
(uint8_t) (0xF0 | ((value >> 18) & 0x3F)), // 11110xxx
|
203
|
+
(uint8_t) (0x80 | ((value >> 12) & 0x3F)), // 10xxxxxx
|
204
|
+
(uint8_t) (0x80 | ((value >> 6) & 0x3F)), // 10xxxxxx
|
205
|
+
(uint8_t) (0x80 | (value & 0x3F)) // 10xxxxxx
|
206
|
+
};
|
207
|
+
|
208
|
+
pm_buffer_append_bytes(buffer, bytes, 4);
|
209
|
+
return true;
|
210
|
+
} else {
|
211
|
+
return false;
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
/**
|
216
|
+
* Append a slice of source code to the buffer.
|
217
|
+
*/
|
218
|
+
void
|
219
|
+
pm_buffer_append_source(pm_buffer_t *buffer, const uint8_t *source, size_t length, pm_buffer_escaping_t escaping) {
|
220
|
+
for (size_t index = 0; index < length; index++) {
|
221
|
+
const uint8_t byte = source[index];
|
222
|
+
|
223
|
+
if ((byte <= 0x06) || (byte >= 0x0E && byte <= 0x1F) || (byte >= 0x7F)) {
|
224
|
+
if (escaping == PM_BUFFER_ESCAPING_RUBY) {
|
225
|
+
pm_buffer_append_format(buffer, "\\x%02X", byte);
|
226
|
+
} else {
|
227
|
+
pm_buffer_append_format(buffer, "\\u%04X", byte);
|
228
|
+
}
|
229
|
+
} else {
|
230
|
+
switch (byte) {
|
231
|
+
case '\a':
|
232
|
+
if (escaping == PM_BUFFER_ESCAPING_RUBY) {
|
233
|
+
pm_buffer_append_string(buffer, "\\a", 2);
|
234
|
+
} else {
|
235
|
+
pm_buffer_append_format(buffer, "\\u%04X", byte);
|
236
|
+
}
|
237
|
+
break;
|
238
|
+
case '\b':
|
239
|
+
pm_buffer_append_string(buffer, "\\b", 2);
|
240
|
+
break;
|
241
|
+
case '\t':
|
242
|
+
pm_buffer_append_string(buffer, "\\t", 2);
|
243
|
+
break;
|
244
|
+
case '\n':
|
245
|
+
pm_buffer_append_string(buffer, "\\n", 2);
|
246
|
+
break;
|
247
|
+
case '\v':
|
248
|
+
if (escaping == PM_BUFFER_ESCAPING_RUBY) {
|
249
|
+
pm_buffer_append_string(buffer, "\\v", 2);
|
250
|
+
} else {
|
251
|
+
pm_buffer_append_format(buffer, "\\u%04X", byte);
|
252
|
+
}
|
253
|
+
break;
|
254
|
+
case '\f':
|
255
|
+
pm_buffer_append_string(buffer, "\\f", 2);
|
256
|
+
break;
|
257
|
+
case '\r':
|
258
|
+
pm_buffer_append_string(buffer, "\\r", 2);
|
259
|
+
break;
|
260
|
+
case '"':
|
261
|
+
pm_buffer_append_string(buffer, "\\\"", 2);
|
262
|
+
break;
|
263
|
+
case '#': {
|
264
|
+
if (escaping == PM_BUFFER_ESCAPING_RUBY && index + 1 < length) {
|
265
|
+
const uint8_t next_byte = source[index + 1];
|
266
|
+
if (next_byte == '{' || next_byte == '@' || next_byte == '$') {
|
267
|
+
pm_buffer_append_byte(buffer, '\\');
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
pm_buffer_append_byte(buffer, '#');
|
272
|
+
break;
|
273
|
+
}
|
274
|
+
case '\\':
|
275
|
+
pm_buffer_append_string(buffer, "\\\\", 2);
|
276
|
+
break;
|
277
|
+
default:
|
278
|
+
pm_buffer_append_byte(buffer, byte);
|
279
|
+
break;
|
280
|
+
}
|
281
|
+
}
|
282
|
+
}
|
283
|
+
}
|
284
|
+
|
285
|
+
/**
|
286
|
+
* Prepend the given string to the buffer.
|
287
|
+
*/
|
288
|
+
void
|
289
|
+
pm_buffer_prepend_string(pm_buffer_t *buffer, const char *value, size_t length) {
|
290
|
+
size_t cursor = buffer->length;
|
291
|
+
if (pm_buffer_append_length(buffer, length)) {
|
292
|
+
memmove(buffer->value + length, buffer->value, cursor);
|
293
|
+
memcpy(buffer->value, value, length);
|
294
|
+
}
|
295
|
+
}
|
296
|
+
|
297
|
+
/**
|
298
|
+
* Concatenate one buffer onto another.
|
299
|
+
*/
|
300
|
+
void
|
301
|
+
pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source) {
|
302
|
+
if (source->length > 0) {
|
303
|
+
pm_buffer_append(destination, source->value, source->length);
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
/**
|
308
|
+
* Clear the buffer by reducing its size to 0. This does not free the allocated
|
309
|
+
* memory, but it does allow the buffer to be reused.
|
310
|
+
*/
|
311
|
+
void
|
312
|
+
pm_buffer_clear(pm_buffer_t *buffer) {
|
313
|
+
buffer->length = 0;
|
314
|
+
}
|
315
|
+
|
316
|
+
/**
|
317
|
+
* Strip the whitespace from the end of the buffer.
|
318
|
+
*/
|
319
|
+
void
|
320
|
+
pm_buffer_rstrip(pm_buffer_t *buffer) {
|
321
|
+
while (buffer->length > 0 && pm_char_is_whitespace((uint8_t) buffer->value[buffer->length - 1])) {
|
322
|
+
buffer->length--;
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
326
|
+
/**
|
327
|
+
* Checks if the buffer includes the given value.
|
328
|
+
*/
|
329
|
+
size_t
|
330
|
+
pm_buffer_index(const pm_buffer_t *buffer, char value) {
|
331
|
+
const char *first = memchr(buffer->value, value, buffer->length);
|
332
|
+
return (first == NULL) ? SIZE_MAX : (size_t) (first - buffer->value);
|
333
|
+
}
|
334
|
+
|
335
|
+
/**
|
336
|
+
* Insert the given string into the buffer at the given index.
|
337
|
+
*/
|
338
|
+
void
|
339
|
+
pm_buffer_insert(pm_buffer_t *buffer, size_t index, const char *value, size_t length) {
|
340
|
+
assert(index <= buffer->length);
|
341
|
+
|
342
|
+
if (index == buffer->length) {
|
343
|
+
pm_buffer_append_string(buffer, value, length);
|
344
|
+
} else {
|
345
|
+
pm_buffer_append_zeroes(buffer, length);
|
346
|
+
memmove(buffer->value + index + length, buffer->value + index, buffer->length - length - index);
|
347
|
+
memcpy(buffer->value + index, value, length);
|
348
|
+
}
|
349
|
+
}
|
350
|
+
|
351
|
+
/**
|
352
|
+
* Free the memory associated with the buffer.
|
353
|
+
*/
|
354
|
+
void
|
355
|
+
pm_buffer_free(pm_buffer_t *buffer) {
|
356
|
+
xfree(buffer->value);
|
357
|
+
}
|
@@ -0,0 +1,318 @@
|
|
1
|
+
#include "prism/util/pm_char.h"
|
2
|
+
|
3
|
+
#define PRISM_CHAR_BIT_WHITESPACE (1 << 0)
|
4
|
+
#define PRISM_CHAR_BIT_INLINE_WHITESPACE (1 << 1)
|
5
|
+
#define PRISM_CHAR_BIT_REGEXP_OPTION (1 << 2)
|
6
|
+
|
7
|
+
#define PRISM_NUMBER_BIT_BINARY_DIGIT (1 << 0)
|
8
|
+
#define PRISM_NUMBER_BIT_BINARY_NUMBER (1 << 1)
|
9
|
+
#define PRISM_NUMBER_BIT_OCTAL_DIGIT (1 << 2)
|
10
|
+
#define PRISM_NUMBER_BIT_OCTAL_NUMBER (1 << 3)
|
11
|
+
#define PRISM_NUMBER_BIT_DECIMAL_DIGIT (1 << 4)
|
12
|
+
#define PRISM_NUMBER_BIT_DECIMAL_NUMBER (1 << 5)
|
13
|
+
#define PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT (1 << 6)
|
14
|
+
#define PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER (1 << 7)
|
15
|
+
|
16
|
+
static const uint8_t pm_byte_table[256] = {
|
17
|
+
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
18
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3, 0, 0, // 0x
|
19
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
|
20
|
+
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
|
21
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3x
|
22
|
+
0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 4x
|
23
|
+
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, // 5x
|
24
|
+
0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 6x
|
25
|
+
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, // 7x
|
26
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
|
27
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
|
28
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax
|
29
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx
|
30
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
|
31
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
|
32
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
|
33
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx
|
34
|
+
};
|
35
|
+
|
36
|
+
static const uint8_t pm_number_table[256] = {
|
37
|
+
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
38
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x
|
39
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1x
|
40
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2x
|
41
|
+
0xff, 0xff, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3x
|
42
|
+
0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 4x
|
43
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, // 5x
|
44
|
+
0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 6x
|
45
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 7x
|
46
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8x
|
47
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 9x
|
48
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ax
|
49
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Bx
|
50
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Cx
|
51
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Dx
|
52
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ex
|
53
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Fx
|
54
|
+
};
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Returns the number of characters at the start of the string that match the
|
58
|
+
* given kind. Disallows searching past the given maximum number of characters.
|
59
|
+
*/
|
60
|
+
static inline size_t
|
61
|
+
pm_strspn_char_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
62
|
+
if (length <= 0) return 0;
|
63
|
+
|
64
|
+
size_t size = 0;
|
65
|
+
size_t maximum = (size_t) length;
|
66
|
+
|
67
|
+
while (size < maximum && (pm_byte_table[string[size]] & kind)) size++;
|
68
|
+
return size;
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Returns the number of characters at the start of the string that are
|
73
|
+
* whitespace. Disallows searching past the given maximum number of characters.
|
74
|
+
*/
|
75
|
+
size_t
|
76
|
+
pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length) {
|
77
|
+
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_WHITESPACE);
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* Returns the number of characters at the start of the string that are
|
82
|
+
* whitespace while also tracking the location of each newline. Disallows
|
83
|
+
* searching past the given maximum number of characters.
|
84
|
+
*/
|
85
|
+
size_t
|
86
|
+
pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list) {
|
87
|
+
if (length <= 0) return 0;
|
88
|
+
|
89
|
+
size_t size = 0;
|
90
|
+
size_t maximum = (size_t) length;
|
91
|
+
|
92
|
+
while (size < maximum && (pm_byte_table[string[size]] & PRISM_CHAR_BIT_WHITESPACE)) {
|
93
|
+
if (string[size] == '\n') {
|
94
|
+
pm_newline_list_append(newline_list, string + size);
|
95
|
+
}
|
96
|
+
|
97
|
+
size++;
|
98
|
+
}
|
99
|
+
|
100
|
+
return size;
|
101
|
+
}
|
102
|
+
|
103
|
+
/**
|
104
|
+
* Returns the number of characters at the start of the string that are inline
|
105
|
+
* whitespace. Disallows searching past the given maximum number of characters.
|
106
|
+
*/
|
107
|
+
size_t
|
108
|
+
pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length) {
|
109
|
+
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_INLINE_WHITESPACE);
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* Returns the number of characters at the start of the string that are regexp
|
114
|
+
* options. Disallows searching past the given maximum number of characters.
|
115
|
+
*/
|
116
|
+
size_t
|
117
|
+
pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length) {
|
118
|
+
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_REGEXP_OPTION);
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Returns true if the given character matches the given kind.
|
123
|
+
*/
|
124
|
+
static inline bool
|
125
|
+
pm_char_is_char_kind(const uint8_t b, uint8_t kind) {
|
126
|
+
return (pm_byte_table[b] & kind) != 0;
|
127
|
+
}
|
128
|
+
|
129
|
+
/**
|
130
|
+
* Returns true if the given character is a whitespace character.
|
131
|
+
*/
|
132
|
+
bool
|
133
|
+
pm_char_is_whitespace(const uint8_t b) {
|
134
|
+
return pm_char_is_char_kind(b, PRISM_CHAR_BIT_WHITESPACE);
|
135
|
+
}
|
136
|
+
|
137
|
+
/**
|
138
|
+
* Returns true if the given character is an inline whitespace character.
|
139
|
+
*/
|
140
|
+
bool
|
141
|
+
pm_char_is_inline_whitespace(const uint8_t b) {
|
142
|
+
return pm_char_is_char_kind(b, PRISM_CHAR_BIT_INLINE_WHITESPACE);
|
143
|
+
}
|
144
|
+
|
145
|
+
/**
|
146
|
+
* Scan through the string and return the number of characters at the start of
|
147
|
+
* the string that match the given kind. Disallows searching past the given
|
148
|
+
* maximum number of characters.
|
149
|
+
*/
|
150
|
+
static inline size_t
|
151
|
+
pm_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
152
|
+
if (length <= 0) return 0;
|
153
|
+
|
154
|
+
size_t size = 0;
|
155
|
+
size_t maximum = (size_t) length;
|
156
|
+
|
157
|
+
while (size < maximum && (pm_number_table[string[size]] & kind)) size++;
|
158
|
+
return size;
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* Scan through the string and return the number of characters at the start of
|
163
|
+
* the string that match the given kind. Disallows searching past the given
|
164
|
+
* maximum number of characters.
|
165
|
+
*
|
166
|
+
* Additionally, report the location of the last invalid underscore character
|
167
|
+
* found in the string through the out invalid parameter.
|
168
|
+
*/
|
169
|
+
static inline size_t
|
170
|
+
pm_strspn_number_kind_underscores(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid, uint8_t kind) {
|
171
|
+
if (length <= 0) return 0;
|
172
|
+
|
173
|
+
size_t size = 0;
|
174
|
+
size_t maximum = (size_t) length;
|
175
|
+
|
176
|
+
bool underscore = false;
|
177
|
+
while (size < maximum && (pm_number_table[string[size]] & kind)) {
|
178
|
+
if (string[size] == '_') {
|
179
|
+
if (underscore) *invalid = string + size;
|
180
|
+
underscore = true;
|
181
|
+
} else {
|
182
|
+
underscore = false;
|
183
|
+
}
|
184
|
+
|
185
|
+
size++;
|
186
|
+
}
|
187
|
+
|
188
|
+
if (size > 0 && string[size - 1] == '_') *invalid = string + size - 1;
|
189
|
+
return size;
|
190
|
+
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
* Returns the number of characters at the start of the string that are binary
|
194
|
+
* digits or underscores. Disallows searching past the given maximum number of
|
195
|
+
* characters.
|
196
|
+
*
|
197
|
+
* If multiple underscores are found in a row or if an underscore is
|
198
|
+
* found at the end of the number, then the invalid pointer is set to the index
|
199
|
+
* of the first invalid underscore.
|
200
|
+
*/
|
201
|
+
size_t
|
202
|
+
pm_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
|
203
|
+
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_BINARY_NUMBER);
|
204
|
+
}
|
205
|
+
|
206
|
+
/**
|
207
|
+
* Returns the number of characters at the start of the string that are octal
|
208
|
+
* digits or underscores. Disallows searching past the given maximum number of
|
209
|
+
* characters.
|
210
|
+
*
|
211
|
+
* If multiple underscores are found in a row or if an underscore is
|
212
|
+
* found at the end of the number, then the invalid pointer is set to the index
|
213
|
+
* of the first invalid underscore.
|
214
|
+
*/
|
215
|
+
size_t
|
216
|
+
pm_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
|
217
|
+
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_OCTAL_NUMBER);
|
218
|
+
}
|
219
|
+
|
220
|
+
/**
|
221
|
+
* Returns the number of characters at the start of the string that are decimal
|
222
|
+
* digits. Disallows searching past the given maximum number of characters.
|
223
|
+
*/
|
224
|
+
size_t
|
225
|
+
pm_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length) {
|
226
|
+
return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_DECIMAL_DIGIT);
|
227
|
+
}
|
228
|
+
|
229
|
+
/**
|
230
|
+
* Returns the number of characters at the start of the string that are decimal
|
231
|
+
* digits or underscores. Disallows searching past the given maximum number of
|
232
|
+
* characters.
|
233
|
+
*
|
234
|
+
* If multiple underscores are found in a row or if an underscore is
|
235
|
+
* found at the end of the number, then the invalid pointer is set to the index
|
236
|
+
* of the first invalid underscore
|
237
|
+
*/
|
238
|
+
size_t
|
239
|
+
pm_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
|
240
|
+
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_DECIMAL_NUMBER);
|
241
|
+
}
|
242
|
+
|
243
|
+
/**
|
244
|
+
* Returns the number of characters at the start of the string that are
|
245
|
+
* hexadecimal digits. Disallows searching past the given maximum number of
|
246
|
+
* characters.
|
247
|
+
*/
|
248
|
+
size_t
|
249
|
+
pm_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length) {
|
250
|
+
return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
|
251
|
+
}
|
252
|
+
|
253
|
+
/**
|
254
|
+
* Returns the number of characters at the start of the string that are
|
255
|
+
* hexadecimal digits or underscores. Disallows searching past the given maximum
|
256
|
+
* number of characters.
|
257
|
+
*
|
258
|
+
* If multiple underscores are found in a row or if an underscore is
|
259
|
+
* found at the end of the number, then the invalid pointer is set to the index
|
260
|
+
* of the first invalid underscore.
|
261
|
+
*/
|
262
|
+
size_t
|
263
|
+
pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
|
264
|
+
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER);
|
265
|
+
}
|
266
|
+
|
267
|
+
/**
|
268
|
+
* Returns true if the given character matches the given kind.
|
269
|
+
*/
|
270
|
+
static inline bool
|
271
|
+
pm_char_is_number_kind(const uint8_t b, uint8_t kind) {
|
272
|
+
return (pm_number_table[b] & kind) != 0;
|
273
|
+
}
|
274
|
+
|
275
|
+
/**
|
276
|
+
* Returns true if the given character is a binary digit.
|
277
|
+
*/
|
278
|
+
bool
|
279
|
+
pm_char_is_binary_digit(const uint8_t b) {
|
280
|
+
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_BINARY_DIGIT);
|
281
|
+
}
|
282
|
+
|
283
|
+
/**
|
284
|
+
* Returns true if the given character is an octal digit.
|
285
|
+
*/
|
286
|
+
bool
|
287
|
+
pm_char_is_octal_digit(const uint8_t b) {
|
288
|
+
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_OCTAL_DIGIT);
|
289
|
+
}
|
290
|
+
|
291
|
+
/**
|
292
|
+
* Returns true if the given character is a decimal digit.
|
293
|
+
*/
|
294
|
+
bool
|
295
|
+
pm_char_is_decimal_digit(const uint8_t b) {
|
296
|
+
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_DECIMAL_DIGIT);
|
297
|
+
}
|
298
|
+
|
299
|
+
/**
|
300
|
+
* Returns true if the given character is a hexadecimal digit.
|
301
|
+
*/
|
302
|
+
bool
|
303
|
+
pm_char_is_hexadecimal_digit(const uint8_t b) {
|
304
|
+
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
|
305
|
+
}
|
306
|
+
|
307
|
+
#undef PRISM_CHAR_BIT_WHITESPACE
|
308
|
+
#undef PRISM_CHAR_BIT_INLINE_WHITESPACE
|
309
|
+
#undef PRISM_CHAR_BIT_REGEXP_OPTION
|
310
|
+
|
311
|
+
#undef PRISM_NUMBER_BIT_BINARY_DIGIT
|
312
|
+
#undef PRISM_NUMBER_BIT_BINARY_NUMBER
|
313
|
+
#undef PRISM_NUMBER_BIT_OCTAL_DIGIT
|
314
|
+
#undef PRISM_NUMBER_BIT_OCTAL_NUMBER
|
315
|
+
#undef PRISM_NUMBER_BIT_DECIMAL_DIGIT
|
316
|
+
#undef PRISM_NUMBER_BIT_DECIMAL_NUMBER
|
317
|
+
#undef PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER
|
318
|
+
#undef PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT
|