6 #ifdef PRISM_EXCLUDE_PACK
16 strtoumaxc(
const char **format) {
18 while (**format >=
'0' && **format <=
'9') {
19 if (value > UINTMAX_MAX / 10) {
22 value = value * 10 + ((uintmax_t) (**format -
'0'));
32 const char *format_end,
41 if (*encoding == PM_PACK_ENCODING_START) {
42 *encoding = PM_PACK_ENCODING_US_ASCII;
45 if (*format == format_end) {
47 *signed_type = PM_PACK_SIGNED_NA;
48 *endian = PM_PACK_ENDIAN_NA;
49 *size = PM_PACK_SIZE_NA;
50 *length_type = PM_PACK_LENGTH_NA;
54 *length_type = PM_PACK_LENGTH_FIXED;
56 bool length_changed_allowed =
true;
58 char directive = **format;
67 *
type = PM_PACK_SPACE;
68 *signed_type = PM_PACK_SIGNED_NA;
69 *endian = PM_PACK_ENDIAN_NA;
70 *size = PM_PACK_SIZE_NA;
71 *length_type = PM_PACK_LENGTH_NA;
75 while ((*format < format_end) && (**format !=
'\n')) {
78 *
type = PM_PACK_COMMENT;
79 *signed_type = PM_PACK_SIGNED_NA;
80 *endian = PM_PACK_ENDIAN_NA;
81 *size = PM_PACK_SIZE_NA;
82 *length_type = PM_PACK_LENGTH_NA;
86 *
type = PM_PACK_INTEGER;
87 *signed_type = PM_PACK_UNSIGNED;
88 *endian = PM_PACK_AGNOSTIC_ENDIAN;
89 *size = PM_PACK_SIZE_8;
92 *
type = PM_PACK_INTEGER;
93 *signed_type = PM_PACK_UNSIGNED;
94 *endian = PM_PACK_NATIVE_ENDIAN;
95 *size = PM_PACK_SIZE_16;
98 *
type = PM_PACK_INTEGER;
99 *signed_type = PM_PACK_UNSIGNED;
100 *endian = PM_PACK_NATIVE_ENDIAN;
101 *size = PM_PACK_SIZE_32;
104 *
type = PM_PACK_INTEGER;
105 *signed_type = PM_PACK_UNSIGNED;
106 *endian = PM_PACK_NATIVE_ENDIAN;
107 *size = PM_PACK_SIZE_64;
110 *
type = PM_PACK_INTEGER;
111 *signed_type = PM_PACK_UNSIGNED;
112 *endian = PM_PACK_NATIVE_ENDIAN;
113 *size = PM_PACK_SIZE_P;
116 *
type = PM_PACK_INTEGER;
117 *signed_type = PM_PACK_SIGNED;
118 *endian = PM_PACK_AGNOSTIC_ENDIAN;
119 *size = PM_PACK_SIZE_8;
122 *
type = PM_PACK_INTEGER;
123 *signed_type = PM_PACK_SIGNED;
124 *endian = PM_PACK_NATIVE_ENDIAN;
125 *size = PM_PACK_SIZE_16;
128 *
type = PM_PACK_INTEGER;
129 *signed_type = PM_PACK_SIGNED;
130 *endian = PM_PACK_NATIVE_ENDIAN;
131 *size = PM_PACK_SIZE_32;
134 *
type = PM_PACK_INTEGER;
135 *signed_type = PM_PACK_SIGNED;
136 *endian = PM_PACK_NATIVE_ENDIAN;
137 *size = PM_PACK_SIZE_64;
140 *
type = PM_PACK_INTEGER;
141 *signed_type = PM_PACK_SIGNED;
142 *endian = PM_PACK_NATIVE_ENDIAN;
143 *size = PM_PACK_SIZE_P;
146 *
type = PM_PACK_INTEGER;
147 *signed_type = PM_PACK_UNSIGNED;
148 *endian = PM_PACK_NATIVE_ENDIAN;
149 *size = PM_PACK_SIZE_INT;
152 *
type = PM_PACK_INTEGER;
153 *signed_type = PM_PACK_SIGNED;
154 *endian = PM_PACK_NATIVE_ENDIAN;
155 *size = PM_PACK_SIZE_INT;
158 *
type = PM_PACK_INTEGER;
159 *signed_type = PM_PACK_UNSIGNED;
160 *endian = PM_PACK_BIG_ENDIAN;
161 *size = PM_PACK_SIZE_16;
162 length_changed_allowed =
false;
165 *
type = PM_PACK_INTEGER;
166 *signed_type = PM_PACK_UNSIGNED;
167 *endian = PM_PACK_BIG_ENDIAN;
168 *size = PM_PACK_SIZE_32;
169 length_changed_allowed =
false;
172 *
type = PM_PACK_INTEGER;
173 *signed_type = PM_PACK_UNSIGNED;
174 *endian = PM_PACK_LITTLE_ENDIAN;
175 *size = PM_PACK_SIZE_16;
176 length_changed_allowed =
false;
179 *
type = PM_PACK_INTEGER;
180 *signed_type = PM_PACK_UNSIGNED;
181 *endian = PM_PACK_LITTLE_ENDIAN;
182 *size = PM_PACK_SIZE_32;
183 length_changed_allowed =
false;
186 *
type = PM_PACK_UTF8;
187 *signed_type = PM_PACK_SIGNED_NA;
188 *endian = PM_PACK_ENDIAN_NA;
189 *size = PM_PACK_SIZE_NA;
193 *signed_type = PM_PACK_SIGNED_NA;
194 *endian = PM_PACK_ENDIAN_NA;
195 *size = PM_PACK_SIZE_NA;
199 *
type = PM_PACK_FLOAT;
200 *signed_type = PM_PACK_SIGNED_NA;
201 *endian = PM_PACK_NATIVE_ENDIAN;
202 *size = PM_PACK_SIZE_64;
206 *
type = PM_PACK_FLOAT;
207 *signed_type = PM_PACK_SIGNED_NA;
208 *endian = PM_PACK_NATIVE_ENDIAN;
209 *size = PM_PACK_SIZE_32;
212 *
type = PM_PACK_FLOAT;
213 *signed_type = PM_PACK_SIGNED_NA;
214 *endian = PM_PACK_LITTLE_ENDIAN;
215 *size = PM_PACK_SIZE_64;
218 *
type = PM_PACK_FLOAT;
219 *signed_type = PM_PACK_SIGNED_NA;
220 *endian = PM_PACK_LITTLE_ENDIAN;
221 *size = PM_PACK_SIZE_32;
224 *
type = PM_PACK_FLOAT;
225 *signed_type = PM_PACK_SIGNED_NA;
226 *endian = PM_PACK_BIG_ENDIAN;
227 *size = PM_PACK_SIZE_64;
230 *
type = PM_PACK_FLOAT;
231 *signed_type = PM_PACK_SIGNED_NA;
232 *endian = PM_PACK_BIG_ENDIAN;
233 *size = PM_PACK_SIZE_32;
236 *
type = PM_PACK_STRING_SPACE_PADDED;
237 *signed_type = PM_PACK_SIGNED_NA;
238 *endian = PM_PACK_ENDIAN_NA;
239 *size = PM_PACK_SIZE_NA;
242 *
type = PM_PACK_STRING_NULL_PADDED;
243 *signed_type = PM_PACK_SIGNED_NA;
244 *endian = PM_PACK_ENDIAN_NA;
245 *size = PM_PACK_SIZE_NA;
248 *
type = PM_PACK_STRING_NULL_TERMINATED;
249 *signed_type = PM_PACK_SIGNED_NA;
250 *endian = PM_PACK_ENDIAN_NA;
251 *size = PM_PACK_SIZE_NA;
254 *
type = PM_PACK_STRING_MSB;
255 *signed_type = PM_PACK_SIGNED_NA;
256 *endian = PM_PACK_ENDIAN_NA;
257 *size = PM_PACK_SIZE_NA;
260 *
type = PM_PACK_STRING_LSB;
261 *signed_type = PM_PACK_SIGNED_NA;
262 *endian = PM_PACK_ENDIAN_NA;
263 *size = PM_PACK_SIZE_NA;
266 *
type = PM_PACK_STRING_HEX_HIGH;
267 *signed_type = PM_PACK_SIGNED_NA;
268 *endian = PM_PACK_ENDIAN_NA;
269 *size = PM_PACK_SIZE_NA;
272 *
type = PM_PACK_STRING_HEX_LOW;
273 *signed_type = PM_PACK_SIGNED_NA;
274 *endian = PM_PACK_ENDIAN_NA;
275 *size = PM_PACK_SIZE_NA;
278 *
type = PM_PACK_STRING_UU;
279 *signed_type = PM_PACK_SIGNED_NA;
280 *endian = PM_PACK_ENDIAN_NA;
281 *size = PM_PACK_SIZE_NA;
284 *
type = PM_PACK_STRING_MIME;
285 *signed_type = PM_PACK_SIGNED_NA;
286 *endian = PM_PACK_ENDIAN_NA;
287 *size = PM_PACK_SIZE_NA;
290 *
type = PM_PACK_STRING_BASE64;
291 *signed_type = PM_PACK_SIGNED_NA;
292 *endian = PM_PACK_ENDIAN_NA;
293 *size = PM_PACK_SIZE_NA;
296 *
type = PM_PACK_STRING_FIXED;
297 *signed_type = PM_PACK_SIGNED_NA;
298 *endian = PM_PACK_ENDIAN_NA;
299 *size = PM_PACK_SIZE_NA;
302 *
type = PM_PACK_STRING_POINTER;
303 *signed_type = PM_PACK_SIGNED_NA;
304 *endian = PM_PACK_ENDIAN_NA;
305 *size = PM_PACK_SIZE_NA;
308 *
type = PM_PACK_MOVE;
309 *signed_type = PM_PACK_SIGNED_NA;
310 *endian = PM_PACK_ENDIAN_NA;
311 *size = PM_PACK_SIZE_NA;
314 *
type = PM_PACK_BACK;
315 *signed_type = PM_PACK_SIGNED_NA;
316 *endian = PM_PACK_ENDIAN_NA;
317 *size = PM_PACK_SIZE_NA;
320 *
type = PM_PACK_NULL;
321 *signed_type = PM_PACK_SIGNED_NA;
322 *endian = PM_PACK_ENDIAN_NA;
323 *size = PM_PACK_SIZE_NA;
326 return PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE;
328 return PM_PACK_ERROR_UNKNOWN_DIRECTIVE;
331 bool explicit_endian =
false;
333 while (*format < format_end) {
338 if (*
type != PM_PACK_INTEGER || !length_changed_allowed) {
339 return PM_PACK_ERROR_BANG_NOT_ALLOWED;
342 case PM_PACK_SIZE_SHORT:
343 case PM_PACK_SIZE_INT:
344 case PM_PACK_SIZE_LONG:
345 case PM_PACK_SIZE_LONG_LONG:
347 case PM_PACK_SIZE_16:
348 *size = PM_PACK_SIZE_SHORT;
350 case PM_PACK_SIZE_32:
351 *size = PM_PACK_SIZE_LONG;
353 case PM_PACK_SIZE_64:
354 *size = PM_PACK_SIZE_LONG_LONG;
359 return PM_PACK_ERROR_BANG_NOT_ALLOWED;
364 if (explicit_endian) {
365 return PM_PACK_ERROR_DOUBLE_ENDIAN;
367 *endian = PM_PACK_LITTLE_ENDIAN;
368 explicit_endian =
true;
372 if (explicit_endian) {
373 return PM_PACK_ERROR_DOUBLE_ENDIAN;
375 *endian = PM_PACK_BIG_ENDIAN;
376 explicit_endian =
true;
379 goto exit_modifier_loop;
385 if (variant == PM_PACK_VARIANT_UNPACK && *
type == PM_PACK_MOVE) {
389 if (*format < format_end) {
390 if (**format ==
'*') {
395 case PM_PACK_VARIANT_PACK:
396 *length_type = PM_PACK_LENGTH_FIXED;
398 case PM_PACK_VARIANT_UNPACK:
399 *length_type = PM_PACK_LENGTH_MAX;
407 case PM_PACK_VARIANT_PACK:
408 *length_type = PM_PACK_LENGTH_FIXED;
410 case PM_PACK_VARIANT_UNPACK:
411 *length_type = PM_PACK_LENGTH_RELATIVE;
417 case PM_PACK_STRING_UU:
418 *length_type = PM_PACK_LENGTH_FIXED;
422 case PM_PACK_STRING_FIXED:
424 case PM_PACK_VARIANT_PACK:
425 *length_type = PM_PACK_LENGTH_FIXED;
428 case PM_PACK_VARIANT_UNPACK:
429 *length_type = PM_PACK_LENGTH_MAX;
435 case PM_PACK_STRING_MIME:
436 case PM_PACK_STRING_BASE64:
437 *length_type = PM_PACK_LENGTH_FIXED;
442 *length_type = PM_PACK_LENGTH_MAX;
448 }
else if (**format >=
'0' && **format <=
'9') {
450 *length_type = PM_PACK_LENGTH_FIXED;
451 #if UINTMAX_MAX < UINT64_MAX
452 #error "prism's design assumes uintmax_t is at least as large as uint64_t"
454 uintmax_t length_max = strtoumaxc(format);
455 if (
errno || length_max > UINT64_MAX) {
456 return PM_PACK_ERROR_LENGTH_TOO_BIG;
458 *length = (uint64_t) length_max;
465 if (*encoding == PM_PACK_ENCODING_US_ASCII) {
466 *encoding = PM_PACK_ENCODING_UTF_8;
469 case PM_PACK_STRING_MIME:
470 case PM_PACK_STRING_BASE64:
471 case PM_PACK_STRING_UU:
476 *encoding = PM_PACK_ENCODING_ASCII_8BIT;
486 case PM_PACK_SIZE_SHORT:
487 return sizeof(short);
488 case PM_PACK_SIZE_INT:
490 case PM_PACK_SIZE_LONG:
492 case PM_PACK_SIZE_LONG_LONG:
493 return sizeof(
long long);
496 case PM_PACK_SIZE_16:
498 case PM_PACK_SIZE_32:
500 case PM_PACK_SIZE_64:
503 return sizeof(
void *);
VALUE type(ANYARGS)
ANYARGS-ed function type.
A pack template string parser.
pm_pack_encoding
The type of encoding for a pack template string.
pm_pack_result
The result of parsing a pack template.
pm_pack_variant
The type of pack template we are parsing.
pm_pack_endian
The endianness of a pack directive.
pm_pack_signed
The signness of a pack directive.
pm_pack_size
The size of an integer pack directive.
PRISM_EXPORTED_FUNCTION size_t pm_size_to_native(pm_pack_size size)
Prism abstracts sizes away from the native system - this converts an abstract size to a native size.
pm_pack_length_type
The type of length of a pack directive.
PRISM_EXPORTED_FUNCTION pm_pack_result pm_pack_parse(pm_pack_variant variant, const char **format, const char *format_end, pm_pack_type *type, pm_pack_signed *signed_type, pm_pack_endian *endian, pm_pack_size *size, pm_pack_length_type *length_type, uint64_t *length, pm_pack_encoding *encoding)
Parse a single directive from a pack or unpack format string.
pm_pack_type
A directive within the pack template.
#define PRISM_EXPORTED_FUNCTION
By default, we compile with -fvisibility=hidden.
#define errno
Ractor-aware version of errno.