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