10pm_pack_parse(
pm_pack_variant variant,
const char **format,
const char *format_end,
14 if (*encoding == PM_PACK_ENCODING_START) {
15 *encoding = PM_PACK_ENCODING_US_ASCII;
18 if (*format == format_end) {
20 *signed_type = PM_PACK_SIGNED_NA;
21 *endian = PM_PACK_ENDIAN_NA;
22 *size = PM_PACK_SIZE_NA;
23 *length_type = PM_PACK_LENGTH_NA;
27 *length_type = PM_PACK_LENGTH_FIXED;
29 bool length_changed_allowed =
true;
31 char directive = **format;
40 *type = PM_PACK_SPACE;
41 *signed_type = PM_PACK_SIGNED_NA;
42 *endian = PM_PACK_ENDIAN_NA;
43 *size = PM_PACK_SIZE_NA;
44 *length_type = PM_PACK_LENGTH_NA;
48 while ((*format < format_end) && (**format !=
'\n')) {
51 *type = PM_PACK_COMMENT;
52 *signed_type = PM_PACK_SIGNED_NA;
53 *endian = PM_PACK_ENDIAN_NA;
54 *size = PM_PACK_SIZE_NA;
55 *length_type = PM_PACK_LENGTH_NA;
59 *type = PM_PACK_INTEGER;
60 *signed_type = PM_PACK_UNSIGNED;
61 *endian = PM_PACK_AGNOSTIC_ENDIAN;
62 *size = PM_PACK_SIZE_8;
65 *type = PM_PACK_INTEGER;
66 *signed_type = PM_PACK_UNSIGNED;
67 *endian = PM_PACK_NATIVE_ENDIAN;
68 *size = PM_PACK_SIZE_16;
71 *type = PM_PACK_INTEGER;
72 *signed_type = PM_PACK_UNSIGNED;
73 *endian = PM_PACK_NATIVE_ENDIAN;
74 *size = PM_PACK_SIZE_32;
77 *type = PM_PACK_INTEGER;
78 *signed_type = PM_PACK_UNSIGNED;
79 *endian = PM_PACK_NATIVE_ENDIAN;
80 *size = PM_PACK_SIZE_64;
83 *type = PM_PACK_INTEGER;
84 *signed_type = PM_PACK_UNSIGNED;
85 *endian = PM_PACK_NATIVE_ENDIAN;
86 *size = PM_PACK_SIZE_P;
89 *type = PM_PACK_INTEGER;
90 *signed_type = PM_PACK_SIGNED;
91 *endian = PM_PACK_AGNOSTIC_ENDIAN;
92 *size = PM_PACK_SIZE_8;
95 *type = PM_PACK_INTEGER;
96 *signed_type = PM_PACK_SIGNED;
97 *endian = PM_PACK_NATIVE_ENDIAN;
98 *size = PM_PACK_SIZE_16;
101 *type = PM_PACK_INTEGER;
102 *signed_type = PM_PACK_SIGNED;
103 *endian = PM_PACK_NATIVE_ENDIAN;
104 *size = PM_PACK_SIZE_32;
107 *type = PM_PACK_INTEGER;
108 *signed_type = PM_PACK_SIGNED;
109 *endian = PM_PACK_NATIVE_ENDIAN;
110 *size = PM_PACK_SIZE_64;
113 *type = PM_PACK_INTEGER;
114 *signed_type = PM_PACK_SIGNED;
115 *endian = PM_PACK_NATIVE_ENDIAN;
116 *size = PM_PACK_SIZE_P;
119 *type = PM_PACK_INTEGER;
120 *signed_type = PM_PACK_UNSIGNED;
121 *endian = PM_PACK_NATIVE_ENDIAN;
122 *size = PM_PACK_SIZE_INT;
125 *type = PM_PACK_INTEGER;
126 *signed_type = PM_PACK_SIGNED;
127 *endian = PM_PACK_NATIVE_ENDIAN;
128 *size = PM_PACK_SIZE_INT;
131 *type = PM_PACK_INTEGER;
132 *signed_type = PM_PACK_UNSIGNED;
133 *endian = PM_PACK_BIG_ENDIAN;
134 *size = PM_PACK_SIZE_16;
135 length_changed_allowed =
false;
138 *type = PM_PACK_INTEGER;
139 *signed_type = PM_PACK_UNSIGNED;
140 *endian = PM_PACK_BIG_ENDIAN;
141 *size = PM_PACK_SIZE_32;
142 length_changed_allowed =
false;
145 *type = PM_PACK_INTEGER;
146 *signed_type = PM_PACK_UNSIGNED;
147 *endian = PM_PACK_LITTLE_ENDIAN;
148 *size = PM_PACK_SIZE_16;
149 length_changed_allowed =
false;
152 *type = PM_PACK_INTEGER;
153 *signed_type = PM_PACK_UNSIGNED;
154 *endian = PM_PACK_LITTLE_ENDIAN;
155 *size = PM_PACK_SIZE_32;
156 length_changed_allowed =
false;
159 *type = PM_PACK_UTF8;
160 *signed_type = PM_PACK_SIGNED_NA;
161 *endian = PM_PACK_ENDIAN_NA;
162 *size = PM_PACK_SIZE_NA;
166 *signed_type = PM_PACK_SIGNED_NA;
167 *endian = PM_PACK_ENDIAN_NA;
168 *size = PM_PACK_SIZE_NA;
172 *type = PM_PACK_FLOAT;
173 *signed_type = PM_PACK_SIGNED_NA;
174 *endian = PM_PACK_NATIVE_ENDIAN;
175 *size = PM_PACK_SIZE_64;
179 *type = PM_PACK_FLOAT;
180 *signed_type = PM_PACK_SIGNED_NA;
181 *endian = PM_PACK_NATIVE_ENDIAN;
182 *size = PM_PACK_SIZE_32;
185 *type = PM_PACK_FLOAT;
186 *signed_type = PM_PACK_SIGNED_NA;
187 *endian = PM_PACK_LITTLE_ENDIAN;
188 *size = PM_PACK_SIZE_64;
191 *type = PM_PACK_FLOAT;
192 *signed_type = PM_PACK_SIGNED_NA;
193 *endian = PM_PACK_LITTLE_ENDIAN;
194 *size = PM_PACK_SIZE_32;
197 *type = PM_PACK_FLOAT;
198 *signed_type = PM_PACK_SIGNED_NA;
199 *endian = PM_PACK_BIG_ENDIAN;
200 *size = PM_PACK_SIZE_64;
203 *type = PM_PACK_FLOAT;
204 *signed_type = PM_PACK_SIGNED_NA;
205 *endian = PM_PACK_BIG_ENDIAN;
206 *size = PM_PACK_SIZE_32;
209 *type = PM_PACK_STRING_SPACE_PADDED;
210 *signed_type = PM_PACK_SIGNED_NA;
211 *endian = PM_PACK_ENDIAN_NA;
212 *size = PM_PACK_SIZE_NA;
215 *type = PM_PACK_STRING_NULL_PADDED;
216 *signed_type = PM_PACK_SIGNED_NA;
217 *endian = PM_PACK_ENDIAN_NA;
218 *size = PM_PACK_SIZE_NA;
221 *type = PM_PACK_STRING_NULL_TERMINATED;
222 *signed_type = PM_PACK_SIGNED_NA;
223 *endian = PM_PACK_ENDIAN_NA;
224 *size = PM_PACK_SIZE_NA;
227 *type = PM_PACK_STRING_MSB;
228 *signed_type = PM_PACK_SIGNED_NA;
229 *endian = PM_PACK_ENDIAN_NA;
230 *size = PM_PACK_SIZE_NA;
233 *type = PM_PACK_STRING_LSB;
234 *signed_type = PM_PACK_SIGNED_NA;
235 *endian = PM_PACK_ENDIAN_NA;
236 *size = PM_PACK_SIZE_NA;
239 *type = PM_PACK_STRING_HEX_HIGH;
240 *signed_type = PM_PACK_SIGNED_NA;
241 *endian = PM_PACK_ENDIAN_NA;
242 *size = PM_PACK_SIZE_NA;
245 *type = PM_PACK_STRING_HEX_LOW;
246 *signed_type = PM_PACK_SIGNED_NA;
247 *endian = PM_PACK_ENDIAN_NA;
248 *size = PM_PACK_SIZE_NA;
251 *type = PM_PACK_STRING_UU;
252 *signed_type = PM_PACK_SIGNED_NA;
253 *endian = PM_PACK_ENDIAN_NA;
254 *size = PM_PACK_SIZE_NA;
257 *type = PM_PACK_STRING_MIME;
258 *signed_type = PM_PACK_SIGNED_NA;
259 *endian = PM_PACK_ENDIAN_NA;
260 *size = PM_PACK_SIZE_NA;
263 *type = PM_PACK_STRING_BASE64;
264 *signed_type = PM_PACK_SIGNED_NA;
265 *endian = PM_PACK_ENDIAN_NA;
266 *size = PM_PACK_SIZE_NA;
269 *type = PM_PACK_STRING_FIXED;
270 *signed_type = PM_PACK_SIGNED_NA;
271 *endian = PM_PACK_ENDIAN_NA;
272 *size = PM_PACK_SIZE_NA;
275 *type = PM_PACK_STRING_POINTER;
276 *signed_type = PM_PACK_SIGNED_NA;
277 *endian = PM_PACK_ENDIAN_NA;
278 *size = PM_PACK_SIZE_NA;
281 *type = PM_PACK_MOVE;
282 *signed_type = PM_PACK_SIGNED_NA;
283 *endian = PM_PACK_ENDIAN_NA;
284 *size = PM_PACK_SIZE_NA;
287 *type = PM_PACK_BACK;
288 *signed_type = PM_PACK_SIGNED_NA;
289 *endian = PM_PACK_ENDIAN_NA;
290 *size = PM_PACK_SIZE_NA;
293 *type = PM_PACK_NULL;
294 *signed_type = PM_PACK_SIGNED_NA;
295 *endian = PM_PACK_ENDIAN_NA;
296 *size = PM_PACK_SIZE_NA;
299 return PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE;
301 return PM_PACK_ERROR_UNKNOWN_DIRECTIVE;
304 bool explicit_endian =
false;
306 while (*format < format_end) {
311 if (*type != PM_PACK_INTEGER || !length_changed_allowed) {
312 return PM_PACK_ERROR_BANG_NOT_ALLOWED;
315 case PM_PACK_SIZE_SHORT:
316 case PM_PACK_SIZE_INT:
317 case PM_PACK_SIZE_LONG:
318 case PM_PACK_SIZE_LONG_LONG:
320 case PM_PACK_SIZE_16:
321 *size = PM_PACK_SIZE_SHORT;
323 case PM_PACK_SIZE_32:
324 *size = PM_PACK_SIZE_LONG;
326 case PM_PACK_SIZE_64:
327 *size = PM_PACK_SIZE_LONG_LONG;
332 return PM_PACK_ERROR_BANG_NOT_ALLOWED;
337 if (explicit_endian) {
338 return PM_PACK_ERROR_DOUBLE_ENDIAN;
340 *endian = PM_PACK_LITTLE_ENDIAN;
341 explicit_endian =
true;
345 if (explicit_endian) {
346 return PM_PACK_ERROR_DOUBLE_ENDIAN;
348 *endian = PM_PACK_BIG_ENDIAN;
349 explicit_endian =
true;
352 goto exit_modifier_loop;
358 if (variant == PM_PACK_VARIANT_UNPACK && *type == PM_PACK_MOVE) {
362 if (*format < format_end) {
363 if (**format ==
'*') {
368 case PM_PACK_VARIANT_PACK:
369 *length_type = PM_PACK_LENGTH_FIXED;
371 case PM_PACK_VARIANT_UNPACK:
372 *length_type = PM_PACK_LENGTH_MAX;
380 case PM_PACK_VARIANT_PACK:
381 *length_type = PM_PACK_LENGTH_FIXED;
383 case PM_PACK_VARIANT_UNPACK:
384 *length_type = PM_PACK_LENGTH_RELATIVE;
390 case PM_PACK_STRING_UU:
391 *length_type = PM_PACK_LENGTH_FIXED;
395 case PM_PACK_STRING_FIXED:
397 case PM_PACK_VARIANT_PACK:
398 *length_type = PM_PACK_LENGTH_FIXED;
401 case PM_PACK_VARIANT_UNPACK:
402 *length_type = PM_PACK_LENGTH_MAX;
408 case PM_PACK_STRING_MIME:
409 case PM_PACK_STRING_BASE64:
410 *length_type = PM_PACK_LENGTH_FIXED;
415 *length_type = PM_PACK_LENGTH_MAX;
421 }
else if (**format >=
'0' && **format <=
'9') {
423 *length_type = PM_PACK_LENGTH_FIXED;
424 #if UINTMAX_MAX < UINT64_MAX
425 #error "prism's design assumes uintmax_t is at least as large as uint64_t"
427 uintmax_t length_max = strtoumaxc(format);
428 if (
errno || length_max > UINT64_MAX) {
429 return PM_PACK_ERROR_LENGTH_TOO_BIG;
431 *length = (uint64_t) length_max;
438 if (*encoding == PM_PACK_ENCODING_US_ASCII) {
439 *encoding = PM_PACK_ENCODING_UTF_8;
442 case PM_PACK_STRING_MIME:
443 case PM_PACK_STRING_BASE64:
444 case PM_PACK_STRING_UU:
449 *encoding = PM_PACK_ENCODING_ASCII_8BIT;