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