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