t_snprintb.c revision 1.16 1 /* $NetBSD: t_snprintb.c,v 1.16 2024/02/16 01:19:53 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.16 2024/02/16 01:19:53 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-fields with no match
496 h_snprintb(
497 "\177\020"
498 "f\010\004Field\0"
499 "=\1one\0"
500 "=\2two\0",
501 0x301,
502 "0x301<Field=0x3>");
503 h_snprintb(
504 "\177\020"
505 "F\010\004\0"
506 ":\1one\0"
507 ":\2two\0",
508 0x301,
509 "0x301<>");
510 h_snprintb(
511 "\177\020"
512 "f\010\004Field\0"
513 "=\1one\0"
514 "=\2two\0"
515 "b\000separator\0"
516 "F\010\004\0"
517 ":\1one\0"
518 ":\2two\0",
519 0x301,
520 "0x301<Field=0x3,separator,>");
521
522 // new-style format, two separate bit-fields
523 h_snprintb(
524 "\177\20"
525 "f\0\4Field_1\0"
526 "=\1ONE\0"
527 "=\2TWO\0"
528 "f\4\4Field_2\0"
529 "=\1ONE\0"
530 "=\2TWO\0",
531 0x12,
532 "0x12<Field_1=0x2=TWO,Field_2=0x1=ONE>");
533
534 // new-style format, mixed named and unnamed bit-fields
535 h_snprintb(
536 "\177\20"
537 "f\0\4Field_1\0"
538 "=\1ONE\0"
539 "=\2TWO\0"
540 "F\x8\4\0"
541 "*Field_3=%jd\0"
542 "f\4\4Field_2\0"
543 ":\1:ONE\0"
544 ":\2:TWO\0",
545 0xD12,
546 "0xd12<Field_1=0x2=TWO,Field_3=13,Field_2=0x1:ONE>");
547
548 // new-style format, descriptions with spaces
549 h_snprintb(
550 "\177\020"
551 "b\000has std options\0"
552 "f\010\004std options\0"
553 "=\000no options\0"
554 "=\017all options\0"
555 "F\020\004ext options\0"
556 ":\000no ext options\0"
557 ":\017all ext options\0",
558 0x000001,
559 "0x1<has std options,std options=0=no options,no ext options>");
560 h_snprintb(
561 "\177\020"
562 "f\010\004std options\0"
563 "*=other std options\0"
564 "F\020\004ext\toptions\0"
565 "*other\text\toptions\0",
566 0x000001,
567 "0x1<std options=0=other std options,other\text\toptions>");
568
569 // It is possible but cumbersome to implement a reduced variant of
570 // rot13 using snprintb, shown here for lowercase letters only.
571 for (char ch = 'A'; ch <= '~'; ch++) {
572 char rot13 = ch >= 'a' && ch <= 'm' ? ch + 13
573 : ch >= 'n' && ch <= 'z' ? ch - 13
574 : '?';
575 char expected[8];
576 ATF_REQUIRE_EQ(7,
577 snprintf(expected, sizeof(expected), "%#x<%c>", ch, rot13));
578 h_snprintb(
579 "\177\020"
580 "F\000\010\0"
581 ":an\0:bo\0:cp\0:dq\0:er\0:fs\0:gt\0:hu\0"
582 ":iv\0:jw\0:kx\0:ly\0:mz\0"
583 ":na\0:ob\0:pc\0:qd\0:re\0:sf\0:tg\0:uh\0"
584 ":vi\0:wj\0:xk\0:yl\0:zm\0"
585 // If snprintf accepted "%jc", it would be possible to
586 // echo the non-alphabetic characters instead of a
587 // catchall question mark.
588 "*?\0",
589 ch,
590 expected);
591 }
592
593 // new-style format, small buffer
594 #if 0
595 // FIXME: Calling snprintb with buffer size 0 invokes undefined
596 // behavior due to out-of-bounds 'bp' pointer.
597 h_snprintb_len(
598 0, "\177\020", 0,
599 1, "");
600 #endif
601 h_snprintb_len(
602 1, "\177\020", 0,
603 1, "");
604 h_snprintb_len(
605 2, "\177\020", 0,
606 1, "0");
607 h_snprintb_len(
608 3, "\177\020", 0,
609 1, "0");
610 h_snprintb_len(
611 3, "\177\020", 7,
612 3, "0x");
613 h_snprintb_len(
614 4, "\177\020", 7,
615 3, "0x7");
616 h_snprintb_len(
617 7, "\177\020b\000lsb\0", 7,
618 8, "0x7<ls");
619 h_snprintb_len(
620 8, "\177\020b\000lsb\0", 7,
621 8, "0x7<lsb");
622 h_snprintb_len(
623 9, "\177\020b\000lsb\0", 7,
624 8, "0x7<lsb>");
625 h_snprintb_len(
626 9, "\177\020b\000one\0b\001two\0", 7,
627 12, "0x7<one,");
628 h_snprintb_len(
629 10, "\177\020b\000one\0b\001two\0", 7,
630 12, "0x7<one,t");
631 h_snprintb_len(
632 12, "\177\020b\000one\0b\001two\0", 7,
633 12, "0x7<one,two");
634 h_snprintb_len(
635 13, "\177\020b\000one\0b\001two\0", 7,
636 12, "0x7<one,two>");
637
638 }
639
640 static void
641 h_snprintb_m_loc(const char *file, size_t line,
642 size_t bufsize, const char *fmt, size_t fmtlen, uint64_t val, size_t max,
643 size_t exp_rv, const char *res, size_t reslen)
644 {
645 char buf[1024];
646
647 ATF_REQUIRE(bufsize > 1);
648 ATF_REQUIRE(bufsize <= sizeof(buf));
649 ATF_REQUIRE(reslen <= sizeof(buf));
650
651 memset(buf, 'Z', sizeof(buf));
652 int rv = snprintb_m(buf, bufsize, fmt, val, max);
653 ATF_REQUIRE_MSG(rv >= 0,
654 "formatting %jx with '%s' returns error %d",
655 (uintmax_t)val, vis_arr(fmt, fmtlen), rv);
656
657 size_t total = rv;
658 ATF_CHECK_MSG(
659 total == exp_rv && memcmp(buf, res, reslen) == 0,
660 "failed:\n"
661 "\ttest case: %s:%zu\n"
662 "\tformat: %s\n"
663 "\tvalue: %#jx\n"
664 "\tmax: %zu\n"
665 "\twant: %zu bytes %s\n"
666 "\thave: %zu bytes %s\n",
667 file, line,
668 vis_arr(fmt, fmtlen),
669 (uintmax_t)val,
670 max,
671 exp_rv, vis_arr(res, reslen),
672 total, vis_arr(buf, reslen));
673 check_unmodified_loc(file, line, buf, reslen, sizeof(buf));
674 }
675
676 #define h_snprintb_m_len(bufsize, fmt, val, line_max, exp_rv, res) \
677 h_snprintb_m_loc(__FILE__, __LINE__, \
678 bufsize, fmt, sizeof(fmt) - 1, val, line_max, \
679 exp_rv, res, sizeof(res))
680 #define h_snprintb_m(fmt, val, max, res) \
681 h_snprintb_m_len(1024, fmt, val, max, sizeof(res) - 1, res)
682
683 ATF_TC(snprintb_m);
684 ATF_TC_HEAD(snprintb_m, tc)
685 {
686 atf_tc_set_md_var(tc, "descr", "Checks snprintb_m(3)");
687 }
688 ATF_TC_BODY(snprintb_m, tc)
689 {
690 // old-style format, small maximum line length
691 h_snprintb_m_len(
692 68,
693 "\020"
694 "\001bit1"
695 "\002bit2"
696 "\003bit3",
697 0xffff,
698 6,
699 143,
700 "0xffff>\0"
701 "0xffff<>\0"
702 "0xffffb>\0"
703 "0xffffi>\0"
704 "0xfffft>\0"
705 "0xffff1>\0"
706 "0xffff<>\0"
707 "0xff\0"
708 );
709
710 // new-style format, small maximum line length
711 h_snprintb_m_len(
712 68,
713 "\177\020"
714 "b\000bit1\0"
715 "b\001bit2\0"
716 "b\002bit3\0",
717 0xffff,
718 6,
719 143,
720 "0xffff>\0"
721 "0xffff<>\0"
722 "0xffffb>\0"
723 "0xffffi>\0"
724 "0xfffft>\0"
725 "0xffff1>\0"
726 "0xffff<>\0"
727 "0xff\0"
728 );
729
730 // new-style format, buffer too small for number
731 h_snprintb_m_len(
732 2,
733 "\177\020",
734 0,
735 64,
736 2,
737 "\0"
738 );
739
740 // new-style format, buffer too small for '<'
741 h_snprintb_m_len(
742 6,
743 "\177\020"
744 "b\000lsb\0",
745 0xff,
746 64,
747 10,
748 "0xff\0"
749 );
750
751 // new-style format, buffer too small for description
752 h_snprintb_m_len(
753 7,
754 "\177\020"
755 "b\000lsb\0",
756 0xff,
757 64,
758 10,
759 "0xff<\0"
760 );
761
762 // new-style format, buffer too small for complete description
763 h_snprintb_m_len(
764 9,
765 "\177\020"
766 "b\000lsb\0",
767 0xff,
768 64,
769 10,
770 "0xff<ls\0"
771 );
772
773 // new-style format, buffer too small for '>'
774 h_snprintb_m_len(
775 10,
776 "\177\020"
777 "b\000lsb\0",
778 0xff,
779 64,
780 10,
781 "0xff<lsb\0"
782 );
783
784 // new-style format, buffer too small for second line
785 h_snprintb_m_len(
786 11,
787 "\177\020"
788 "b\000lsb\0"
789 "b\001two\0",
790 0xff,
791 11,
792 20,
793 "0xff<lsb>\0"
794 );
795
796 // new-style format, buffer too small for number in line 2
797 h_snprintb_m_len(
798 12,
799 "\177\020"
800 "b\000lsb\0"
801 "b\001two\0",
802 0xff,
803 11,
804 20,
805 "0xff<lsb>\0"
806 "\0"
807 );
808
809 // new-style format, buffer too small for complete number in line 2
810 h_snprintb_m_len(
811 15,
812 "\177\020"
813 "b\000lsb\0"
814 "b\001two\0",
815 0xff,
816 11,
817 20,
818 "0xff<lsb>\0"
819 "0xf\0" // XXX: incomplete number may be misleading
820 );
821
822 // new-style format, buffer too small for '<' in line 2
823 h_snprintb_m_len(
824 16,
825 "\177\020"
826 "b\000lsb\0"
827 "b\001two\0",
828 0xff,
829 11,
830 20,
831 "0xff<lsb>\0"
832 "0xff\0"
833 );
834
835 // new-style format, buffer too small for description in line 2
836 h_snprintb_m_len(
837 17,
838 "\177\020"
839 "b\000lsb\0"
840 "b\001two\0",
841 0xff,
842 11,
843 20,
844 "0xff<lsb>\0"
845 "0xff<\0"
846 );
847
848 // new-style format, line too small for unmatched field value
849 h_snprintb_m_len(
850 30,
851 "\177\020"
852 "f\000\004bits\0"
853 ":\000other\0",
854 0xff,
855 11,
856 22,
857 "0xff<bits=0xf>\0" // XXX: line too long (14 > 11)
858 "0xff#>\0" // XXX: why '#'? unbalanced '<>'
859 );
860
861 // new-style format, line too small for field value
862 h_snprintb_m_len(
863 30,
864 "\177\020"
865 "f\000\004bits\0"
866 ":\017other\0",
867 0xff,
868 11,
869 27,
870 "0xff<bits=0xf>\0" // XXX: line too long (14 > 11)
871 "0xff#other>\0" // XXX: unbalanced '<>'
872 );
873
874 // new-style format, buffer too small for fallback
875 h_snprintb_m_len(
876 20,
877 "\177\020"
878 "f\000\004bits\0"
879 "*=fallback\0"
880 "b\0024\0",
881 0xff,
882 64,
883 26,
884 "0xff<bits=0xf=fall\0"
885 );
886
887 h_snprintb_m(
888 "\177\020"
889 "b\0LSB\0"
890 "b\1_BITONE\0"
891 "f\4\4NIBBLE2\0"
892 "f\x10\4BURST\0"
893 "=\04FOUR\0"
894 "=\17FIFTEEN\0"
895 "b\x1fMSB\0",
896 0x800f0701,
897 33,
898 "0x800f0701<LSB,NIBBLE2=0>\0"
899 "0x800f0701<BURST=0xf=FIFTEEN,MSB>\0"
900 );
901
902 h_snprintb_m(
903 "\177\020"
904 "b\0LSB\0"
905 "b\1_BITONE\0"
906 "f\4\4NIBBLE2\0"
907 "f\x10\4BURST\0"
908 "=\04FOUR\0"
909 "=\17FIFTEEN\0"
910 "b\x1fMSB\0",
911 0x800f0701,
912 32,
913 "0x800f0701<LSB,NIBBLE2=0>\0"
914 "0x800f0701<BURST=0xf=FIFTEEN>\0"
915 "0x800f0701<MSB>\0");
916 }
917
918 ATF_TP_ADD_TCS(tp)
919 {
920
921 ATF_TP_ADD_TC(tp, snprintb);
922 ATF_TP_ADD_TC(tp, snprintb_m);
923
924 return atf_no_error();
925 }
926