t_snprintb.c revision 1.23 1 /* $NetBSD: t_snprintb.c,v 1.23 2024/02/20 19:49:10 rillig Exp $ */
2
3 /*
4 * Copyright (c) 2002, 2004, 2008, 2010, 2024 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code was contributed to The NetBSD Foundation by Christos Zoulas and
8 * Roland Illig.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __COPYRIGHT("@(#) Copyright (c) 2008, 2010, 2024\
34 The NetBSD Foundation, inc. All rights reserved.");
35 __RCSID("$NetBSD: t_snprintb.c,v 1.23 2024/02/20 19:49:10 rillig Exp $");
36
37 #include <stdio.h>
38 #include <string.h>
39 #include <util.h>
40 #include <vis.h>
41
42 #include <atf-c.h>
43
44 static const char *
45 vis_arr(const char *arr, size_t arrsize)
46 {
47 static char buf[6][1024];
48 static size_t i;
49
50 i = (i + 1) % (sizeof(buf) / sizeof(buf[0]));
51 buf[i][0] = '"';
52 int rv = strnvisx(buf[i] + 1, sizeof(buf[i]) - 2, arr, arrsize,
53 VIS_WHITE | VIS_OCTAL);
54 ATF_REQUIRE_MSG(rv >= 0, "strnvisx failed for size %zu", arrsize);
55 strcpy(buf[i] + 1 + rv, "\"");
56 return buf[i];
57 }
58
59 static void
60 check_unmodified_loc(const char *file, size_t line,
61 const char *arr, size_t begin, size_t end)
62 {
63 while (begin < end && arr[begin] == 'Z')
64 begin++;
65 while (begin < end && arr[end - 1] == 'Z')
66 end--;
67 ATF_CHECK_MSG(
68 begin == end,
69 "failed:\n"
70 "\ttest case: %s:%zu\n"
71 "\tout-of-bounds write from %zu to %zu: %s\n",
72 file, line,
73 begin, end, vis_arr(arr + begin, end - begin));
74 }
75
76 static void
77 h_snprintb_loc(const char *file, size_t line,
78 size_t bufsize, const char *bitfmt, size_t bitfmtlen, uint64_t val,
79 int want_rv, const char *want_buf, size_t want_bufsize)
80 {
81 char buf[1024];
82
83 ATF_REQUIRE(bufsize <= sizeof(buf));
84 ATF_REQUIRE(want_bufsize <= sizeof(buf));
85 if (bitfmtlen > 2 && bitfmt[0] == '\177')
86 ATF_REQUIRE_MSG(bitfmt[bitfmtlen - 1] == '\0',
87 "%s:%zu: missing trailing '\\0' in bitfmt",
88 file, line);
89 if (bufsize == 0 && want_bufsize == 1)
90 want_bufsize = 0;
91
92 memset(buf, 'Z', sizeof(buf));
93 int rv = snprintb(buf, bufsize, bitfmt, val);
94 ATF_REQUIRE(rv >= 0);
95 size_t rlen = rv;
96
97 ATF_CHECK_MSG(
98 rv == want_rv
99 && memcmp(buf, want_buf, want_bufsize) == 0
100 && (bufsize < 1
101 || buf[rlen < bufsize ? rlen : bufsize - 1] == '\0'),
102 "failed:\n"
103 "\ttest case: %s:%zu\n"
104 "\tformat: %s\n"
105 "\tvalue: %#jx\n"
106 "\twant: %d bytes %s\n"
107 "\thave: %d bytes %s\n",
108 file, line,
109 vis_arr(bitfmt, bitfmtlen),
110 (uintmax_t)val,
111 want_rv, vis_arr(want_buf, want_bufsize),
112 rv, vis_arr(buf, want_bufsize));
113 check_unmodified_loc(file, line, buf, want_bufsize, sizeof(buf));
114 }
115
116 #define h_snprintb_len(bufsize, bitfmt, val, want_rv, want_buf) \
117 h_snprintb_loc(__FILE__, __LINE__, \
118 bufsize, bitfmt, sizeof(bitfmt) - 1, val, \
119 want_rv, want_buf, sizeof(want_buf))
120 #define h_snprintb(bitfmt, val, want_buf) \
121 h_snprintb_len(1024, bitfmt, val, sizeof(want_buf) - 1, want_buf)
122
123 static void
124 h_snprintb_error_loc(const char *file, size_t line,
125 const char *bitfmt, size_t bitfmtlen)
126 {
127 char buf[1024];
128
129 memset(buf, 'Z', sizeof(buf));
130 int rv = snprintb(buf, sizeof(buf), bitfmt, 0);
131 size_t buflen = rv;
132
133 ATF_REQUIRE(rv >= -1);
134 ATF_CHECK_MSG(rv == -1,
135 "expected error but got success:\n"
136 "\ttest case: %s:%zu\n"
137 "\tformat: %s\n"
138 "\tresult: %zu bytes %s\n",
139 file, line,
140 vis_arr(bitfmt, bitfmtlen),
141 buflen, vis_arr(buf, buflen));
142 }
143
144 #define h_snprintb_error(bitfmt) \
145 h_snprintb_error_loc(__FILE__, __LINE__, bitfmt, sizeof(bitfmt) - 1)
146
147 ATF_TC(snprintb);
148 ATF_TC_HEAD(snprintb, tc)
149 {
150 atf_tc_set_md_var(tc, "descr", "Checks snprintb(3)");
151 }
152 ATF_TC_BODY(snprintb, tc)
153 {
154
155 // style and number base, old style, octal, zero value
156 //
157 // The value 0 does not get a leading '0'.
158 h_snprintb(
159 "\010",
160 0,
161 "0");
162
163 // style and number base, old style, octal, nonzero value
164 //
165 // Nonzero octal values get a leading '0'.
166 h_snprintb(
167 "\010",
168 0xff,
169 "0377");
170
171 // style and number base, old style, decimal, zero value
172 h_snprintb(
173 "\012",
174 0,
175 "0");
176
177 // style and number base, old style, decimal, nonzero value
178 h_snprintb(
179 "\012",
180 0xff,
181 "255");
182
183 // style and number base, old style, hexadecimal, zero value
184 //
185 // The value 0 does not get a leading '0x'.
186 h_snprintb(
187 "\020",
188 0,
189 "0");
190
191 // style and number base, old style, hexadecimal, nonzero value
192 //
193 // Nonzero hexadecimal values get a leading '0x'.
194 h_snprintb(
195 "\177\020",
196 0xff,
197 "0xff");
198
199 // style and number base, old style, invalid base 0
200 h_snprintb_error(
201 "");
202
203 // style and number base, old style, invalid base 2
204 h_snprintb_error(
205 "\002");
206
207 // style and number base, old style, invalid base 255 or -1
208 h_snprintb_error(
209 "\377");
210
211 // style and number base, new style, octal, zero value
212 //
213 // The value 0 does not get a leading '0'.
214 h_snprintb(
215 "\177\010",
216 0,
217 "0");
218
219 // style and number base, new style, octal, nonzero value
220 //
221 // Nonzero octal values get a leading '0'.
222 h_snprintb(
223 "\177\010",
224 0xff,
225 "0377");
226
227 // style and number base, new style, decimal, zero value
228 h_snprintb(
229 "\177\012",
230 0,
231 "0");
232
233 // style and number base, new style, decimal, nonzero value
234 h_snprintb(
235 "\177\012",
236 0xff,
237 "255");
238
239 // style and number base, new style, hexadecimal, zero value
240 //
241 // The value 0 does not get a leading '0x'.
242 h_snprintb(
243 "\177\020",
244 0,
245 "0");
246
247 // style and number base, new style, hexadecimal, nonzero value
248 //
249 // Nonzero hexadecimal values get a leading '0x'.
250 h_snprintb(
251 "\177\020",
252 0xff,
253 "0xff");
254
255 // style and number base, new style, invalid number base 0
256 h_snprintb_error(
257 "\177");
258
259 // style and number base, new style, invalid number base 2
260 h_snprintb_error(
261 "\177\002");
262
263 // style and number base, new style, invalid number base 255 or -1
264 h_snprintb_error(
265 "\177\377");
266
267 // old style, from lsb to msb
268 h_snprintb(
269 "\020"
270 "\001bit1"
271 "\002bit2"
272 "\037bit31"
273 "\040bit32",
274 0xffffffff80000001,
275 "0xffffffff80000001<bit1,bit32>");
276
277 // old style, invalid bit number, at the beginning
278 #if 0 /* undefined behavior due to out-of-bounds bit shift */
279 h_snprintb_error(
280 "\020"
281 "\041invalid");
282 #endif
283
284 // old style, invalid bit number, in the middle
285 //
286 // The old-style format supports only 32 bits, interpreting the
287 // \041 as part of the text belonging to bit 1.
288 h_snprintb(
289 "\020"
290 "\001bit1"
291 "\041bit33",
292 0x1,
293 "0x1<bit1!bit33>");
294
295 // old style, repeated bit numbers
296 //
297 // When a bit number is mentioned more than once,
298 // this is most likely a typo.
299 h_snprintb(
300 "\020"
301 "\001once"
302 "\001again",
303 0x1,
304 "0x1<once,again>");
305
306 // old style, non-printable description
307 //
308 // The characters ' ' and '\t' are interpreted as bit numbers,
309 // not as part of the description; the visual arrangement is
310 // misleading.
311 h_snprintb(
312 "\020"
313 "\001least significant"
314 "\002horizontal\ttab",
315 0xff,
316 "0xff<least,horizontal>");
317
318 // old style, empty description
319 //
320 // Empty descriptions result in multiple commas in a row, which is a
321 // mistake.
322 h_snprintb(
323 "\020"
324 "\001lsb"
325 "\004"
326 "\005"
327 "\010msb",
328 0xff,
329 "0xff<lsb,,,msb>");
330
331 // old style, buffer size 0
332 //
333 // With the buffer size being 0, the buffer is not modified at all.
334 // In kernel mode, the buffer is zeroed out and thus must not be null.
335 h_snprintb_len(
336 0, "\020", 0,
337 1, "");
338
339 // old style, buffer too small for value
340 h_snprintb_len(
341 1, "\020", 0,
342 1, "");
343
344 // old style, buffer large enough for zero value
345 h_snprintb_len(
346 2, "\020", 0,
347 1, "0");
348
349 // old style, buffer larger than necessary for zero value
350 h_snprintb_len(
351 3, "\020", 0,
352 1, "0");
353
354 // old style, buffer too small for nonzero value
355 h_snprintb_len(
356 3, "\020", 7,
357 3, "0x");
358
359 // old style, buffer large enough for nonzero value
360 h_snprintb_len(
361 4, "\020", 7,
362 3, "0x7");
363
364 // old style, buffer too small for '<'
365 h_snprintb_len(
366 4, "\020\001lsb", 7,
367 8, "0x7");
368
369 // old style, buffer too small for description
370 h_snprintb_len(
371 7, "\020\001lsb", 7,
372 8, "0x7<ls");
373
374 // old style, buffer too small for '>'
375 h_snprintb_len(
376 8, "\020\001lsb", 7,
377 8, "0x7<lsb");
378
379 // old style, buffer large enough for '<'
380 h_snprintb_len(
381 9, "\020\001lsb", 7,
382 8, "0x7<lsb>");
383
384 // old style, buffer too small for second description
385 h_snprintb_len(
386 9, "\020\001one\002two", 7,
387 12, "0x7<one,");
388
389 // old style, buffer too small for second description
390 h_snprintb_len(
391 10, "\020\001one\002two", 7,
392 12, "0x7<one,t");
393
394 // old style, buffer too small for '>' after second description
395 h_snprintb_len(
396 12, "\020\001one\002two", 7,
397 12, "0x7<one,two");
398
399 // old style, buffer large enough for '>' after second description
400 h_snprintb_len(
401 13, "\020\001one\002two", 7,
402 12, "0x7<one,two>");
403
404 // new style single bits
405 h_snprintb(
406 "\177\020"
407 "b\000lsb\0"
408 "b\001above-lsb\0"
409 "b\037bit31\0"
410 "b\040bit32\0"
411 "b\076below-msb\0"
412 "b\077msb\0",
413 0x8000000180000001,
414 "0x8000000180000001<lsb,bit31,bit32,msb>");
415
416 // new style single bits, duplicate bits
417 h_snprintb(
418 "\177\020"
419 "b\000lsb\0"
420 "b\000lsb\0"
421 "b\000lsb\0",
422 0xff,
423 "0xff<lsb,lsb,lsb>");
424
425 // new style single bits, empty description
426 h_snprintb(
427 "\177\020"
428 "b\000lsb\0"
429 "b\001\0"
430 "b\002\0"
431 "b\007msb\0"
432 ,
433 0xff,
434 "0xff<lsb,,,msb>");
435
436 // new style single bits, invalid
437 #if 0 /* undefined behavior due to out-of-bounds bit shift */
438 h_snprintb_error(
439 "\177\020"
440 "b\100too-high\0");
441 #endif
442 #if 0 /* undefined behavior due to out-of-bounds bit shift */
443 h_snprintb_error(
444 "\177\020"
445 "b\377too-high\0");
446 #endif
447
448 // new style single bits, non-printable description
449 //
450 // Contrary to the old-style format, the new-style format allows
451 // arbitrary characters in the description, even control characters
452 // and non-ASCII characters.
453 h_snprintb(
454 "\177\020"
455 "b\000space \t \xC3\xA4\0",
456 0x1,
457 "0x1<space \t \xC3\xA4>");
458
459 // new style named bit-field, octal
460 //
461 // The bit-field value gets a leading '0' iff it is nonzero.
462 h_snprintb(
463 "\177\010"
464 "f\000\010byte0\0"
465 "f\010\010byte1\0",
466 0x0100,
467 "0400<byte0=0,byte1=01>");
468
469 // new style named bit-field, decimal
470 h_snprintb(
471 "\177\012"
472 "f\000\010byte0\0"
473 "f\010\010byte1\0",
474 0x0100,
475 "256<byte0=0,byte1=1>");
476
477 // new style named bit-field, hexadecimal
478 h_snprintb(
479 "\177\020"
480 "f\000\010byte0\0"
481 "f\010\010byte1\0",
482 0x0100,
483 "0x100<byte0=0,byte1=0x1>");
484
485 // new style bit-field, from 0 width 0
486 h_snprintb(
487 "\177\020"
488 "f\000\000zero-width\0"
489 "=\000zero\0",
490 0xffff,
491 "0xffff<zero-width=0=zero>");
492
493 // new style bit-field, from 0 width 1
494 h_snprintb(
495 "\177\020"
496 "f\000\001lsb\0"
497 "=\000zero\0"
498 "=\001one\0",
499 0x0,
500 "0<lsb=0=zero>");
501 h_snprintb(
502 "\177\020"
503 "f\000\001lsb\0"
504 "=\000zero\0"
505 "=\001one\0",
506 0x1,
507 "0x1<lsb=0x1=one>");
508
509 // new style bit-field, from 0 width 63
510 h_snprintb(
511 "\177\020"
512 "f\000\077uint63\0"
513 "=\125match\0",
514 0xaaaa5555aaaa5555,
515 "0xaaaa5555aaaa5555<uint63=0x2aaa5555aaaa5555>");
516
517 // new style bit-field, from 0 width 64
518 #if 0 /* undefined behavior due to out-of-bounds bit shift */
519 h_snprintb(
520 "\177\020"
521 "f\000\100uint64\0"
522 "=\125match\0",
523 0xaaaa5555aaaa5555,
524 "0xaaaa5555aaaa5555<uint64=0xaaaa5555aaaa5555>");
525 #endif
526
527 // new style bit-field, from 0 width 65
528 #if 0 /* undefined behavior due to out-of-bounds bit shift */
529 h_snprintb_error(
530 "\177\020"
531 "f\000\101uint65\0");
532 #endif
533
534 // new style bit-field, from 1 width 8
535 h_snprintb(
536 "\177\020"
537 "f\001\010uint8\0"
538 "=\203match\0",
539 0x0106,
540 "0x106<uint8=0x83=match>");
541
542 // new style bit-field, from 1 width 9
543 //
544 // The '=' and ':' directives can only match a bit-field value between
545 // 0 and 255, independent of the bit-field's width.
546 h_snprintb(
547 "\177\020"
548 "f\001\011uint9\0"
549 "=\203match\0"
550 "*=other-f\0"
551 "F\001\011\0"
552 ":\203match\0"
553 "*other-F\0",
554 0x0306,
555 "0x306<uint9=0x183=other-f,other-F>");
556
557 // new style bit-field, from 32 width 32
558 h_snprintb(
559 "\177\020"
560 "f\040\040uint32\0",
561 0xaaaa555500000000,
562 "0xaaaa555500000000<uint32=0xaaaa5555>");
563
564 // new style bit-field, from 60 width 4
565 h_snprintb(
566 "\177\020"
567 "f\074\004uint4\0",
568 0xf555555555555555,
569 "0xf555555555555555<uint4=0xf>");
570
571 // new style bit-field, from 60 width 5
572 //
573 // The end of the bit-field is out of bounds.
574 h_snprintb(
575 "\177\020"
576 "f\074\005uint5\0",
577 0xf555555555555555,
578 "0xf555555555555555<uint5=0xf>");
579
580 // new style bit-field, from 64 width 0
581 //
582 // The beginning of the bit-field is out of bounds, the end is fine.
583 #if 0 /* undefined behavior due to out-of-bounds bit shift */
584 h_snprintb_error(
585 "\177\020"
586 "f\100\000uint0\0");
587 #endif
588
589 // new style bit-field, from 65 width 0
590 //
591 // The beginning and end of the bit-field are out of bounds.
592 #if 0 /* undefined behavior due to out-of-bounds bit shift */
593 h_snprintb_error(
594 "\177\020"
595 "f\101\000uint0\0");
596 #endif
597
598 // new style bit-field, empty field description
599 //
600 // The description of a field may be empty, though this is probably a
601 // mistake, as it outputs an isolated '='.
602 h_snprintb(
603 "\177\020"
604 "f\000\004\0"
605 "=\001one\0",
606 0x1,
607 "0x1<=0x1=one>");
608
609 // new style bit-field, non-printable description
610 //
611 // Contrary to the old-style format, the new-style format allows
612 // arbitrary characters in the description, even control characters
613 // and non-ASCII characters.
614 h_snprintb(
615 "\177\020"
616 "f\000\010\t \xC3\xA4\0"
617 "=\001\t \xC3\xA4\0"
618 "F\000\010\0"
619 ":\001\t \xC3\xA4\0"
620 "F\000\010\0"
621 "*\t \xC3\xA4\0",
622 0x1,
623 "0x1<\t \xC3\xA4=0x1=\t \xC3\xA4,\t \xC3\xA4,\t \xC3\xA4>");
624
625 // new style bit-field, '=' with empty description
626 //
627 // The description of a '=' directive may be empty, though this is
628 // probably a mistake, as it outputs several '=' in a row.
629 h_snprintb(
630 "\177\020"
631 "f\000\004f\0"
632 "=\001one\0"
633 "=\001\0"
634 "=\001\0",
635 0x1,
636 "0x1<f=0x1=one==>");
637
638 // new style bit-field, 'F' followed by ':' with empty description
639 //
640 // The description of a ':' directive may be empty, though this is
641 // probably a mistake, as it leads to empty angle brackets.
642 h_snprintb(
643 "\177\020"
644 "F\000\004\0"
645 ":\001\0"
646 "*default\0",
647 0x1,
648 "0x1<>");
649
650 // new style bit-field, 'F', ':' with empty description, '*'
651 //
652 // The ':' directive could be used to suppress a following '*'
653 // directive, but this combination is probably a mistake, as a
654 // matching ':' leads to empty angle brackets.
655 h_snprintb(
656 "\177\020"
657 "F\000\004\0"
658 ":\001\0"
659 "*default\0",
660 0x2,
661 "0x2<default>");
662
663 // new style bit-field, 'f' with non-exhaustive '='
664 h_snprintb(
665 "\177\020"
666 "f\000\004Field\0"
667 "=\1one\0"
668 "=\2two\0",
669 0x3,
670 "0x3<Field=0x3>");
671
672 // new style bit-field, 'F' with non-exhaustive ':'
673 //
674 // A bit-field that does not match any values still generates empty
675 // angle brackets.
676 h_snprintb(
677 "\177\020"
678 "F\000\004\0"
679 ":\1one\0"
680 ":\2two\0",
681 0x3,
682 "0x3<>");
683
684 // new style bit-field, 'F' with non-exhaustive ':'
685 //
686 // A bit-field that does not match any values still generates empty
687 // angle brackets or adjacent commas.
688 h_snprintb(
689 "\177\020"
690 "b\000bit0\0"
691 "F\000\004\0"
692 ":\1one\0"
693 ":\2two\0"
694 "b\001bit1\0",
695 0x3,
696 "0x3<bit0,,bit1>");
697
698 // new style, two separate bit-fields
699 h_snprintb(
700 "\177\020"
701 "f\000\004f1\0"
702 "=\001one\0"
703 "=\002two\0"
704 "f\004\004f2\0"
705 "=\001one\0"
706 "=\002two\0",
707 0x12,
708 "0x12<f1=0x2=two,f2=0x1=one>");
709
710 // new style, mixed named and unnamed bit-fields
711 h_snprintb(
712 "\177\020"
713 "f\000\004f1\0"
714 "=\001one\0"
715 "=\002two\0"
716 "F\010\004\0"
717 ":\015thirteen\0"
718 "f\004\004f2\0"
719 "=\001one\0"
720 "=\002two\0",
721 0x0d12,
722 "0xd12<f1=0x2=two,thirteen,f2=0x1=one>");
723
724 // new style bit-field, overlapping
725 h_snprintb(
726 "\177\020"
727 "f\000\004lo\0"
728 "f\002\004mid\0"
729 "f\004\004hi\0"
730 "f\000\010all\0",
731 0x18,
732 "0x18<lo=0x8,mid=0x6,hi=0x1,all=0x18>");
733
734 // new style bit-field, difference between '=' and ':'
735 //
736 // The ':' directive can almost emulate the '=' directive, without the
737 // numeric output and with a different separator. It's best to use
738 // either 'f' with '=' or 'F' with ':', but not mix them.
739 h_snprintb(
740 "\177\020"
741 "f\000\004field\0"
742 "=\010value\0"
743 "F\000\000\0"
744 ":\000field\0" // Since the description of 'F' is ignored.
745 "F\000\004\0"
746 ":\010value\0",
747 0x18,
748 "0x18<field=0x8=value,field,value>");
749
750 // new style bit-field default, fixed string
751 //
752 // The 'f' directive pairs up with the '=' directive,
753 // the 'F' directive pairs up with the ':' directive,
754 // but there's only one 'default' directive for both variants,
755 // so its description should include the '=' when used with 'f' but
756 // not with 'F'.
757 h_snprintb(
758 "\177\020"
759 "f\030\010f1\0"
760 "*default\0"
761 "f\020\010f2\0"
762 "*=default\0"
763 "F\010\010\0"
764 "*default\0"
765 "F\010\010\0"
766 "*=default\0",
767 0x11223344,
768 "0x11223344<f1=0x11default,f2=0x22=default,default,=default>");
769
770 // new style bit-field default, numeric conversion specifier
771 h_snprintb(
772 "\177\020"
773 "f\010\010f\0"
774 "*=f(%ju)\0"
775 "F\000\010F\0"
776 "*F(%ju)\0",
777 0x1122,
778 "0x1122<f=0x11=f(17),F(34)>");
779
780 // new style bit-field default, invalid conversion specifier
781 //
782 // There is no reliable way to make snprintf return an error, as such
783 // errors are defined as undefined behavior in the C standard.
784 // Instead, here's a conversion specifier that produces a literal '%'.
785 h_snprintb(
786 "\177\020"
787 "f\000\010f\0"
788 "*=%030ju%%\0",
789 0xff,
790 "0xff<f=0xff=000000000000000000000000000255%>");
791
792 // new style unknown directive
793 //
794 // Unknown directives are assumed to have a single byte argument
795 // followed by a description; they are skipped up to the next '\0'.
796 h_snprintb(
797 "\177\020"
798 "c\010ignored\0"
799 "c\000b\0"
800 "lsb\0"
801 "b\007msb\0",
802 0xff,
803 "0xff<msb>");
804
805 // new style combinations, 'b' '='
806 //
807 // A '=' directive without a preceding 'f' or 'F' directive applies to
808 // the whole value; its description may appear inside or outside the
809 // angle brackets. Having such a format is likely an error.
810 h_snprintb(
811 "\177\020"
812 "b\004bit4\0"
813 "=\000clear\0"
814 "=\001set\0"
815 "=\245complete\0"
816 "b\000bit0\0"
817 "=\000clear\0"
818 "=\001set\0"
819 "=\245complete\0",
820 0xa5,
821 "0xa5=complete<bit0=complete>");
822
823 // new style combinations, 'b' ':'
824 //
825 // A ':' directive without a preceding 'f' or 'F' directive applies to
826 // the whole value; its description may appear inside or outside the
827 // angle brackets. Having such a format is likely an error.
828 h_snprintb(
829 "\177\020"
830 "b\004bit4\0"
831 ":\000clear\0"
832 ":\001set\0"
833 ":\245complete\0"
834 "b\000bit0\0"
835 ":\000clear\0"
836 ":\001set\0"
837 ":\245complete\0",
838 0xa5,
839 "0xa5complete<bit0complete>");
840
841 // new style combinations, 'b' '*'
842 //
843 // A '*' directive without a preceding 'f' or 'F' directive is ignored.
844 h_snprintb(
845 "\177\020"
846 "b\004bit4\0"
847 "*default(%ju)\0"
848 "b\000bit0\0"
849 "*default(%ju)\0",
850 0xa5,
851 "0xa5<bit0>");
852
853 // new style combinations, 'f' 'b' '='
854 //
855 // Between an 'f' and an '=' directive, there may be unrelated 'b'
856 // directives, they do not affect the value of the "previous field".
857 // Formats like these are probably mistakes.
858 h_snprintb(
859 "\177\020"
860 "f\000\010f\0"
861 "b\005bit5\0"
862 "=\xa5match\0",
863 0xa5,
864 "0xa5<f=0xa5,bit5=match>");
865
866 // new style combinations, 'f' 'b' ':'
867 //
868 // Between an 'f' and a ':' directive, there may be unrelated 'b'
869 // directives, they do not affect the value of the "previous field".
870 // Formats like these are mistakes, as the output is garbled.
871 h_snprintb(
872 "\177\020"
873 "f\000\010f\0"
874 "b\005bit5\0"
875 ":\xa5match\0",
876 0xa5,
877 "0xa5<f=0xa5,bit5match>");
878
879 // new style combinations, 'f' ':'
880 h_snprintb(
881 "\177\20"
882 "f\000\004nibble\0"
883 ":\001one\0",
884 0x01,
885 "0x1<nibble=0x1one>");
886
887 // new style combinations, 'F' '='
888 //
889 // Combining the 'F' and '=' directives outputs an isolated '=', which
890 // doesn't look well-formed.
891 h_snprintb(
892 "\177\20"
893 "F\000\004\0"
894 "=\001one\0",
895 0x01,
896 "0x1<=one>");
897
898 // new style combinations, '='
899 //
900 // A '=' directive without a preceding 'f' or 'F' directive matches on
901 // the complete value. This is not documented in the manual page, and
902 // formats like these are probably mistakes.
903 h_snprintb(
904 "\177\020"
905 "=\xa5match\0",
906 0xa5,
907 "0xa5=match");
908
909 // new style combinations, ':'
910 //
911 // A ':' directive without a preceding 'f' or 'F' directive matches on
912 // the complete value. This is not documented in the manual page, and
913 // formats like these are probably mistakes.
914 h_snprintb(
915 "\177\020"
916 ":\xa5match\0",
917 0xa5,
918 "0xa5match");
919
920 // new style combinations, '*'
921 //
922 // A '*' directive without a preceding 'f' or 'F' is skipped. Formats
923 // like these are mistakes.
924 h_snprintb(
925 "\177\020"
926 "*match\0",
927 0xa5,
928 "0xa5");
929
930 // new style combinations, 'f' '*' '='
931 //
932 // A '*' directive may be followed by a '=' directive. Formats like
933 // this are probably a mistake.
934 h_snprintb(
935 "\177\020"
936 "f\000\010f\0"
937 "*=default\0"
938 "=\xa5match\0",
939 0xa5,
940 "0xa5<f=0xa5=default=match>");
941
942 // new style combinations, 'F' '*' ':'
943 //
944 // A '*' directive may be followed by a ':' directive. Formats like
945 // this are probably a mistake.
946 h_snprintb(
947 "\177\020"
948 "F\000\010F\0"
949 "*default\0"
950 ":\xa5-match\0",
951 0xa5,
952 "0xa5<default-match>");
953
954 // new style combinations, '*' '*'
955 //
956 // The first '*' directive matches everything, so the second '*'
957 // directive cannot match anything and is thus redundant. Formats like
958 // this are a mistake.
959 h_snprintb(
960 "\177\020"
961 "f\000\010f\0"
962 "*=default-f\0"
963 "*ignored\0"
964 "F\000\010\0"
965 "*default-F\0"
966 "*ignored\0",
967 0xa5,
968 "0xa5<f=0xa5=default-f,default-F>");
969
970 // manual page, old style octal
971 h_snprintb(
972 "\10\2BITTWO\1BITONE",
973 3,
974 "03<BITTWO,BITONE>");
975
976 // manual page, old style hexadecimal
977 h_snprintb(
978 "\20"
979 "\x10NOTBOOT" "\x0f""FPP" "\x0eSDVMA"
980 "\x0cVIDEO" "\x0bLORES" "\x0a""FPA" "\x09""DIAG"
981 "\x07""CACHE" "\x06IOCACHE" "\x05LOOPBACK"
982 "\x04""DBGCACHE",
983 0xe860,
984 "0xe860<NOTBOOT,FPP,SDVMA,VIDEO,CACHE,IOCACHE>");
985
986 // manual page, new style bits and fields
987 h_snprintb(
988 "\177\020"
989 "b\0LSB\0" "b\1BITONE\0"
990 "f\4\4NIBBLE2\0"
991 "f\x10\4BURST\0" "=\4FOUR\0" "=\xf""FIFTEEN\0"
992 "b\x1fMSB\0",
993 0x800f0701,
994 "0x800f0701<LSB,NIBBLE2=0,BURST=0xf=FIFTEEN,MSB>");
995
996 // manual page, new style mmap
997 #define MAP_FMT \
998 "\177\020" \
999 "b\0" "SHARED\0" \
1000 "b\1" "PRIVATE\0" \
1001 "b\2" "COPY\0" \
1002 "b\4" "FIXED\0" \
1003 "b\5" "RENAME\0" \
1004 "b\6" "NORESERVE\0" \
1005 "b\7" "INHERIT\0" \
1006 "b\11" "HASSEMAPHORE\0" \
1007 "b\12" "TRYFIXED\0" \
1008 "b\13" "WIRED\0" \
1009 "F\14\1\0" \
1010 ":\0" "FILE\0" \
1011 ":\1" "ANONYMOUS\0" \
1012 "b\15" "STACK\0" \
1013 "F\30\010\0" \
1014 ":\000" "ALIGN=NONE\0" \
1015 ":\015" "ALIGN=8KB\0" \
1016 "*" "ALIGN=2^%ju\0"
1017 h_snprintb(
1018 MAP_FMT,
1019 0x0d001234,
1020 "0xd001234<COPY,FIXED,RENAME,HASSEMAPHORE,ANONYMOUS,ALIGN=8KB>");
1021 h_snprintb(
1022 MAP_FMT,
1023 0x2e000000,
1024 "0x2e000000<FILE,ALIGN=2^46>");
1025
1026 // It is possible but cumbersome to implement a reduced variant of
1027 // rot13 using snprintb, shown here for lowercase letters only.
1028 for (char ch = 'A'; ch <= '~'; ch++) {
1029 char rot13 = ch >= 'a' && ch <= 'm' ? ch + 13
1030 : ch >= 'n' && ch <= 'z' ? ch - 13
1031 : '?';
1032 char expected[8];
1033 ATF_REQUIRE_EQ(7,
1034 snprintf(expected, sizeof(expected), "%#x<%c>", ch, rot13));
1035 h_snprintb(
1036 "\177\020"
1037 "F\000\010\0"
1038 ":an\0:bo\0:cp\0:dq\0:er\0:fs\0:gt\0:hu\0"
1039 ":iv\0:jw\0:kx\0:ly\0:mz\0"
1040 ":na\0:ob\0:pc\0:qd\0:re\0:sf\0:tg\0:uh\0"
1041 ":vi\0:wj\0:xk\0:yl\0:zm\0"
1042 // If snprintf accepted "%jc", it would be possible to
1043 // echo the non-alphabetic characters instead of a
1044 // catchall question mark.
1045 "*?\0",
1046 ch,
1047 expected);
1048 }
1049
1050 // new style, small buffers
1051 h_snprintb_len(
1052 0, "\177\020", 0,
1053 1, "");
1054 h_snprintb_len(
1055 1, "\177\020", 0,
1056 1, "");
1057 h_snprintb_len(
1058 2, "\177\020", 0,
1059 1, "0");
1060 h_snprintb_len(
1061 3, "\177\020", 0,
1062 1, "0");
1063 h_snprintb_len(
1064 3, "\177\020", 7,
1065 3, "0x");
1066 h_snprintb_len(
1067 4, "\177\020", 7,
1068 3, "0x7");
1069 h_snprintb_len(
1070 7, "\177\020b\000lsb\0", 7,
1071 8, "0x7<ls");
1072 h_snprintb_len(
1073 8, "\177\020b\000lsb\0", 7,
1074 8, "0x7<lsb");
1075 h_snprintb_len(
1076 9, "\177\020b\000lsb\0", 7,
1077 8, "0x7<lsb>");
1078 h_snprintb_len(
1079 9, "\177\020b\000one\0b\001two\0", 7,
1080 12, "0x7<one,");
1081 h_snprintb_len(
1082 10, "\177\020b\000one\0b\001two\0", 7,
1083 12, "0x7<one,t");
1084 h_snprintb_len(
1085 12, "\177\020b\000one\0b\001two\0", 7,
1086 12, "0x7<one,two");
1087 h_snprintb_len(
1088 13, "\177\020b\000one\0b\001two\0", 7,
1089 12, "0x7<one,two>");
1090 }
1091
1092 static void
1093 h_snprintb_m_loc(const char *file, size_t line,
1094 size_t bufsize, const char *bitfmt, size_t bitfmtlen, uint64_t val,
1095 size_t max,
1096 size_t want_rv, const char *want_buf, size_t want_bufsize)
1097 {
1098 char buf[1024];
1099
1100 ATF_REQUIRE(bufsize > 0);
1101 ATF_REQUIRE(bufsize <= sizeof(buf));
1102 ATF_REQUIRE(want_bufsize <= sizeof(buf));
1103 if (bitfmtlen > 2 && bitfmt[0] == '\177')
1104 ATF_REQUIRE_MSG(bitfmt[bitfmtlen - 1] == '\0',
1105 "%s:%zu: missing trailing '\\0' in bitfmt",
1106 file, line);
1107
1108 memset(buf, 'Z', sizeof(buf));
1109 int rv = snprintb_m(buf, bufsize, bitfmt, val, max);
1110 ATF_REQUIRE_MSG(rv >= 0,
1111 "formatting %jx with '%s' returns error %d",
1112 (uintmax_t)val, vis_arr(bitfmt, bitfmtlen), rv);
1113
1114 size_t total = rv;
1115 ATF_CHECK_MSG(
1116 total == want_rv
1117 && memcmp(buf, want_buf, want_bufsize) == 0
1118 && (bufsize < 1
1119 || buf[total < bufsize ? total : bufsize - 1] == '\0')
1120 && (bufsize < 2
1121 || buf[total < bufsize ? total - 1 : bufsize - 2] == '\0'),
1122 "failed:\n"
1123 "\ttest case: %s:%zu\n"
1124 "\tformat: %s\n"
1125 "\tvalue: %#jx\n"
1126 "\tmax: %zu\n"
1127 "\twant: %zu bytes %s\n"
1128 "\thave: %zu bytes %s\n",
1129 file, line,
1130 vis_arr(bitfmt, bitfmtlen),
1131 (uintmax_t)val,
1132 max,
1133 want_rv, vis_arr(want_buf, want_bufsize),
1134 total, vis_arr(buf, want_bufsize));
1135 check_unmodified_loc(file, line, buf, want_bufsize, sizeof(buf));
1136 }
1137
1138 #define h_snprintb_m_len(bufsize, bitfmt, val, line_max, want_rv, want_buf) \
1139 h_snprintb_m_loc(__FILE__, __LINE__, \
1140 bufsize, bitfmt, sizeof(bitfmt) - 1, val, line_max, \
1141 want_rv, want_buf, sizeof(want_buf))
1142 #define h_snprintb_m(bitfmt, val, line_max, want_buf) \
1143 h_snprintb_m_len(1024, bitfmt, val, line_max, \
1144 sizeof(want_buf) - 1, want_buf)
1145
1146 ATF_TC(snprintb_m);
1147 ATF_TC_HEAD(snprintb_m, tc)
1148 {
1149 atf_tc_set_md_var(tc, "descr", "Checks snprintb_m(3)");
1150 }
1151 ATF_TC_BODY(snprintb_m, tc)
1152 {
1153
1154 // old style, line_max exceeded by number in line 1
1155 h_snprintb_m(
1156 "\020",
1157 0xff,
1158 1,
1159 "0xff\0"); // FIXME: line longer than line_max
1160
1161 // old style, line_max exceeded by '<' in line 1
1162 h_snprintb_m(
1163 "\020",
1164 0xff,
1165 4,
1166 "0xff\0");
1167
1168 // old style, line_max exceeded by description in line 1
1169 h_snprintb_m(
1170 "\020"
1171 "\001bit1"
1172 "\002bit2",
1173 0xff,
1174 4,
1175 "0xff>\0" // FIXME: unbalanced angle brackets
1176 "0xff<>\0" // FIXME: empty angle brackets
1177 "0xffb>\0" // FIXME: partial description
1178 "0xffi>\0"
1179 "0xfft>\0"
1180 "0xff1>\0"
1181 "0xff<>\0" // FIXME: empty angle brackets
1182 "0xffb>\0" // FIXME: partial description
1183 "0xffi>\0"
1184 "0xfft>\0"
1185 "0xff2>\0");
1186
1187 // old style, line_max exceeded by '>' in line 1
1188 h_snprintb_m(
1189 "\020"
1190 "\001bit1"
1191 "\0022",
1192 0xff,
1193 9,
1194 "0xff<bit>\0"
1195 "0xff1,2>\0");
1196
1197 // old style, line_max exceeded by description in line 2
1198 h_snprintb_m(
1199 "\020"
1200 "\0011"
1201 "\002bit2",
1202 0xff,
1203 8,
1204 "0xff<1>\0"
1205 "0xff<bi>\0" // FIXME: incomplete description
1206 "0xfft2>\0"); // FIXME: unbalanced angle brackets
1207
1208 // old style, line_max exceeded by '>' in line 2
1209 h_snprintb_m(
1210 "\020"
1211 "\0011"
1212 "\002bit2",
1213 0xff,
1214 9,
1215 "0xff<1>\0"
1216 "0xff<bit>\0" // FIXME: incomplete description
1217 "0xff2>\0"); // FIXME: unbalanced angle brackets
1218
1219 // old style complete
1220 h_snprintb_m(
1221 "\020"
1222 "\0011"
1223 "\002bit2",
1224 0xff,
1225 10,
1226 "0xff<1>\0"
1227 "0xff<bit2>\0");
1228
1229 // new style, line_max exceeded by value in line 1
1230 h_snprintb_m(
1231 "\177\020",
1232 0xff,
1233 1,
1234 "0xff\0"); // FIXME: line too long
1235
1236 // new style, line_max exceeded by single-bit '<' in line 1
1237 h_snprintb_m(
1238 "\177\020"
1239 "b\000bit\0",
1240 0xff,
1241 4,
1242 "0xff>\0" // FIXME: unbalanced angle brackets
1243 "0xff<>\0"
1244 "0xffb>\0"
1245 "0xffi>\0"
1246 "0xfft>\0"); // FIXME: line too long
1247
1248 // new style, line_max exceeded by single-bit description in line 1
1249 h_snprintb_m(
1250 "\177\020"
1251 "b\000bit0\0"
1252 "b\001two\0",
1253 0xff,
1254 8,
1255 "0xff<bi>\0" // FIXME: incomplete description
1256 "0xfft0>\0" // FIXME: unbalanced angle brackets
1257 "0xff<tw>\0" // FIXME: incomplete description
1258 "0xffo>\0"); // FIXME: unbalanced angle brackets
1259
1260 // new style, line_max exceeded by single-bit '>' in line 1
1261 h_snprintb_m(
1262 "\177\020"
1263 "b\000bit0\0"
1264 "b\001two\0",
1265 0xff,
1266 9,
1267 "0xff<bit>\0" // FIXME: incomplete description
1268 "0xff0>\0" // FIXME: empty angle brackets
1269 "0xff<two>\0"); // FIXME: incomplete description
1270
1271 // new style, line_max exceeded by single-bit description in line 2
1272 h_snprintb_m(
1273 "\177\020"
1274 "b\000one\0"
1275 "b\001three\0",
1276 0xff,
1277 9,
1278 "0xff<one>\0"
1279 "0xff<thr>\0" // FIXME: incomplete description
1280 "0xffee>\0"); // FIXME: unbalanced angle brackets
1281
1282 // new style, line_max exceeded by single-bit '>' in line 2
1283 h_snprintb_m(
1284 "\177\020"
1285 "b\000one\0"
1286 "b\001four\0",
1287 0xff,
1288 9,
1289 "0xff<one>\0"
1290 "0xff<fou>\0" // FIXME: incomplete description
1291 "0xffr>\0"); // FIXME: unbalanced angle brackets
1292
1293 // new style, single-bit complete
1294 h_snprintb_m(
1295 "\177\020"
1296 "b\000one\0"
1297 "b\001three\0",
1298 0xff,
1299 11,
1300 "0xff<one>\0"
1301 "0xff<three>\0");
1302
1303 // new style, line_max exceeded by named bit-field number in line 1
1304 h_snprintb_m(
1305 "\177\020"
1306 "f\000\004lo\0",
1307 0xff,
1308 3,
1309 "0xff>\0" // FIXME: unbalanced angle brackets
1310 "0xff<>\0"
1311 "0xffl>\0" // FIXME: incomplete bit-field description
1312 "0xffo>\0"
1313 "0xff=0xf>\0" // FIXME: line too long
1314 "0xff#>\0");
1315
1316 // new style, line_max exceeded by named bit-field '<' in line 1
1317 h_snprintb_m(
1318 "\177\020"
1319 "f\000\004lo\0",
1320 0xff,
1321 4,
1322 "0xff>\0" // FIXME: unbalanced angle brackets
1323 "0xff<>\0"
1324 "0xffl>\0" // FIXME: incomplete bit-field description
1325 "0xffo>\0"
1326 "0xff=0xf>\0" // FIXME: line too long
1327 "0xff#>\0");
1328
1329 // new style, line_max exceeded by named bit-field field description in line 1
1330 h_snprintb_m(
1331 "\177\020"
1332 "f\000\004lo\0",
1333 0xff,
1334 6,
1335 "0xff<>\0"
1336 "0xffl>\0"
1337 "0xffo>\0" // FIXME: incomplete bit-field description
1338 "0xff=0xf>\0" // FIXME: line too long
1339 "0xff#>\0");
1340
1341 // new style, line_max exceeded by named bit-field '=' in line 1
1342 h_snprintb_m(
1343 "\177\020"
1344 "f\000\004lo\0",
1345 0xff,
1346 7,
1347 "0xff<l>\0" // FIXME: unbalanced angle brackets
1348 "0xffo=0xf>\0"
1349 "0xff#>\0");
1350
1351 // new style, line_max exceeded by named bit-field value in line 1
1352 h_snprintb_m(
1353 "\177\020"
1354 "f\000\004lo\0",
1355 0xff,
1356 10,
1357 "0xff<lo=0xf>\0" // FIXME: line too long
1358 "0xff#>\0"); // FIXME: unbalanced angle brackets
1359
1360 // new style, line_max exceeded by named bit-field '=' in line 1
1361 h_snprintb_m(
1362 "\177\020"
1363 "f\000\004lo\0"
1364 "=\017match\0",
1365 0xff,
1366 11,
1367 "0xff<lo=0xf>\0" // FIXME: line too long
1368 "0xff=match>\0"); // FIXME: unbalanced angle brackets
1369
1370 // new style, line_max exceeded by named bit-field value description in line 1
1371 h_snprintb_m(
1372 "\177\020"
1373 "f\000\004lo\0"
1374 "=\017match\0",
1375 0xff,
1376 16,
1377 "0xff<lo=0xf=mat>\0" // FIXME: incomplete field description
1378 "0xffch>\0"); // FIXME: unbalanced angle brackets
1379
1380 // new style, line_max exceeded by named bit-field '>' in line 1
1381 h_snprintb_m(
1382 "\177\020"
1383 "f\000\004lo\0"
1384 "=\017match\0",
1385 0xff,
1386 17,
1387 "0xff<lo=0xf=matc>\0" // FIXME: incomplete field description
1388 "0xffh>\0"); // FIXME: unbalanced angle brackets
1389
1390 // new style, line_max exceeded by named bit-field description in line 2
1391 h_snprintb_m(
1392 "\177\020"
1393 "f\000\004lo\0"
1394 "f\000\004low-bits\0"
1395 "=\017match\0",
1396 0xff,
1397 12,
1398 "0xff<lo=0xf>\0"
1399 "0xff<low-bi>\0"
1400 "0xffts=0xf=>\0"
1401 "0xffmatch>\0");
1402
1403 // new style, line_max exceeded by named bit-field '=' in line 2
1404 h_snprintb_m(
1405 "\177\020"
1406 "f\000\004lo\0"
1407 "f\000\004low-bits\0"
1408 "=\017match\0",
1409 0xff,
1410 13,
1411 "0xff<lo=0xf>\0"
1412 "0xff<low-bit>\0"
1413 "0xffs=0xf=ma>\0"
1414 "0xfftch>\0");
1415
1416 // new style, line_max exceeded by named bit-field value in line 2
1417 h_snprintb_m(
1418 "\177\020"
1419 "f\000\004lo\0"
1420 "f\000\004low-bits\0"
1421 "=\017match\0",
1422 0xff,
1423 16,
1424 "0xff<lo=0xf>\0"
1425 "0xff<low-bits=0xf>\0" // FIXME: line too long
1426 "0xff#=match>\0");
1427
1428 // new style, line_max exceeded by named bit-field '=' in line 2
1429 h_snprintb_m(
1430 "\177\020"
1431 "f\000\004lo\0"
1432 "f\000\004low-bits\0"
1433 "=\017match\0",
1434 0xff,
1435 17,
1436 "0xff<lo=0xf>\0"
1437 "0xff<low-bits=0xf>\0" // FIXME: line too long
1438 "0xff=match>\0");
1439
1440 // new style, line_max exceeded by named bit-field value description in line 2
1441 h_snprintb_m(
1442 "\177\020"
1443 "f\000\004lo\0"
1444 "f\000\004low-bits\0"
1445 "=\017match\0",
1446 0xff,
1447 22,
1448 "0xff<lo=0xf>\0"
1449 "0xff<low-bits=0xf=mat>\0" // FIXME: incomplete description
1450 "0xffch>\0");
1451
1452 // new style, line_max exceeded by named bit-field '>' in line 2
1453 h_snprintb_m(
1454 "\177\020"
1455 "f\000\004lo\0"
1456 "f\000\004low-bits\0"
1457 "=\017match\0",
1458 0xff,
1459 23,
1460 "0xff<lo=0xf>\0"
1461 "0xff<low-bits=0xf=matc>\0" // FIXME: incomplete description
1462 "0xffh>\0");
1463
1464 // new style, named bit-field complete
1465 h_snprintb_m(
1466 "\177\020"
1467 "f\000\004lo\0"
1468 "f\000\004low-bits\0"
1469 "=\017match\0",
1470 0xff,
1471 24,
1472 "0xff<lo=0xf>\0"
1473 "0xff<low-bits=0xf=match>\0");
1474
1475 // new style, line_max exceeded by unnamed bit-field number in line 1
1476 h_snprintb_m(
1477 "\177\020"
1478 "F\000\004\0",
1479 0xff,
1480 3,
1481 "0xff>\0" // FIXME: unbalanced angle brackets
1482 "0xff<>\0"); // FIXME: empty angle brackets
1483
1484 // new style, line_max exceeded by unnamed bit-field '<' in line 1
1485 h_snprintb_m(
1486 "\177\020"
1487 "F\000\004\0",
1488 0xff,
1489 4,
1490 "0xff>\0" // FIXME: unbalanced angle brackets
1491 "0xff<>\0"); // FIXME: empty angle brackets
1492
1493 // new style, line_max exceeded by unnamed bit-field value description in line 1
1494 h_snprintb_m(
1495 "\177\020"
1496 "F\000\004\0"
1497 ":\017match\0",
1498 0xff,
1499 9,
1500 "0xff<mat>\0"
1501 "0xffch>\0"); // FIXME: unbalanced angle brackets
1502
1503 // new style, line_max exceeded by unnamed bit-field '>' in line 1
1504 h_snprintb_m(
1505 "\177\020"
1506 "F\000\004\0"
1507 ":\017match\0",
1508 0xff,
1509 10,
1510 "0xff<matc>\0" // FIXME: unbalanced angle brackets
1511 "0xffh>\0"); // FIXME: empty angle brackets
1512
1513 // new style, line_max exceeded by unnamed bit-field value description in line 2
1514 h_snprintb_m(
1515 "\177\020"
1516 "F\000\004\0"
1517 ":\017m1\0"
1518 ":\017match\0",
1519 0xff,
1520 10,
1521 "0xff<m1ma>\0" // XXX: don't concatenate?
1522 "0xfftch>\0");
1523
1524 // new style, line_max exceeded by unnamed bit-field '>' in line 2
1525 h_snprintb_m(
1526 "\177\020"
1527 "F\000\004\0"
1528 ":\017m1\0"
1529 ":\017match\0",
1530 0xff,
1531 10,
1532 "0xff<m1ma>\0" // XXX: don't concatenate?
1533 "0xfftch>\0");
1534
1535 // new style unnamed bit-field complete
1536 h_snprintb_m(
1537 "\177\020"
1538 "F\000\004\0"
1539 ":\017m1\0"
1540 ":\017match\0",
1541 0xff,
1542 11,
1543 "0xff<m1mat>\0" // XXX: don't concatenate?
1544 "0xffch>\0");
1545
1546 // new style, line_max exceeded by bit-field default
1547 h_snprintb_m(
1548 "\177\020"
1549 "f\000\004f\0"
1550 "*=default\0",
1551 0xff,
1552 17,
1553 "0xff<f=0xf=default>\0"); // FIXME: line too long
1554
1555 // new style, line_max exceeded by unmatched field value
1556 h_snprintb_m(
1557 "\177\020"
1558 "f\000\004bits\0"
1559 ":\000other\0",
1560 0xff,
1561 11,
1562 "0xff<bits=0xf>\0" // XXX: line too long (14 > 11)
1563 "0xff#>\0"); // XXX: why '#'? unbalanced '<>'
1564
1565 // manual page, new style bits and fields
1566 h_snprintb_m(
1567 "\177\020"
1568 "b\0LSB\0"
1569 "b\1BITONE\0"
1570 "f\4\4NIBBLE2\0"
1571 "f\x10\4BURST\0"
1572 "=\4FOUR\0"
1573 "=\xf""FIFTEEN\0"
1574 "b\x1fMSB\0",
1575 0x800f0701,
1576 34,
1577 "0x800f0701<LSB,NIBBLE2=0>\0"
1578 "0x800f0701<BURST=0xf=FIFTEEN,MSB>\0");
1579
1580 // new style, buffer too small for complete number in line 2
1581 h_snprintb_m_len(
1582 15,
1583 "\177\020"
1584 "b\000lsb\0"
1585 "b\001two\0",
1586 0xff,
1587 11,
1588 20,
1589 "0xff<lsb>\0"
1590 "0xf\0" // XXX: incomplete number may be misleading
1591 );
1592
1593 // new-style format, buffer too small for '<' in line 2
1594 h_snprintb_m_len(
1595 16,
1596 "\177\020"
1597 "b\000lsb\0"
1598 "b\001two\0",
1599 0xff,
1600 11,
1601 20,
1602 "0xff<lsb>\0"
1603 "0xff\0"
1604 );
1605
1606 // new-style format, buffer too small for fallback
1607 h_snprintb_m(
1608 "\177\020"
1609 "f\000\004bits\0"
1610 "*=fallback\0"
1611 "b\0024\0",
1612 0xff,
1613 64,
1614 "0xff<bits=0xf=fallback,4>\0"
1615 );
1616
1617 // new-style format, buffer too small for numeric fallback
1618 h_snprintb_m_len(
1619 20,
1620 "\177\020"
1621 "F\000\004\0"
1622 "*fallback(%040jd)\0",
1623 0xff,
1624 64,
1625 57,
1626 "0xff<fallback(0000\0"
1627 );
1628
1629 // new-style format, buffer too small for numeric fallback past buffer
1630 h_snprintb_m_len(
1631 15,
1632 "\177\020"
1633 "F\000\004\0"
1634 "*fallback(%010jd)\0"
1635 "F\004\004\0"
1636 "*fallback(%010jd)\0",
1637 0xff,
1638 64,
1639 48,
1640 "0xff<fallback\0"
1641 );
1642
1643 // new style, bits and fields, line break between fields
1644 h_snprintb_m(
1645 "\177\020"
1646 "b\0LSB\0"
1647 "b\1_BITONE\0"
1648 "f\4\4NIBBLE2\0"
1649 "f\x10\4BURST\0"
1650 "=\04FOUR\0"
1651 "=\17FIFTEEN\0"
1652 "b\x1fMSB\0",
1653 0x800f0701,
1654 33,
1655 "0x800f0701<LSB,NIBBLE2=0>\0"
1656 "0x800f0701<BURST=0xf=FIFTEEN,MSB>\0"
1657 );
1658
1659 // new style, bits and fields, line break after field description
1660 h_snprintb_m(
1661 "\177\020"
1662 "b\0LSB\0"
1663 "b\1_BITONE\0"
1664 "f\4\4NIBBLE2\0"
1665 "f\x10\4BURST\0"
1666 "=\04FOUR\0"
1667 "=\17FIFTEEN\0"
1668 "b\x1fMSB\0",
1669 0x800f0701,
1670 32,
1671 "0x800f0701<LSB,NIBBLE2=0>\0"
1672 "0x800f0701<BURST=0xf=FIFTEEN>\0"
1673 "0x800f0701<MSB>\0");
1674 }
1675
1676 ATF_TP_ADD_TCS(tp)
1677 {
1678
1679 ATF_TP_ADD_TC(tp, snprintb);
1680 ATF_TP_ADD_TC(tp, snprintb_m);
1681
1682 return atf_no_error();
1683 }
1684