t_snprintb.c revision 1.33 1 /* $NetBSD: t_snprintb.c,v 1.33 2024/04/07 10:10:54 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.33 2024/04/07 10:10:54 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, 'b' with empty description
419 //
420 // The description of a 'b' conversion must not be empty, as the
421 // output would contain several commas in a row.
422 h_snprintb_len(
423 1024,
424 "\177\020"
425 "b\000lsb\0"
426 "b\001\0"
427 "b\002\0"
428 "b\007msb\0",
429 0xff,
430 -1,
431 "0xff<lsb#");
432
433 // new style single bits, bit number too large
434 h_snprintb_error(
435 "\177\020"
436 "b\100too-high\0",
437 "0#");
438 h_snprintb_error(
439 "\177\020"
440 "b\377too-high\0",
441 "0#");
442
443 // new style single bits, non-printable description
444 //
445 // Contrary to the old-style format, the new-style format allows
446 // arbitrary characters in the description, even control characters
447 // and non-ASCII characters.
448 h_snprintb(
449 "\177\020"
450 "b\000space \t \xC3\xA4\0",
451 0x1,
452 "0x1<space \t \xC3\xA4>");
453
454 // new style named bit-field, octal
455 //
456 // The bit-field value gets a leading '0' iff it is nonzero.
457 h_snprintb(
458 "\177\010"
459 "f\000\010byte0\0"
460 "f\010\010byte1\0",
461 0x0100,
462 "0400<byte0=0,byte1=01>");
463
464 // new style named bit-field, decimal
465 h_snprintb(
466 "\177\012"
467 "f\000\010byte0\0"
468 "f\010\010byte1\0",
469 0x0100,
470 "256<byte0=0,byte1=1>");
471
472 // new style named bit-field, hexadecimal
473 //
474 // The bit-field value gets a leading '0x' iff it is nonzero.
475 h_snprintb(
476 "\177\020"
477 "f\000\010byte0\0"
478 "f\010\010byte1\0",
479 0x0100,
480 "0x100<byte0=0,byte1=0x1>");
481
482 // new style bit-field, from 0 width 0
483 h_snprintb(
484 "\177\020"
485 "f\000\000zero-width\0"
486 "=\000zero\0",
487 0xffff,
488 "0xffff<zero-width=0=zero>");
489
490 // new style bit-field, from 0 width 1
491 h_snprintb(
492 "\177\020"
493 "f\000\001lsb\0"
494 "=\000zero\0"
495 "=\001one\0",
496 0x0,
497 "0<lsb=0=zero>");
498 h_snprintb(
499 "\177\020"
500 "f\000\001lsb\0"
501 "=\000zero\0"
502 "=\001one\0",
503 0x1,
504 "0x1<lsb=0x1=one>");
505
506 // new style bit-field, from 0 width 63
507 h_snprintb(
508 "\177\020"
509 "f\000\077uint63\0"
510 "=\125match\0",
511 0xaaaa5555aaaa5555,
512 "0xaaaa5555aaaa5555<uint63=0x2aaa5555aaaa5555>");
513
514 // new style bit-field, from 0 width 64
515 h_snprintb(
516 "\177\020"
517 "f\000\100uint64\0"
518 "=\125match\0",
519 0xaaaa5555aaaa5555,
520 "0xaaaa5555aaaa5555<uint64=0xaaaa5555aaaa5555>");
521
522 // new style bit-field, from 0 width 65
523 h_snprintb_error(
524 "\177\020"
525 "f\000\101uint65\0",
526 "0#");
527
528 // new style bit-field, from 1 width 8
529 h_snprintb(
530 "\177\020"
531 "f\001\010uint8\0"
532 "=\203match\0",
533 0x0106,
534 "0x106<uint8=0x83=match>");
535
536 // new style bit-field, from 1 width 9
537 //
538 // The '=' and ':' directives can match a bit-field value between
539 // 0 and 255, independent of the bit-field's width.
540 h_snprintb(
541 "\177\020"
542 "f\001\011uint9\0"
543 "=\203match\0"
544 "*=default-f\0"
545 "F\001\011\0"
546 ":\203match\0"
547 "*default-F\0",
548 0x0306,
549 "0x306<uint9=0x183=default-f,default-F>");
550
551 // new style bit-field, from 24 width 32
552 h_snprintb(
553 "\177\020"
554 "f\030\040uint32\0",
555 0xaaaa555500000000,
556 "0xaaaa555500000000<uint32=0xaa555500>");
557
558 // new style bit-field, from 60 width 4
559 h_snprintb(
560 "\177\020"
561 "f\074\004uint4\0",
562 0xf555555555555555,
563 "0xf555555555555555<uint4=0xf>");
564
565 // new style bit-field, from 60 width 5
566 //
567 // The end of the bit-field is out of bounds.
568 h_snprintb(
569 "\177\020"
570 "f\074\005uint5\0",
571 0xf555555555555555,
572 "0xf555555555555555<uint5=0xf>");
573
574 // new style bit-field, from 64 width 0
575 //
576 // The beginning of the bit-field is out of bounds, the end is fine.
577 h_snprintb_error(
578 "\177\020"
579 "f\100\000uint0\0",
580 "0#");
581
582 // new style bit-field, from 65 width 0
583 //
584 // The beginning and end of the bit-field are out of bounds.
585 h_snprintb_error(
586 "\177\020"
587 "f\101\000uint0\0",
588 "0#");
589
590 // new style bit-field, 'f' with empty description
591 //
592 // The description of an 'f' conversion must not be empty, as the
593 // output would contain an isolated '='.
594 h_snprintb_len(
595 1024,
596 "\177\020"
597 "f\000\004\0"
598 "=\001one\0",
599 0x1,
600 -1,
601 "0x1#");
602
603 // new style bit-field, non-printable description
604 //
605 // Contrary to the old-style format, the new-style format allows
606 // arbitrary characters in the description, even control characters
607 // and non-ASCII characters.
608 h_snprintb(
609 "\177\020"
610 "f\000\010\t \xC3\xA4\0"
611 "=\001\t \xC3\xA4\0"
612 "F\000\010\0"
613 ":\001\t \xC3\xA4\0"
614 "F\000\010\0"
615 "*\t \xC3\xA4\0",
616 0x1,
617 "0x1<\t \xC3\xA4=0x1=\t \xC3\xA4,\t \xC3\xA4,\t \xC3\xA4>");
618
619 // new style bit-field, '=' with empty description
620 //
621 // The description of a '=' conversion must not be empty, as the
622 // output would contain several '=' in a row.
623 h_snprintb_len(
624 1024,
625 "\177\020"
626 "f\000\004f\0"
627 "=\001one\0"
628 "=\001\0"
629 "=\001\0",
630 0x1,
631 -1,
632 "0x1<f=0x1=one#");
633
634 // new style bit-field, 'F' followed by ':' with empty description
635 //
636 // The description of a ':' conversion must not be empty, as the
637 // output would contain empty angle brackets.
638 h_snprintb_len(
639 1024,
640 "\177\020"
641 "F\000\004\0"
642 ":\001\0"
643 "*default\0",
644 0x1,
645 -1,
646 "0x1<#");
647
648 // new style bit-field, 'F', ':' with empty description, '*'
649 //
650 // The description of a ':' conversion must not be empty, as the
651 // output would contain empty angle brackets. Not in this particular
652 // test case, as the value is different, but the structural error is
653 // detected nevertheless.
654 h_snprintb_len(
655 1024,
656 "\177\020"
657 "F\000\004\0"
658 ":\001\0"
659 "*default\0",
660 0x2,
661 -1,
662 "0x2<#");
663
664 // new style bit-field, 'f' with non-exhaustive '='
665 h_snprintb(
666 "\177\020"
667 "f\000\004Field\0"
668 "=\1one\0"
669 "=\2two\0",
670 0x3,
671 "0x3<Field=0x3>");
672
673 // new style bit-field, 'F' with non-exhaustive ':'
674 //
675 // An unnamed bit-field that does not match any values generates empty
676 // angle brackets, which looks confusing. The ':' directives should
677 // either be exhaustive, or there should be a '*' catch-all directive.
678 h_snprintb(
679 "\177\020"
680 "F\000\004\0"
681 ":\1one\0"
682 ":\2two\0",
683 0x3,
684 "0x3<>");
685
686 // new style bit-field, 'F' with non-exhaustive ':'
687 //
688 // A bit-field that does not match any values generates multiple commas
689 // in a row, which looks confusing. The ':' directives should either be
690 // exhaustive, or there should be a '*' catch-all directive.
691 h_snprintb(
692 "\177\020"
693 "b\000bit0\0"
694 "F\000\004\0"
695 ":\1one\0"
696 ":\2two\0"
697 "b\001bit1\0",
698 0x3,
699 "0x3<bit0,,bit1>");
700
701 // new style bit-field, '=', can never match
702 //
703 // The extracted value from the bit-field has 7 bits and is thus less
704 // than 128, therefore it can neither match 128 nor 255.
705 h_snprintb(
706 "\177\020"
707 "f\000\007f\0"
708 "=\200never\0"
709 "=\377never\0",
710 0xff,
711 "0xff<f=0x7f>");
712
713 // new style, two separate bit-fields
714 h_snprintb(
715 "\177\020"
716 "f\000\004f1\0"
717 "=\001one\0"
718 "=\002two\0"
719 "f\004\004f2\0"
720 "=\001one\0"
721 "=\002two\0",
722 0x12,
723 "0x12<f1=0x2=two,f2=0x1=one>");
724
725 // new style, mixed named and unnamed bit-fields
726 h_snprintb(
727 "\177\020"
728 "f\000\004f1\0"
729 "=\001one\0"
730 "=\002two\0"
731 "F\010\004\0"
732 ":\015thirteen\0"
733 "f\004\004f2\0"
734 "=\001one\0"
735 "=\002two\0",
736 0x0d12,
737 "0xd12<f1=0x2=two,thirteen,f2=0x1=one>");
738
739 // new style bit-field, overlapping
740 h_snprintb(
741 "\177\020"
742 "f\000\004lo\0"
743 "f\002\004mid\0"
744 "f\004\004hi\0"
745 "f\000\010all\0",
746 0x18,
747 "0x18<lo=0x8,mid=0x6,hi=0x1,all=0x18>");
748
749 // new style bit-field, difference between '=' and ':'
750 //
751 // The ':' directive can almost emulate the '=' directive, without the
752 // numeric output and with a different separator. It's best to use
753 // either 'f' with '=', or 'F' with ':', but not mix them.
754 h_snprintb(
755 "\177\020"
756 "f\000\004field\0"
757 "=\010f-value\0"
758 "F\000\000\0" // Use an empty bit-field
759 ":\000separator\0" // to generate a separator.
760 "F\000\004\0"
761 ":\010F-value\0",
762 0x18,
763 "0x18<field=0x8=f-value,separator,F-value>");
764
765 // new style bit-field default, fixed string
766 //
767 // The 'f' directive pairs up with the '=' directive,
768 // the 'F' directive pairs up with the ':' directive,
769 // but there's only one 'default' directive for both variants,
770 // so its description should include the '=' when used with 'f' but
771 // not with 'F'.
772 h_snprintb(
773 "\177\020"
774 "f\030\010f1\0"
775 "*default\0"
776 "f\020\010f2\0"
777 "*=default\0"
778 "F\010\010\0"
779 "*default\0"
780 "F\010\010\0"
781 "*=default\0",
782 0x11223344,
783 "0x11223344<f1=0x11default,f2=0x22=default,default,=default>");
784
785 // new style bit-field default, numeric conversion specifier
786 h_snprintb(
787 "\177\020"
788 "f\010\010f\0"
789 "*=f(%ju)\0"
790 "F\000\010F\0"
791 "*F(%ju)\0",
792 0x1122,
793 "0x1122<f=0x11=f(17),F(34)>");
794
795 // new style bit-field default, can never match
796 //
797 // The '=' directive are exhaustive, making the '*' redundant.
798 h_snprintb(
799 "\177\020"
800 "f\010\002f\0"
801 "=\000zero\0"
802 "=\001one\0"
803 "=\002two\0"
804 "=\003three\0"
805 "*default\0",
806 0xff00,
807 "0xff00<f=0x3=three>");
808
809 // new style bit-field default, invalid conversion specifier
810 //
811 // There is no reliable way to make snprintf return an error, as such
812 // errors are defined as undefined behavior in the C standard.
813 // Instead, here's a conversion specifier that produces a literal '%'.
814 h_snprintb(
815 "\177\020"
816 "f\000\010f\0"
817 "*=%030ju%%\0",
818 0xff,
819 "0xff<f=0xff=000000000000000000000000000255%>");
820
821 // new style unknown directive, at the beginning
822 h_snprintb_len(
823 128,
824 "\177\020"
825 "unknown\0",
826 0xff,
827 -1,
828 "0xff#");
829
830 // new style unknown directive, after a known directive
831 h_snprintb_len(
832 128,
833 "\177\020"
834 "b\007msb\0"
835 "unknown\0",
836 0xff,
837 -1,
838 "0xff<msb#");
839
840 // new style combinations, 'b' '='
841 //
842 // A '=' directive without a preceding 'f' or 'F' directive generates
843 // misleading output outside the angle brackets, which is a mistake.
844 h_snprintb(
845 "\177\020"
846 "b\004bit4\0"
847 "=\000clear\0"
848 "=\001set\0"
849 "=\245complete\0"
850 "b\000bit0\0"
851 "=\000clear\0"
852 "=\001set\0"
853 "=\245complete\0",
854 0xa5,
855 "0xa5=complete<bit0=complete>");
856
857 // new style combinations, 'b' ':'
858 //
859 // A ':' directive without a preceding 'f' or 'F' directive generates
860 // misleading output outside or inside the angle brackets, which is a
861 // mistake.
862 h_snprintb(
863 "\177\020"
864 "b\004bit4\0"
865 ":\000clear\0"
866 ":\001set\0"
867 ":\245complete\0"
868 "b\000bit0\0"
869 ":\000clear\0"
870 ":\001set\0"
871 ":\245complete\0",
872 0xa5,
873 "0xa5complete<bit0complete>");
874
875 // new style combinations, 'b' '*'
876 //
877 // A '*' directive without a preceding 'f' or 'F' directive is ignored.
878 h_snprintb(
879 "\177\020"
880 "b\004bit4\0"
881 "*default(%ju)\0"
882 "b\000bit0\0"
883 "*default(%ju)\0",
884 0xa5,
885 "0xa5<bit0>");
886
887 // new style combinations, 'f' 'b' '='
888 //
889 // A 'b' directive that occurs between an 'f' and an '=' directive
890 // generates misleading output, which is a mistake.
891 h_snprintb(
892 "\177\020"
893 "f\000\010f\0"
894 "b\005bit5\0"
895 "=\245match\0",
896 0xa5,
897 "0xa5<f=0xa5,bit5=match>");
898
899 // new style combinations, 'f' 'b' ':'
900 //
901 // A 'b' directive that occurs between an 'f' and a ':' directive
902 // generates misleading output, which is a mistake.
903 h_snprintb(
904 "\177\020"
905 "f\000\010f\0"
906 "b\005bit5\0"
907 ":\245match\0",
908 0xa5,
909 "0xa5<f=0xa5,bit5match>");
910
911 // new style combinations, 'f' ':'
912 //
913 // Combining the 'f' directive with the ':' directive produces the
914 // misleading output '0x1one', which is a mistake.
915 h_snprintb(
916 "\177\20"
917 "f\000\004nibble\0"
918 ":\001one\0",
919 0x01,
920 "0x1<nibble=0x1one>");
921
922 // new style combinations, 'F' '='
923 //
924 // Combining the 'F' and '=' directives outputs an isolated '=', which
925 // is a mistake.
926 h_snprintb(
927 "\177\20"
928 "F\000\004\0"
929 "=\001one\0",
930 0x01,
931 "0x1<=one>");
932
933 // new style combinations, '='
934 //
935 // A '=' directive without a preceding 'f' or 'F' directive generates
936 // output that doesn't match the standard '0xaa<description>' form,
937 // which is a mistake.
938 h_snprintb(
939 "\177\020"
940 "=\245match\0",
941 0xa5,
942 "0xa5=match");
943
944 // new style combinations, ':'
945 //
946 // A ':' directive without a preceding 'f' or 'F' directive generates
947 // misleading output, which is a mistake.
948 h_snprintb(
949 "\177\020"
950 ":\245match\0",
951 0xa5,
952 "0xa5match");
953
954 // new style combinations, '*'
955 //
956 // A '*' directive without a preceding 'f' or 'F' is useless, which is
957 // a mistake.
958 h_snprintb(
959 "\177\020"
960 "*match\0",
961 0xa5,
962 "0xa5");
963
964 // new style combinations, 'f' '*' '='
965 //
966 // After a catch-all '*' directive, any following '=' directive
967 // generates misleading output, which is a mistake.
968 h_snprintb(
969 "\177\020"
970 "f\000\010f\0"
971 "*=default\0"
972 "=\245match\0",
973 0xa5,
974 "0xa5<f=0xa5=default=match>");
975
976 // new style combinations, 'F' '*' ':'
977 //
978 // After a catch-all '*' directive, any following ':' directive
979 // generates misleading output, which is a mistake.
980 h_snprintb(
981 "\177\020"
982 "F\000\010F\0"
983 "*default\0"
984 ":\245-match\0",
985 0xa5,
986 "0xa5<default-match>");
987
988 // new style combinations, '*' '*'
989 //
990 // After a catch-all '*' directive, any further '*' directive is
991 // ignored and thus redundant, which is a mistake.
992 h_snprintb(
993 "\177\020"
994 "f\000\010f\0"
995 "*=default-f\0"
996 "*ignored\0"
997 "F\000\010\0"
998 "*default-F\0"
999 "*ignored\0",
1000 0xa5,
1001 "0xa5<f=0xa5=default-f,default-F>");
1002
1003 // example from the manual page, old style octal
1004 h_snprintb(
1005 "\10\2BITTWO\1BITONE",
1006 0x03,
1007 "03<BITTWO,BITONE>");
1008
1009 // example from the manual page, old style hexadecimal
1010 //
1011 // When using a hexadecimal escape sequence to encode a bit number,
1012 // the description must not start with a hexadecimal digit, or that
1013 // digit is interpreted as part of the bit number. To prevent this,
1014 // the bit number and the description need to be written as separate
1015 // string literals.
1016 h_snprintb(
1017 "\20"
1018 "\x10NOTBOOT" "\x0f""FPP" "\x0eSDVMA"
1019 "\x0cVIDEO" "\x0bLORES" "\x0a""FPA" "\x09""DIAG"
1020 "\x07""CACHE" "\x06IOCACHE" "\x05LOOPBACK"
1021 "\x04""DBGCACHE",
1022 0xe860,
1023 "0xe860<NOTBOOT,FPP,SDVMA,VIDEO,CACHE,IOCACHE>");
1024
1025 // example from the manual page, new style bits and fields
1026 h_snprintb(
1027 "\177\020"
1028 "b\0LSB\0" "b\1BITONE\0"
1029 "f\4\4NIBBLE2\0"
1030 "f\x10\4BURST\0" "=\4FOUR\0" "=\xf""FIFTEEN\0"
1031 "b\x1fMSB\0",
1032 0x800f0701,
1033 "0x800f0701<LSB,NIBBLE2=0,BURST=0xf=FIFTEEN,MSB>");
1034
1035 // example from the manual page, new style mmap
1036 #define MAP_FMT \
1037 "\177\020" \
1038 "b\0" "SHARED\0" \
1039 "b\1" "PRIVATE\0" \
1040 "b\2" "COPY\0" \
1041 "b\4" "FIXED\0" \
1042 "b\5" "RENAME\0" \
1043 "b\6" "NORESERVE\0" \
1044 "b\7" "INHERIT\0" \
1045 "b\11" "HASSEMAPHORE\0" \
1046 "b\12" "TRYFIXED\0" \
1047 "b\13" "WIRED\0" \
1048 "F\14\1\0" \
1049 ":\0" "FILE\0" \
1050 ":\1" "ANONYMOUS\0" \
1051 "b\15" "STACK\0" \
1052 "F\30\010\0" \
1053 ":\000" "ALIGN=NONE\0" \
1054 ":\015" "ALIGN=8KB\0" \
1055 "*" "ALIGN=2^%ju\0"
1056 h_snprintb(
1057 MAP_FMT,
1058 0x0d001234,
1059 "0xd001234<COPY,FIXED,RENAME,HASSEMAPHORE,ANONYMOUS,ALIGN=8KB>");
1060 h_snprintb(
1061 MAP_FMT,
1062 0x2e000000,
1063 "0x2e000000<FILE,ALIGN=2^46>");
1064
1065 // It is possible but cumbersome to implement a reduced variant of
1066 // rot13 using snprintb, shown here for lowercase letters only.
1067 for (char ch = 'A'; ch <= '~'; ch++) {
1068 char rot13 = ch >= 'a' && ch <= 'm' ? ch + 13
1069 : ch >= 'n' && ch <= 'z' ? ch - 13
1070 : '?';
1071 char expected[8];
1072 ATF_REQUIRE_EQ(7,
1073 snprintf(expected, sizeof(expected), "%#x<%c>", ch, rot13));
1074 h_snprintb(
1075 "\177\020"
1076 "F\000\010\0"
1077 ":an\0:bo\0:cp\0:dq\0:er\0:fs\0:gt\0:hu\0"
1078 ":iv\0:jw\0:kx\0:ly\0:mz\0"
1079 ":na\0:ob\0:pc\0:qd\0:re\0:sf\0:tg\0:uh\0"
1080 ":vi\0:wj\0:xk\0:yl\0:zm\0"
1081 // If snprintf accepted "%jc", it would be possible to
1082 // echo the non-alphabetic characters instead of a
1083 // catchall question mark.
1084 "*?\0",
1085 ch,
1086 expected);
1087 }
1088
1089 // new style, small buffers
1090 h_snprintb_len(
1091 0, "\177\020", 0x00,
1092 1, "");
1093 h_snprintb_len(
1094 1, "\177\020", 0x00,
1095 1, "");
1096 h_snprintb_len(
1097 2, "\177\020", 0x00,
1098 1, "0");
1099 h_snprintb_len(
1100 3, "\177\020", 0x00,
1101 1, "0");
1102 h_snprintb_len(
1103 3, "\177\020", 0x07,
1104 3, "0#");
1105 h_snprintb_len(
1106 4, "\177\020", 0x07,
1107 3, "0x7");
1108 h_snprintb_len(
1109 7, "\177\020b\000lsb\0", 0x07,
1110 8, "0x7<l#");
1111 h_snprintb_len(
1112 8, "\177\020b\000lsb\0", 0x07,
1113 8, "0x7<ls#");
1114 h_snprintb_len(
1115 9, "\177\020b\000lsb\0", 0x07,
1116 8, "0x7<lsb>");
1117 h_snprintb_len(
1118 9, "\177\020b\000one\0b\001two\0", 0x07,
1119 12, "0x7<one#");
1120 h_snprintb_len(
1121 10, "\177\020b\000one\0b\001two\0", 0x07,
1122 12, "0x7<one,#");
1123 h_snprintb_len(
1124 12, "\177\020b\000one\0b\001two\0", 0x07,
1125 12, "0x7<one,tw#");
1126 h_snprintb_len(
1127 13, "\177\020b\000one\0b\001two\0", 0x07,
1128 12, "0x7<one,two>");
1129 }
1130
1131 ATF_TC(snprintb_m);
1132 ATF_TC_HEAD(snprintb_m, tc)
1133 {
1134 atf_tc_set_md_var(tc, "descr", "Checks snprintb_m(3)");
1135 }
1136 ATF_TC_BODY(snprintb_m, tc)
1137 {
1138
1139 // old style, line_max exceeded by number in line 1
1140 h_snprintb_m(
1141 "\020",
1142 0xff,
1143 1,
1144 "#\0");
1145
1146 // old style, line_max exceeded by '<' in line 1
1147 h_snprintb_m(
1148 "\020"
1149 "\001lsb",
1150 0xff,
1151 4,
1152 "0xf#\0");
1153
1154 // old style, line_max exceeded by description
1155 h_snprintb_m(
1156 "\020"
1157 "\001bit1"
1158 "\002bit2",
1159 0xff,
1160 7,
1161 "0xff<b#\0"
1162 "0xff<b#\0");
1163
1164 // old style, line_max exceeded by '>' in line 1
1165 h_snprintb_m(
1166 "\020"
1167 "\001bit1"
1168 "\0022",
1169 0xff,
1170 9,
1171 "0xff<bit#\0"
1172 "0xff<2>\0");
1173
1174 // old style, line_max exceeded by description in line 2
1175 h_snprintb_m(
1176 "\020"
1177 "\0011"
1178 "\002bit2",
1179 0xff,
1180 8,
1181 "0xff<1>\0"
1182 "0xff<bi#\0");
1183
1184 // old style, line_max exceeded by '>' in line 2
1185 h_snprintb_m(
1186 "\020"
1187 "\0011"
1188 "\002bit2",
1189 0xff,
1190 9,
1191 "0xff<1>\0"
1192 "0xff<bit#\0");
1193
1194 // old style, complete
1195 h_snprintb_m(
1196 "\020"
1197 "\0011"
1198 "\002bit2",
1199 0xff,
1200 10,
1201 "0xff<1>\0"
1202 "0xff<bit2>\0");
1203
1204 // new style, line_max exceeded by value in line 1
1205 h_snprintb_m(
1206 "\177\020",
1207 0xff,
1208 3,
1209 "0x#\0");
1210
1211 // new style, line_max exceeded by single-bit '<' in line 1
1212 h_snprintb_m(
1213 "\177\020"
1214 "b\000bit\0",
1215 0xff,
1216 4,
1217 "0xf#\0");
1218
1219 // new style, line_max exceeded by single-bit description in line 1
1220 h_snprintb_m(
1221 "\177\020"
1222 "b\000bit0\0"
1223 "b\001two\0",
1224 0xff,
1225 8,
1226 "0xff<bi#\0"
1227 "0xff<tw#\0");
1228
1229 // new style, line_max exceeded by single-bit '>' in line 1
1230 h_snprintb_m(
1231 "\177\020"
1232 "b\000bit0\0"
1233 "b\001two\0",
1234 0xff,
1235 9,
1236 "0xff<bit#\0"
1237 "0xff<two>\0");
1238
1239 // new style, line_max exceeded by single-bit description in line 2
1240 h_snprintb_m(
1241 "\177\020"
1242 "b\000one\0"
1243 "b\001three\0",
1244 0xff,
1245 9,
1246 "0xff<one>\0"
1247 "0xff<thr#\0");
1248
1249 // new style, line_max exceeded by single-bit '>' in line 2
1250 h_snprintb_m(
1251 "\177\020"
1252 "b\000one\0"
1253 "b\001three\0",
1254 0xff,
1255 10,
1256 "0xff<one>\0"
1257 "0xff<thre#\0");
1258
1259 // new style, single-bit complete
1260 h_snprintb_m(
1261 "\177\020"
1262 "b\000one\0"
1263 "b\001three\0",
1264 0xff,
1265 11,
1266 "0xff<one>\0"
1267 "0xff<three>\0");
1268
1269 // new style, line_max exceeded by named bit-field number in line 1
1270 h_snprintb_m(
1271 "\177\020"
1272 "f\000\004lo\0",
1273 0xff,
1274 3,
1275 "0x#\0");
1276
1277 // new style, line_max exceeded by named bit-field '<' in line 1
1278 h_snprintb_m(
1279 "\177\020"
1280 "f\000\004lo\0",
1281 0xff,
1282 4,
1283 "0xf#\0");
1284
1285 // new style, line_max exceeded by bit-field description in line 1
1286 h_snprintb_m(
1287 "\177\020"
1288 "f\000\004lo\0",
1289 0xff,
1290 6,
1291 "0xff<#\0");
1292
1293 // new style, line_max exceeded by named bit-field '=' in line 1
1294 h_snprintb_m(
1295 "\177\020"
1296 "f\000\004lo\0",
1297 0xff,
1298 7,
1299 "0xff<l#\0");
1300
1301 // new style, line_max exceeded by named bit-field value in line 1
1302 h_snprintb_m(
1303 "\177\020"
1304 "f\000\004lo\0",
1305 0xff,
1306 10,
1307 "0xff<lo=0#\0");
1308
1309 // new style, line_max exceeded by named bit-field '=' in line 1
1310 h_snprintb_m(
1311 "\177\020"
1312 "f\000\004lo\0"
1313 "=\017match\0",
1314 0xff,
1315 12,
1316 "0xff<lo=0xf#\0");
1317
1318 // new style, line_max exceeded by named bit-field value description in
1319 // line 1
1320 h_snprintb_m(
1321 "\177\020"
1322 "f\000\004lo\0"
1323 "=\017match\0",
1324 0xff,
1325 16,
1326 "0xff<lo=0xf=mat#\0");
1327
1328 // new style, line_max exceeded by named bit-field '>' in line 1
1329 h_snprintb_m(
1330 "\177\020"
1331 "f\000\004lo\0"
1332 "=\017match\0",
1333 0xff,
1334 17,
1335 "0xff<lo=0xf=matc#\0");
1336
1337 // new style, line_max exceeded by named bit-field description in
1338 // line 2
1339 h_snprintb_m(
1340 "\177\020"
1341 "f\000\004lo\0"
1342 "f\000\004low-bits\0"
1343 "=\017match\0",
1344 0xff,
1345 12,
1346 "0xff<lo=0xf>\0"
1347 "0xff<low-bi#\0");
1348
1349 // new style, line_max exceeded by named bit-field '=' 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 13,
1357 "0xff<lo=0xf>\0"
1358 "0xff<low-bit#\0");
1359
1360 // new style, line_max exceeded by named bit-field value 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 16,
1368 "0xff<lo=0xf>\0"
1369 "0xff<low-bits=0#\0");
1370
1371 // new style, line_max exceeded by named bit-field '=' 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 18,
1379 "0xff<lo=0xf>\0"
1380 "0xff<low-bits=0xf#\0");
1381
1382 // new style, line_max exceeded by named bit-field value description
1383 // in line 2
1384 h_snprintb_m(
1385 "\177\020"
1386 "f\000\004lo\0"
1387 "f\000\004low-bits\0"
1388 "=\017match\0",
1389 0xff,
1390 22,
1391 "0xff<lo=0xf>\0"
1392 "0xff<low-bits=0xf=mat#\0");
1393
1394 // new style, line_max exceeded by named bit-field '>' in line 2
1395 h_snprintb_m(
1396 "\177\020"
1397 "f\000\004lo\0"
1398 "f\000\004low-bits\0"
1399 "=\017match\0",
1400 0xff,
1401 23,
1402 "0xff<lo=0xf>\0"
1403 "0xff<low-bits=0xf=matc#\0");
1404
1405 // new style, named bit-field complete
1406 h_snprintb_m(
1407 "\177\020"
1408 "f\000\004lo\0"
1409 "f\000\004low-bits\0"
1410 "=\017match\0",
1411 0xff,
1412 24,
1413 "0xff<lo=0xf>\0"
1414 "0xff<low-bits=0xf=match>\0");
1415
1416 // new style, line_max exceeded by unnamed bit-field number in line 1
1417 h_snprintb_m(
1418 "\177\020"
1419 "F\000\004\0",
1420 0xff,
1421 3,
1422 "0x#\0");
1423
1424 // new style, line_max exceeded by unnamed bit-field '<' in line 1
1425 h_snprintb_m(
1426 "\177\020"
1427 "F\000\004\0",
1428 0xff,
1429 4,
1430 "0xf#\0");
1431
1432 // new style, line_max exceeded by unnamed bit-field value description
1433 // 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
1452 // in line 2
1453 h_snprintb_m(
1454 "\177\020"
1455 "F\000\004\0"
1456 ":\017m1\0"
1457 ":\017match\0",
1458 0xff,
1459 10,
1460 "0xff<m1ma#\0");
1461
1462 // new style, line_max exceeded by unnamed bit-field '>' in line 2
1463 h_snprintb_m(
1464 "\177\020"
1465 "F\000\004\0"
1466 ":\017m1\0"
1467 ":\017match\0",
1468 0xff,
1469 10,
1470 "0xff<m1ma#\0");
1471
1472 // new style unnamed bit-field complete
1473 h_snprintb_m(
1474 "\177\020"
1475 "F\000\004\0"
1476 ":\017m1\0"
1477 ":\017match\0",
1478 0xff,
1479 13,
1480 "0xff<m1match>\0");
1481
1482 // new style, line_max exceeded by bit-field default
1483 h_snprintb_m(
1484 "\177\020"
1485 "f\000\004f\0"
1486 "*=default\0",
1487 0xff,
1488 17,
1489 "0xff<f=0xf=defau#\0");
1490
1491 // new style, line_max exceeded by unmatched field value
1492 h_snprintb_m(
1493 "\177\020"
1494 "f\000\004bits\0"
1495 ":\000zero\0",
1496 0xff,
1497 11,
1498 "0xff<bits=#\0");
1499
1500 // example from the manual page, new style bits and fields
1501 h_snprintb_m(
1502 "\177\020"
1503 "b\0LSB\0"
1504 "b\1BITONE\0"
1505 "f\4\4NIBBLE2\0"
1506 "f\x10\4BURST\0"
1507 "=\4FOUR\0"
1508 "=\xf""FIFTEEN\0"
1509 "b\x1fMSB\0",
1510 0x800f0701,
1511 34,
1512 "0x800f0701<LSB,NIBBLE2=0>\0"
1513 "0x800f0701<BURST=0xf=FIFTEEN,MSB>\0");
1514
1515 // new style, missing number base
1516 h_snprintb_m_len(
1517 1024,
1518 "\177",
1519 0xff,
1520 128,
1521 -1,
1522 "#\0");
1523
1524 // new style, buffer too small for complete number in line 2
1525 h_snprintb_m_len(
1526 15,
1527 "\177\020"
1528 "b\000lsb\0"
1529 "b\001two\0",
1530 0xff,
1531 11,
1532 20,
1533 "0xff<lsb>\0"
1534 "0x#\0");
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 "0xf#\0");
1547
1548 // new-style format, buffer too small for textual fallback
1549 h_snprintb_m_len(
1550 24,
1551 "\177\020"
1552 "f\000\004bits\0"
1553 "*=fallback\0"
1554 "b\0024\0",
1555 0xff,
1556 64,
1557 26,
1558 "0xff<bits=0xf=fallbac#\0");
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(000#\0");
1570
1571 // new-style format, buffer too small for numeric fallback past buffer
1572 h_snprintb_m_len(
1573 15,
1574 "\177\020"
1575 "F\000\004\0"
1576 "*fallback(%010jd)\0"
1577 "F\004\004\0"
1578 "*fallback(%010jd)\0",
1579 0xff,
1580 64,
1581 48,
1582 "0xff<fallbac#\0");
1583
1584 // new style, bits and fields, line break between fields
1585 h_snprintb_m(
1586 "\177\020"
1587 "b\0LSB\0"
1588 "b\1_BITONE\0"
1589 "f\4\4NIBBLE2\0"
1590 "f\x10\4BURST\0"
1591 "=\04FOUR\0"
1592 "=\17FIFTEEN\0"
1593 "b\x1fMSB\0",
1594 0x800f0701,
1595 33,
1596 "0x800f0701<LSB,NIBBLE2=0>\0"
1597 "0x800f0701<BURST=0xf=FIFTEEN,MSB>\0");
1598
1599 // new style, bits and fields, line break after field description
1600 h_snprintb_m(
1601 "\177\020"
1602 "b\0LSB\0"
1603 "b\1_BITONE\0"
1604 "f\4\4NIBBLE2\0"
1605 "f\020\4BURST\0"
1606 "=\04FOUR\0"
1607 "=\17FIFTEEN\0"
1608 "b\037MSB\0",
1609 0x800f0701,
1610 32,
1611 "0x800f0701<LSB,NIBBLE2=0>\0"
1612 "0x800f0701<BURST=0xf=FIFTEEN>\0"
1613 "0x800f0701<MSB>\0");
1614 }
1615
1616 ATF_TP_ADD_TCS(tp)
1617 {
1618
1619 ATF_TP_ADD_TC(tp, snprintb);
1620 ATF_TP_ADD_TC(tp, snprintb_m);
1621
1622 return atf_no_error();
1623 }
1624