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