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