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