t_snprintb.c revision 1.17 1 /* $NetBSD: t_snprintb.c,v 1.17 2024/02/16 18:09:16 rillig Exp $ */
2
3 /*
4 * Copyright (c) 2002, 2004, 2008, 2010, 2024 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code was contributed to The NetBSD Foundation by Christos Zoulas and
8 * Roland Illig.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __COPYRIGHT("@(#) Copyright (c) 2008, 2010\
34 The NetBSD Foundation, inc. All rights reserved.");
35 __RCSID("$NetBSD: t_snprintb.c,v 1.17 2024/02/16 18:09:16 rillig Exp $");
36
37 #include <stdio.h>
38 #include <string.h>
39 #include <util.h>
40 #include <vis.h>
41
42 #include <atf-c.h>
43
44 static const char *
45 vis_arr(const char *arr, size_t arrsize)
46 {
47 static char buf[6][1024];
48 static size_t i;
49
50 i = (i + 1) % (sizeof(buf) / sizeof(buf[0]));
51 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 size_t mod_begin = begin, mod_end = end;
62 while (mod_begin < mod_end && arr[mod_begin] == 'Z')
63 mod_begin++;
64 while (mod_begin < mod_end && arr[mod_end - 1] == 'Z')
65 mod_end--;
66 ATF_CHECK_MSG(
67 mod_begin == mod_end,
68 "failed:\n"
69 "\ttest case: %s:%zu\n"
70 "\tout-of-bounds write from %zu to %zu: %s\n",
71 file, line,
72 mod_begin, mod_end, vis_arr(arr + mod_begin, mod_end - mod_begin));
73 }
74
75 static void
76 h_snprintb_loc(const char *file, size_t line,
77 size_t bufsize, const char *fmt, size_t fmtlen, uint64_t val,
78 int exp_rv, const char *res, size_t reslen)
79 {
80 char buf[1024];
81
82 // Calling snprintb with bufsize == 0 invokes undefined
83 // behavior due to out-of-range 'bp'.
84 ATF_REQUIRE(bufsize > 0);
85 ATF_REQUIRE(bufsize <= sizeof(buf));
86 ATF_REQUIRE(reslen <= sizeof(buf));
87
88 memset(buf, 'Z', sizeof(buf));
89 int rv = snprintb(buf, bufsize, fmt, val);
90 ATF_REQUIRE(rv >= 0);
91 size_t rlen = rv;
92
93 ATF_CHECK_MSG(
94 rv == exp_rv && memcmp(buf, res, reslen) == 0
95 && buf[rlen < bufsize ? rlen : bufsize - 1] == '\0',
96 "failed:\n"
97 "\ttest case: %s:%zu\n"
98 "\tformat: %s\n"
99 "\tvalue: %#jx\n"
100 "\twant: %d bytes %s\n"
101 "\thave: %d bytes %s\n",
102 file, line,
103 vis_arr(fmt, fmtlen),
104 (uintmax_t)val,
105 exp_rv, vis_arr(res, reslen),
106 rv, vis_arr(buf, reslen));
107 check_unmodified_loc(file, line, buf, reslen, sizeof(buf));
108 }
109
110 #define h_snprintb_len(bufsize, fmt, val, exp_rv, res) \
111 h_snprintb_loc(__FILE__, __LINE__, \
112 bufsize, fmt, sizeof(fmt) - 1, val, \
113 exp_rv, res, sizeof(res))
114 #define h_snprintb(fmt, val, res) \
115 h_snprintb_len(1024, fmt, val, sizeof(res) - 1, res)
116
117 static void
118 h_snprintb_error_loc(const char *file, size_t line,
119 const char *fmt, size_t fmtlen)
120 {
121 char buf[1024];
122
123 memset(buf, 'Z', sizeof(buf));
124 int rv = snprintb(buf, sizeof(buf), fmt, 0);
125 size_t buflen = rv;
126
127 ATF_REQUIRE(rv >= -1);
128 ATF_CHECK_MSG(rv == -1,
129 "expected error but got success:\n"
130 "\ttest case: %s:%zu\n"
131 "\tformat: %s\n"
132 "\tresult: %zu bytes %s\n",
133 file, line,
134 vis_arr(fmt, fmtlen),
135 buflen, vis_arr(buf, buflen));
136 }
137
138 #define h_snprintb_error(fmt) \
139 h_snprintb_error_loc(__FILE__, __LINE__, fmt, sizeof(fmt) - 1)
140
141 ATF_TC(snprintb);
142 ATF_TC_HEAD(snprintb, tc)
143 {
144 atf_tc_set_md_var(tc, "descr", "Checks snprintb(3)");
145 }
146 ATF_TC_BODY(snprintb, tc)
147 {
148
149 // old-style format, octal
150 h_snprintb(
151 "\010"
152 "\002BITTWO"
153 "\001BITONE",
154 3,
155 "03<BITTWO,BITONE>");
156
157 // old-style format, decimal
158 h_snprintb(
159 "\012"
160 "\0011"
161 "\0119"
162 "\02117"
163 "\04032",
164 0xffffffff,
165 "4294967295<1,9,17,32>");
166
167 // old-style format, hexadecimal, from msb downto lsb
168 h_snprintb(
169 "\020"
170 "\04032"
171 "\03024"
172 "\02016"
173 "\0108"
174 "\0077"
175 "\0066"
176 "\0055"
177 "\0044"
178 "\0033"
179 "\0022"
180 "\0011"
181 // The old-style format supports only 32 bits, interpreting the
182 // \041 as part of the text belonging to bit 1.
183 "\04133",
184 0x0000ffff00ff0f35,
185 "0xffff00ff0f35<24,6,5,3,1!33>");
186
187 // old-style format, hexadecimal, from lsb to msb
188 h_snprintb(
189 "\020"
190 "\0011"
191 "\0022"
192 "\0033"
193 "\0044"
194 "\0055"
195 "\0066"
196 "\0077"
197 "\0108"
198 "\02016"
199 "\03024"
200 "\04032"
201 // The old-style format supports only 32 bits, interpreting the
202 // \041 as part of the text belonging to bit 32.
203 "\04133",
204 0xffff0000ff00f0ca,
205 "0xffff0000ff00f0ca<2,4,7,8,16,32!33>");
206
207 // The bits can be listed in arbitrary order, there can also be
208 // duplicates. A bit's description can be empty, resulting in several
209 // commas in a row.
210 h_snprintb(
211 "\020"
212 "\001lsb"
213 "\040msb"
214 "\011"
215 "\012"
216 "\002above-lsb"
217 "\037below-msb"
218 "\001lsb-again"
219 "\040msb-again",
220 0xc0000303,
221 "0xc0000303<lsb,msb,,,above-lsb,below-msb,lsb-again,msb-again>");
222
223 #if 0
224 // If the first bit number is 33 or more, snprintb invokes undefined
225 // behavior due to an out-of-bounds bit shift, though undetected by
226 // -ftrapv. Later bit numbers are properly checked.
227 h_snprintb(
228 "\020"
229 "\177undefined_behavior"
230 "\001lsb",
231 0xffffffffffffffff,
232 "0xffffffffffffffff<?>");
233 #endif
234
235 // old-style format, invalid number base 0
236 h_snprintb_error(
237 "");
238
239 // old-style format, invalid number base 2
240 h_snprintb_error(
241 "\002");
242
243 // old-style format, invalid number base 255 or -1
244 h_snprintb_error(
245 "\377");
246
247 // old-style format, small buffer
248 #if 0
249 // FIXME: Calling snprintb with buffer size 0 invokes undefined
250 // behavior due to out-of-bounds 'bp' pointer.
251 h_snprintb_len(
252 0, "\020", 0,
253 1, "");
254 #endif
255 h_snprintb_len(
256 1, "\020", 0,
257 1, "");
258 h_snprintb_len(
259 2, "\020", 0,
260 1, "0");
261 h_snprintb_len(
262 3, "\020", 0,
263 1, "0");
264 h_snprintb_len(
265 3, "\020", 7,
266 3, "0x");
267 h_snprintb_len(
268 4, "\020", 7,
269 3, "0x7");
270 h_snprintb_len(
271 7, "\020\001lsb", 7,
272 8, "0x7<ls");
273 h_snprintb_len(
274 8, "\020\001lsb", 7,
275 8, "0x7<lsb");
276 h_snprintb_len(
277 9, "\020\001lsb", 7,
278 8, "0x7<lsb>");
279 h_snprintb_len(
280 9, "\020\001one\002two", 7,
281 12, "0x7<one,");
282 h_snprintb_len(
283 10, "\020\001one\002two", 7,
284 12, "0x7<one,t");
285 h_snprintb_len(
286 12, "\020\001one\002two", 7,
287 12, "0x7<one,two");
288 h_snprintb_len(
289 13, "\020\001one\002two", 7,
290 12, "0x7<one,two>");
291
292 // new-style format, single bits, octal
293 h_snprintb(
294 "\177\010"
295 "b\000bit0\0"
296 "b\037bit31\0"
297 "b\040bit32\0"
298 "b\077bit63\0",
299 0xf000000ff000000f,
300 "01700000000776000000017<bit0,bit31,bit32,bit63>");
301
302 // new-style format, single bits, decimal
303 h_snprintb(
304 "\177\012"
305 "b\000bit0\0"
306 "b\037bit31\0"
307 "b\040bit32\0"
308 "b\077bit63\0",
309 0xf000000ff000000f,
310 "17293822637553745935<bit0,bit31,bit32,bit63>");
311
312 // new-style format, single bits, hexadecimal
313 h_snprintb(
314 "\177\020"
315 "b\000bit0\0"
316 "b\037bit31\0"
317 "b\040bit32\0"
318 "b\077bit63\0",
319 0xf000000ff000000f,
320 "0xf000000ff000000f<bit0,bit31,bit32,bit63>");
321
322 // new-style format, invalid number base 2
323 h_snprintb_error(
324 "\177\002");
325
326 // new-style format, invalid number base 255 or -1
327 h_snprintb_error(
328 "\177\377");
329
330 // new-style format, single bits, edge cases
331 //
332 // The bits can be listed in arbitrary order, there can also be
333 // duplicates. A bit's description can be empty, resulting in several
334 // commas in a row.
335 h_snprintb(
336 "\177\020"
337 "b\01lsb\0"
338 "b\02\0"
339 "b\03\0"
340 "b\05NOTBOOT\0"
341 "b\06FPP\0"
342 "b\13SDVMA\0"
343 "b\15VIDEO\0"
344 "b\20LORES\0"
345 "b\21FPA\0"
346 "b\22DIAG\0"
347 "b\16CACHE\0"
348 "b\17IOCACHE\0"
349 "b\22LOOPBACK\0"
350 "b\04DBGCACHE\0",
351 0xe86f,
352 "0xe86f<lsb,,,NOTBOOT,FPP,SDVMA,VIDEO,CACHE,IOCACHE>");
353
354 // new-style format, octal, named bit-field
355 h_snprintb(
356 "\177\010"
357 "f\010\004Field\0"
358 "=\001one\0"
359 "=\002two\0",
360 0x100,
361 "0400<Field=01=one>");
362
363 // new-style format, decimal, named bit-field
364 h_snprintb(
365 "\177\012"
366 "f\010\004Field\0"
367 "=\1one\0"
368 "=\2two\0",
369 0x100,
370 "256<Field=1=one>");
371
372 // new-style format, hexadecimal, named bit-field
373 h_snprintb(
374 "\177\020"
375 "f\010\004Field\0"
376 "=\1one\0"
377 "=\2two\0",
378 0x100,
379 "0x100<Field=0x1=one>");
380
381 // new-style format, octal, unnamed bit-field
382 h_snprintb(
383 "\177\010"
384 "F\010\004Field\0"
385 ":\001one\0"
386 ":\002two\0",
387 0x100,
388 "0400<one>");
389
390 // new-style format, decimal, unnamed bit-field
391 h_snprintb(
392 "\177\012"
393 "F\010\004Field\0"
394 ":\1one\0"
395 ":\2two\0",
396 0x100,
397 "256<one>");
398
399 // new-style format, hexadecimal, unnamed bit-field
400 h_snprintb(
401 "\177\020"
402 "F\010\004Field\0"
403 ":\1one\0"
404 ":\2two\0",
405 0x100,
406 "0x100<one>");
407
408 // new-style format, hexadecimal, named bit-field, edge cases
409 //
410 // Field values can be listed in arbitrary order, there can also be
411 // duplicates. A field value's description can be empty, resulting in
412 // several '=' in a row. The ':' directive can emulate the '='
413 // directive, but not vice versa.
414 h_snprintb(
415 "\177\20"
416 "f\0\4Field\0"
417 "=\1one\0"
418 "=\1one-again\0"
419 "=\1\0"
420 "=\1\0"
421 ":\1double\0"
422 ":\1-colon\0"
423 ":\1=equal\0"
424 "=\2TWO\0",
425 1,
426 "0x1<Field=0x1=one=one-again==double-colon=equal>");
427
428 // new-style format, hexadecimal, unnamed bit-field, edge cases
429 //
430 // Combining the 'F' and '=' directives generates output that doesn't
431 // look well-formed.
432 h_snprintb(
433 "\177\20"
434 "=\0all-zero\0"
435 "=\1all-one\0"
436 ":\1-continued\0"
437 "F\0\4Field\0"
438 "=\1one\0"
439 "=\1one-again\0"
440 "=\1\0"
441 "=\1\0"
442 ":\1double\0"
443 ":\1-colon\0"
444 ":\1=equal\0"
445 "=\2TWO\0",
446 1,
447 "0x1=all-one-continued<=one=one-again==double-colon=equal>");
448
449 // new-style format, bit-fields with fixed fallback value
450 //
451 // Only the first fallback value is used, all others are ignored.
452 h_snprintb(
453 "\177\020"
454 "f\0\4Field\0"
455 "=\1one\0"
456 "=\2two\0"
457 "*=other\0"
458 "*=yet-another\0"
459 "b\1separator\0"
460 "F\0\4Field\0"
461 ":\1one\0"
462 ":\2two\0"
463 "*other\0"
464 "*yet-another\0",
465 3,
466 "0x3<Field=0x3=other,separator,other>");
467
468 // new-style format, bit-fields with numeric fallback value
469 h_snprintb(
470 "\177\020"
471 "f\010\004Field\0"
472 "*=other(%04ju)\0"
473 "b\000separator\0"
474 "F\010\004Field\0"
475 "*other(%04ju)\0",
476 0x301,
477 "0x301<Field=0x3=other(0003),separator,other(0003)>");
478
479 // new-style format, bit-field with more than 8 bits
480 //
481 // The '=' and ':' directives can only match values from 0 to 255, so
482 // the fallback value always steps in. The complete value of the
483 // bit-field appears in the output, though.
484 h_snprintb(
485 "\177\020"
486 "f\010\020Field\0"
487 "=\377ones\0"
488 "*=other(%jx)\0"
489 "F\010\020\0"
490 ":\377ones\0"
491 "*other(%jx)\0",
492 0x77ff55,
493 "0x77ff55<Field=0x77ff=other(77ff),other(77ff)>");
494
495 // new-style format, bit-field with 8 bits
496 h_snprintb(
497 "\177\020"
498 "F\010\010\0"
499 ":\377all\0"
500 "*other\0",
501 0xff00,
502 "0xff00<other>");
503
504 // new-style format, bit-fields with no match
505 h_snprintb(
506 "\177\020"
507 "f\010\004Field\0"
508 "=\1one\0"
509 "=\2two\0",
510 0x301,
511 "0x301<Field=0x3>");
512 h_snprintb(
513 "\177\020"
514 "F\010\004\0"
515 ":\1one\0"
516 ":\2two\0",
517 0x301,
518 "0x301<>");
519 h_snprintb(
520 "\177\020"
521 "f\010\004Field\0"
522 "=\1one\0"
523 "=\2two\0"
524 "b\000separator\0"
525 "F\010\004\0"
526 ":\1one\0"
527 ":\2two\0",
528 0x301,
529 "0x301<Field=0x3,separator,>");
530
531 // new-style format, two separate bit-fields
532 h_snprintb(
533 "\177\20"
534 "f\0\4Field_1\0"
535 "=\1ONE\0"
536 "=\2TWO\0"
537 "f\4\4Field_2\0"
538 "=\1ONE\0"
539 "=\2TWO\0",
540 0x12,
541 "0x12<Field_1=0x2=TWO,Field_2=0x1=ONE>");
542
543 // new-style format, mixed named and unnamed bit-fields
544 h_snprintb(
545 "\177\20"
546 "f\0\4Field_1\0"
547 "=\1ONE\0"
548 "=\2TWO\0"
549 "F\x8\4\0"
550 "*Field_3=%jd\0"
551 "f\4\4Field_2\0"
552 ":\1:ONE\0"
553 ":\2:TWO\0",
554 0xD12,
555 "0xd12<Field_1=0x2=TWO,Field_3=13,Field_2=0x1:ONE>");
556
557 // new-style format, descriptions with spaces
558 h_snprintb(
559 "\177\020"
560 "b\000has std options\0"
561 "f\010\004std options\0"
562 "=\000no options\0"
563 "=\017all options\0"
564 "F\020\004ext options\0"
565 ":\000no ext options\0"
566 ":\017all ext options\0",
567 0x000001,
568 "0x1<has std options,std options=0=no options,no ext options>");
569 h_snprintb(
570 "\177\020"
571 "f\010\004std options\0"
572 "*=other std options\0"
573 "F\020\004ext\toptions\0"
574 "*other\text\toptions\0",
575 0x000001,
576 "0x1<std options=0=other std options,other\text\toptions>");
577
578 // It is possible but cumbersome to implement a reduced variant of
579 // rot13 using snprintb, shown here for lowercase letters only.
580 for (char ch = 'A'; ch <= '~'; ch++) {
581 char rot13 = ch >= 'a' && ch <= 'm' ? ch + 13
582 : ch >= 'n' && ch <= 'z' ? ch - 13
583 : '?';
584 char expected[8];
585 ATF_REQUIRE_EQ(7,
586 snprintf(expected, sizeof(expected), "%#x<%c>", ch, rot13));
587 h_snprintb(
588 "\177\020"
589 "F\000\010\0"
590 ":an\0:bo\0:cp\0:dq\0:er\0:fs\0:gt\0:hu\0"
591 ":iv\0:jw\0:kx\0:ly\0:mz\0"
592 ":na\0:ob\0:pc\0:qd\0:re\0:sf\0:tg\0:uh\0"
593 ":vi\0:wj\0:xk\0:yl\0:zm\0"
594 // If snprintf accepted "%jc", it would be possible to
595 // echo the non-alphabetic characters instead of a
596 // catchall question mark.
597 "*?\0",
598 ch,
599 expected);
600 }
601
602 // new-style format, small buffer
603 #if 0
604 // FIXME: Calling snprintb with buffer size 0 invokes undefined
605 // behavior due to out-of-bounds 'bp' pointer.
606 h_snprintb_len(
607 0, "\177\020", 0,
608 1, "");
609 #endif
610 h_snprintb_len(
611 1, "\177\020", 0,
612 1, "");
613 h_snprintb_len(
614 2, "\177\020", 0,
615 1, "0");
616 h_snprintb_len(
617 3, "\177\020", 0,
618 1, "0");
619 h_snprintb_len(
620 3, "\177\020", 7,
621 3, "0x");
622 h_snprintb_len(
623 4, "\177\020", 7,
624 3, "0x7");
625 h_snprintb_len(
626 7, "\177\020b\000lsb\0", 7,
627 8, "0x7<ls");
628 h_snprintb_len(
629 8, "\177\020b\000lsb\0", 7,
630 8, "0x7<lsb");
631 h_snprintb_len(
632 9, "\177\020b\000lsb\0", 7,
633 8, "0x7<lsb>");
634 h_snprintb_len(
635 9, "\177\020b\000one\0b\001two\0", 7,
636 12, "0x7<one,");
637 h_snprintb_len(
638 10, "\177\020b\000one\0b\001two\0", 7,
639 12, "0x7<one,t");
640 h_snprintb_len(
641 12, "\177\020b\000one\0b\001two\0", 7,
642 12, "0x7<one,two");
643 h_snprintb_len(
644 13, "\177\020b\000one\0b\001two\0", 7,
645 12, "0x7<one,two>");
646
647 }
648
649 static void
650 h_snprintb_m_loc(const char *file, size_t line,
651 size_t bufsize, const char *fmt, size_t fmtlen, uint64_t val, size_t max,
652 size_t exp_rv, const char *res, size_t reslen)
653 {
654 char buf[1024];
655
656 ATF_REQUIRE(bufsize > 1);
657 ATF_REQUIRE(bufsize <= sizeof(buf));
658 ATF_REQUIRE(reslen <= sizeof(buf));
659
660 memset(buf, 'Z', sizeof(buf));
661 int rv = snprintb_m(buf, bufsize, fmt, val, max);
662 ATF_REQUIRE_MSG(rv >= 0,
663 "formatting %jx with '%s' returns error %d",
664 (uintmax_t)val, vis_arr(fmt, fmtlen), rv);
665
666 size_t total = rv;
667 ATF_CHECK_MSG(
668 total == exp_rv && memcmp(buf, res, reslen) == 0,
669 "failed:\n"
670 "\ttest case: %s:%zu\n"
671 "\tformat: %s\n"
672 "\tvalue: %#jx\n"
673 "\tmax: %zu\n"
674 "\twant: %zu bytes %s\n"
675 "\thave: %zu bytes %s\n",
676 file, line,
677 vis_arr(fmt, fmtlen),
678 (uintmax_t)val,
679 max,
680 exp_rv, vis_arr(res, reslen),
681 total, vis_arr(buf, reslen));
682 check_unmodified_loc(file, line, buf, reslen, sizeof(buf));
683 }
684
685 #define h_snprintb_m_len(bufsize, fmt, val, line_max, exp_rv, res) \
686 h_snprintb_m_loc(__FILE__, __LINE__, \
687 bufsize, fmt, sizeof(fmt) - 1, val, line_max, \
688 exp_rv, res, sizeof(res))
689 #define h_snprintb_m(fmt, val, max, res) \
690 h_snprintb_m_len(1024, fmt, val, max, sizeof(res) - 1, res)
691
692 ATF_TC(snprintb_m);
693 ATF_TC_HEAD(snprintb_m, tc)
694 {
695 atf_tc_set_md_var(tc, "descr", "Checks snprintb_m(3)");
696 }
697 ATF_TC_BODY(snprintb_m, tc)
698 {
699 // old-style format, small maximum line length
700 h_snprintb_m_len(
701 68,
702 "\020"
703 "\001bit1"
704 "\002bit2"
705 "\003bit3",
706 0xffff,
707 6,
708 143,
709 "0xffff>\0"
710 "0xffff<>\0"
711 "0xffffb>\0"
712 "0xffffi>\0"
713 "0xfffft>\0"
714 "0xffff1>\0"
715 "0xffff<>\0"
716 "0xff\0"
717 );
718
719 // new-style format, small maximum line length
720 h_snprintb_m_len(
721 68,
722 "\177\020"
723 "b\000bit1\0"
724 "b\001bit2\0"
725 "b\002bit3\0",
726 0xffff,
727 6,
728 143,
729 "0xffff>\0"
730 "0xffff<>\0"
731 "0xffffb>\0"
732 "0xffffi>\0"
733 "0xfffft>\0"
734 "0xffff1>\0"
735 "0xffff<>\0"
736 "0xff\0"
737 );
738
739 // new-style format, buffer too small for number
740 h_snprintb_m_len(
741 2,
742 "\177\020",
743 0,
744 64,
745 2,
746 "\0"
747 );
748
749 // new-style format, buffer too small for '<'
750 h_snprintb_m_len(
751 6,
752 "\177\020"
753 "b\000lsb\0",
754 0xff,
755 64,
756 10,
757 "0xff\0"
758 );
759
760 // new-style format, buffer too small for description
761 h_snprintb_m_len(
762 7,
763 "\177\020"
764 "b\000lsb\0",
765 0xff,
766 64,
767 10,
768 "0xff<\0"
769 );
770
771 // new-style format, buffer too small for complete description
772 h_snprintb_m_len(
773 9,
774 "\177\020"
775 "b\000lsb\0",
776 0xff,
777 64,
778 10,
779 "0xff<ls\0"
780 );
781
782 // new-style format, buffer too small for '>'
783 h_snprintb_m_len(
784 10,
785 "\177\020"
786 "b\000lsb\0",
787 0xff,
788 64,
789 10,
790 "0xff<lsb\0"
791 );
792
793 // new-style format, buffer too small for second line
794 h_snprintb_m_len(
795 11,
796 "\177\020"
797 "b\000lsb\0"
798 "b\001two\0",
799 0xff,
800 11,
801 20,
802 "0xff<lsb>\0"
803 );
804
805 // new-style format, buffer too small for number in line 2
806 h_snprintb_m_len(
807 12,
808 "\177\020"
809 "b\000lsb\0"
810 "b\001two\0",
811 0xff,
812 11,
813 20,
814 "0xff<lsb>\0"
815 "\0"
816 );
817
818 // new-style format, buffer too small for complete number in line 2
819 h_snprintb_m_len(
820 15,
821 "\177\020"
822 "b\000lsb\0"
823 "b\001two\0",
824 0xff,
825 11,
826 20,
827 "0xff<lsb>\0"
828 "0xf\0" // XXX: incomplete number may be misleading
829 );
830
831 // new-style format, buffer too small for '<' in line 2
832 h_snprintb_m_len(
833 16,
834 "\177\020"
835 "b\000lsb\0"
836 "b\001two\0",
837 0xff,
838 11,
839 20,
840 "0xff<lsb>\0"
841 "0xff\0"
842 );
843
844 // new-style format, buffer too small for description in line 2
845 h_snprintb_m_len(
846 17,
847 "\177\020"
848 "b\000lsb\0"
849 "b\001two\0",
850 0xff,
851 11,
852 20,
853 "0xff<lsb>\0"
854 "0xff<\0"
855 );
856
857 // new-style format, line too small for unmatched field value
858 h_snprintb_m_len(
859 30,
860 "\177\020"
861 "f\000\004bits\0"
862 ":\000other\0",
863 0xff,
864 11,
865 22,
866 "0xff<bits=0xf>\0" // XXX: line too long (14 > 11)
867 "0xff#>\0" // XXX: why '#'? unbalanced '<>'
868 );
869
870 // new-style format, line too small for field value
871 h_snprintb_m_len(
872 30,
873 "\177\020"
874 "f\000\004bits\0"
875 ":\017other\0",
876 0xff,
877 11,
878 27,
879 "0xff<bits=0xf>\0" // XXX: line too long (14 > 11)
880 "0xff#other>\0" // XXX: unbalanced '<>'
881 );
882
883 // new-style format, buffer too small for fallback
884 h_snprintb_m_len(
885 20,
886 "\177\020"
887 "f\000\004bits\0"
888 "*=fallback\0"
889 "b\0024\0",
890 0xff,
891 64,
892 26,
893 "0xff<bits=0xf=fall\0"
894 );
895
896 h_snprintb_m(
897 "\177\020"
898 "b\0LSB\0"
899 "b\1_BITONE\0"
900 "f\4\4NIBBLE2\0"
901 "f\x10\4BURST\0"
902 "=\04FOUR\0"
903 "=\17FIFTEEN\0"
904 "b\x1fMSB\0",
905 0x800f0701,
906 33,
907 "0x800f0701<LSB,NIBBLE2=0>\0"
908 "0x800f0701<BURST=0xf=FIFTEEN,MSB>\0"
909 );
910
911 h_snprintb_m(
912 "\177\020"
913 "b\0LSB\0"
914 "b\1_BITONE\0"
915 "f\4\4NIBBLE2\0"
916 "f\x10\4BURST\0"
917 "=\04FOUR\0"
918 "=\17FIFTEEN\0"
919 "b\x1fMSB\0",
920 0x800f0701,
921 32,
922 "0x800f0701<LSB,NIBBLE2=0>\0"
923 "0x800f0701<BURST=0xf=FIFTEEN>\0"
924 "0x800f0701<MSB>\0");
925 }
926
927 ATF_TP_ADD_TCS(tp)
928 {
929
930 ATF_TP_ADD_TC(tp, snprintb);
931 ATF_TP_ADD_TC(tp, snprintb_m);
932
933 return atf_no_error();
934 }
935