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