Module Name: src
Committed By: rillig
Date: Mon Feb 19 23:22:03 UTC 2024
Modified Files:
src/tests/lib/libutil: t_snprintb.c
Log Message:
tests/snprintb: add more tests, especially for snprintb_m
To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/tests/lib/libutil/t_snprintb.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/tests/lib/libutil/t_snprintb.c
diff -u src/tests/lib/libutil/t_snprintb.c:1.20 src/tests/lib/libutil/t_snprintb.c:1.21
--- src/tests/lib/libutil/t_snprintb.c:1.20 Fri Feb 16 19:53:40 2024
+++ src/tests/lib/libutil/t_snprintb.c Mon Feb 19 23:22:03 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: t_snprintb.c,v 1.20 2024/02/16 19:53:40 rillig Exp $ */
+/* $NetBSD: t_snprintb.c,v 1.21 2024/02/19 23:22:03 rillig Exp $ */
/*
* Copyright (c) 2002, 2004, 2008, 2010, 2024 The NetBSD Foundation, Inc.
@@ -30,9 +30,9 @@
*/
#include <sys/cdefs.h>
-__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
+__COPYRIGHT("@(#) Copyright (c) 2008, 2010, 2024\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_snprintb.c,v 1.20 2024/02/16 19:53:40 rillig Exp $");
+__RCSID("$NetBSD: t_snprintb.c,v 1.21 2024/02/19 23:22:03 rillig Exp $");
#include <stdio.h>
#include <string.h>
@@ -58,40 +58,43 @@ static void
check_unmodified_loc(const char *file, size_t line,
const char *arr, size_t begin, size_t end)
{
- size_t mod_begin = begin, mod_end = end;
- while (mod_begin < mod_end && arr[mod_begin] == 'Z')
- mod_begin++;
- while (mod_begin < mod_end && arr[mod_end - 1] == 'Z')
- mod_end--;
+ while (begin < end && arr[begin] == 'Z')
+ begin++;
+ while (begin < end && arr[end - 1] == 'Z')
+ end--;
ATF_CHECK_MSG(
- mod_begin == mod_end,
+ begin == end,
"failed:\n"
"\ttest case: %s:%zu\n"
"\tout-of-bounds write from %zu to %zu: %s\n",
file, line,
- mod_begin, mod_end, vis_arr(arr + mod_begin, mod_end - mod_begin));
+ begin, end, vis_arr(arr + begin, end - begin));
}
static void
h_snprintb_loc(const char *file, size_t line,
- size_t bufsize, const char *fmt, size_t fmtlen, uint64_t val,
- int exp_rv, const char *res, size_t reslen)
+ size_t bufsize, const char *bitfmt, size_t bitfmtlen, uint64_t val,
+ int want_rv, const char *want_buf, size_t want_bufsize)
{
char buf[1024];
ATF_REQUIRE(bufsize <= sizeof(buf));
- ATF_REQUIRE(reslen <= sizeof(buf));
+ ATF_REQUIRE(want_bufsize <= sizeof(buf));
+ if (bitfmtlen > 2 && bitfmt[0] == '\177')
+ ATF_REQUIRE_MSG(bitfmt[bitfmtlen - 1] == '\0',
+ "%s:%zu: missing trailing '\\0' in bitfmt",
+ file, line);
+ if (bufsize == 0 && want_bufsize == 1)
+ want_bufsize = 0;
memset(buf, 'Z', sizeof(buf));
- int rv = snprintb(buf, bufsize, fmt, val);
+ int rv = snprintb(buf, bufsize, bitfmt, val);
ATF_REQUIRE(rv >= 0);
size_t rlen = rv;
- if (bufsize == 0 && reslen == 1)
- reslen = 0;
ATF_CHECK_MSG(
- rv == exp_rv
- && memcmp(buf, res, reslen) == 0
+ rv == want_rv
+ && memcmp(buf, want_buf, want_bufsize) == 0
&& buf[rlen < bufsize ? rlen : bufsize - 1] == '\0',
"failed:\n"
"\ttest case: %s:%zu\n"
@@ -100,28 +103,28 @@ h_snprintb_loc(const char *file, size_t
"\twant: %d bytes %s\n"
"\thave: %d bytes %s\n",
file, line,
- vis_arr(fmt, fmtlen),
+ vis_arr(bitfmt, bitfmtlen),
(uintmax_t)val,
- exp_rv, vis_arr(res, reslen),
- rv, vis_arr(buf, reslen));
- check_unmodified_loc(file, line, buf, reslen, sizeof(buf));
+ want_rv, vis_arr(want_buf, want_bufsize),
+ rv, vis_arr(buf, want_bufsize));
+ check_unmodified_loc(file, line, buf, want_bufsize, sizeof(buf));
}
-#define h_snprintb_len(bufsize, fmt, val, exp_rv, res) \
+#define h_snprintb_len(bufsize, bitfmt, val, want_rv, want_buf) \
h_snprintb_loc(__FILE__, __LINE__, \
- bufsize, fmt, sizeof(fmt) - 1, val, \
- exp_rv, res, sizeof(res))
-#define h_snprintb(fmt, val, res) \
- h_snprintb_len(1024, fmt, val, sizeof(res) - 1, res)
+ bufsize, bitfmt, sizeof(bitfmt) - 1, val, \
+ want_rv, want_buf, sizeof(want_buf))
+#define h_snprintb(bitfmt, val, want_buf) \
+ h_snprintb_len(1024, bitfmt, val, sizeof(want_buf) - 1, want_buf)
static void
h_snprintb_error_loc(const char *file, size_t line,
- const char *fmt, size_t fmtlen)
+ const char *bitfmt, size_t bitfmtlen)
{
char buf[1024];
memset(buf, 'Z', sizeof(buf));
- int rv = snprintb(buf, sizeof(buf), fmt, 0);
+ int rv = snprintb(buf, sizeof(buf), bitfmt, 0);
size_t buflen = rv;
ATF_REQUIRE(rv >= -1);
@@ -131,12 +134,12 @@ h_snprintb_error_loc(const char *file, s
"\tformat: %s\n"
"\tresult: %zu bytes %s\n",
file, line,
- vis_arr(fmt, fmtlen),
+ vis_arr(bitfmt, bitfmtlen),
buflen, vis_arr(buf, buflen));
}
-#define h_snprintb_error(fmt) \
- h_snprintb_error_loc(__FILE__, __LINE__, fmt, sizeof(fmt) - 1)
+#define h_snprintb_error(bitfmt) \
+ h_snprintb_error_loc(__FILE__, __LINE__, bitfmt, sizeof(bitfmt) - 1)
ATF_TC(snprintb);
ATF_TC_HEAD(snprintb, tc)
@@ -146,430 +149,876 @@ ATF_TC_HEAD(snprintb, tc)
ATF_TC_BODY(snprintb, tc)
{
- // old-style format, octal
+ // style and number base, old style, octal, zero value
+ //
+ // The value 0 does not get a leading '0'.
h_snprintb(
- "\010"
- "\002BITTWO"
- "\001BITONE",
- 3,
- "03<BITTWO,BITONE>");
+ "\010",
+ 0,
+ "0");
- // old-style format, decimal
+ // style and number base, old style, octal, nonzero value
+ //
+ // Nonzero octal values get a leading '0'.
h_snprintb(
- "\012"
- "\0011"
- "\0119"
- "\02117"
- "\04032",
- 0xffffffff,
- "4294967295<1,9,17,32>");
-
- // old-style format, hexadecimal, from msb downto lsb
- h_snprintb(
- "\020"
- "\04032"
- "\03024"
- "\02016"
- "\0108"
- "\0077"
- "\0066"
- "\0055"
- "\0044"
- "\0033"
- "\0022"
- "\0011"
- // The old-style format supports only 32 bits, interpreting the
- // \041 as part of the text belonging to bit 1.
- "\04133",
- 0x0000ffff00ff0f35,
- "0xffff00ff0f35<24,6,5,3,1!33>");
+ "\010",
+ 0xff,
+ "0377");
- // old-style format, hexadecimal, from lsb to msb
+ // style and number base, old style, decimal, zero value
h_snprintb(
- "\020"
- "\0011"
- "\0022"
- "\0033"
- "\0044"
- "\0055"
- "\0066"
- "\0077"
- "\0108"
- "\02016"
- "\03024"
- "\04032"
- // The old-style format supports only 32 bits, interpreting the
- // \041 as part of the text belonging to bit 32.
- "\04133",
- 0xffff0000ff00f0ca,
- "0xffff0000ff00f0ca<2,4,7,8,16,32!33>");
-
- // The bits can be listed in arbitrary order, there can also be
- // duplicates. A bit's description can be empty, resulting in several
- // commas in a row.
+ "\012",
+ 0,
+ "0");
+
+ // style and number base, old style, decimal, nonzero value
h_snprintb(
- "\020"
- "\001lsb"
- "\040msb"
- "\011"
- "\012"
- "\002above-lsb"
- "\037below-msb"
- "\001lsb-again"
- "\040msb-again",
- 0xc0000303,
- "0xc0000303<lsb,msb,,,above-lsb,below-msb,lsb-again,msb-again>");
-
-#if 0
- // If the first bit number is 33 or more, snprintb invokes undefined
- // behavior due to an out-of-bounds bit shift, though undetected by
- // -ftrapv. Later bit numbers are properly checked.
- h_snprintb(
- "\020"
- "\177undefined_behavior"
- "\001lsb",
- 0xffffffffffffffff,
- "0xffffffffffffffff<?>");
-#endif
+ "\012",
+ 0xff,
+ "255");
+
+ // style and number base, old style, hexadecimal, zero value
+ //
+ // The value 0 does not get a leading '0x'.
+ h_snprintb(
+ "\020",
+ 0,
+ "0");
- // old-style format, invalid number base 0
+ // style and number base, old style, hexadecimal, nonzero value
+ //
+ // Nonzero hexadecimal values get a leading '0x'.
+ h_snprintb(
+ "\177\020",
+ 0xff,
+ "0xff");
+
+ // style and number base, old style, invalid base 0
h_snprintb_error(
"");
- // old-style format, invalid number base 2
+ // style and number base, old style, invalid base 2
h_snprintb_error(
"\002");
- // old-style format, invalid number base 255 or -1
+ // style and number base, old style, invalid base 255 or -1
h_snprintb_error(
"\377");
- // old-style format, small buffers
+ // style and number base, new style, octal, zero value
+ //
+ // The value 0 does not get a leading '0'.
+ h_snprintb(
+ "\177\010",
+ 0,
+ "0");
+
+ // style and number base, new style, octal, nonzero value
+ //
+ // Nonzero octal values get a leading '0'.
+ h_snprintb(
+ "\177\010",
+ 0xff,
+ "0377");
+
+ // style and number base, new style, decimal, zero value
+ h_snprintb(
+ "\177\012",
+ 0,
+ "0");
+
+ // style and number base, new style, decimal, nonzero value
+ h_snprintb(
+ "\177\012",
+ 0xff,
+ "255");
+
+ // style and number base, new style, hexadecimal, zero value
+ //
+ // The value 0 does not get a leading '0x'.
+ h_snprintb(
+ "\177\020",
+ 0,
+ "0");
+
+ // style and number base, new style, hexadecimal, nonzero value
+ //
+ // Nonzero hexadecimal values get a leading '0x'.
+ h_snprintb(
+ "\177\020",
+ 0xff,
+ "0xff");
+
+ // style and number base, new style, invalid number base 0
+ h_snprintb_error(
+ "\177");
+
+ // style and number base, new style, invalid number base 2
+ h_snprintb_error(
+ "\177\002");
+
+ // style and number base, new style, invalid number base 255 or -1
+ h_snprintb_error(
+ "\177\377");
+
+ // old style, from lsb to msb
+ h_snprintb(
+ "\020"
+ "\001bit1"
+ "\002bit2"
+ "\037bit31"
+ "\040bit32",
+ 0xffffffff80000001,
+ "0xffffffff80000001<bit1,bit32>");
+
+ // old style, invalid bit number, at the beginning
+#if 0 /* undefined behavior due to out-of-bounds bit shift */
+ h_snprintb_error(
+ "\020"
+ "\041invalid");
+#endif
+
+ // old style, invalid bit number, in the middle
+ //
+ // The old-style format supports only 32 bits, interpreting the
+ // \041 as part of the text belonging to bit 1.
+ h_snprintb(
+ "\020"
+ "\001bit1"
+ "\041bit33",
+ 0x1,
+ "0x1<bit1!bit33>");
+
+ // old style, repeated bit numbers
+ //
+ // When a bit number is mentioned more than once,
+ // this is most likely a typo.
+ h_snprintb(
+ "\020"
+ "\001once"
+ "\001again",
+ 0x1,
+ "0x1<once,again>");
+
+ // old style, non-printable description
+ //
+ // The characters ' ' and '\t' are interpreted as bit numbers,
+ // not as part of the description; the visual arrangement is
+ // misleading.
+ h_snprintb(
+ "\020"
+ "\001least significant"
+ "\002horizontal\ttab",
+ 0xff,
+ "0xff<least,horizontal>");
+
+ // old style, empty description
+ //
+ // Empty descriptions result in multiple commas in a row, which is a
+ // mistake.
+ h_snprintb(
+ "\020"
+ "\001lsb"
+ "\004"
+ "\005"
+ "\010msb",
+ 0xff,
+ "0xff<lsb,,,msb>");
+
+ // old style, buffer size 0
+ //
+ // With the buffer size being 0, the buffer is not modified at all.
+ // In kernel mode, the buffer is zeroed out and thus must not be null.
h_snprintb_len(
0, "\020", 0,
1, "");
+
+ // old style, buffer too small for value
h_snprintb_len(
1, "\020", 0,
1, "");
+
+ // old style, buffer large enough for zero value
h_snprintb_len(
2, "\020", 0,
1, "0");
+
+ // old style, buffer larger than necessary for zero value
h_snprintb_len(
3, "\020", 0,
1, "0");
+
+ // old style, buffer too small for nonzero value
h_snprintb_len(
3, "\020", 7,
3, "0x");
+
+ // old style, buffer large enough for nonzero value
h_snprintb_len(
4, "\020", 7,
3, "0x7");
+
+ // old style, buffer too small for '<'
+ h_snprintb_len(
+ 4, "\020\001lsb", 7,
+ 8, "0x7");
+
+ // old style, buffer too small for description
h_snprintb_len(
7, "\020\001lsb", 7,
8, "0x7<ls");
+
+ // old style, buffer too small for '>'
h_snprintb_len(
8, "\020\001lsb", 7,
8, "0x7<lsb");
+
+ // old style, buffer large enough for '<'
h_snprintb_len(
9, "\020\001lsb", 7,
8, "0x7<lsb>");
+
+ // old style, buffer too small for second description
h_snprintb_len(
9, "\020\001one\002two", 7,
12, "0x7<one,");
+
+ // old style, buffer too small for second description
h_snprintb_len(
10, "\020\001one\002two", 7,
12, "0x7<one,t");
+
+ // old style, buffer too small for '>' after second description
h_snprintb_len(
12, "\020\001one\002two", 7,
12, "0x7<one,two");
+
+ // old style, buffer large enough for '>' after second description
h_snprintb_len(
13, "\020\001one\002two", 7,
12, "0x7<one,two>");
- // new-style format, single bits, octal
+ // new style single bits
h_snprintb(
- "\177\010"
- "b\000bit0\0"
+ "\177\020"
+ "b\000lsb\0"
+ "b\001above-lsb\0"
"b\037bit31\0"
"b\040bit32\0"
- "b\077bit63\0",
- 0xf000000ff000000f,
- "01700000000776000000017<bit0,bit31,bit32,bit63>");
+ "b\076below-msb\0"
+ "b\077msb\0",
+ 0x8000000180000001,
+ "0x8000000180000001<lsb,bit31,bit32,msb>");
- // new-style format, single bits, decimal
+ // new style single bits, duplicate bits
h_snprintb(
- "\177\012"
- "b\000bit0\0"
- "b\037bit31\0"
- "b\040bit32\0"
- "b\077bit63\0",
- 0xf000000ff000000f,
- "17293822637553745935<bit0,bit31,bit32,bit63>");
+ "\177\020"
+ "b\000lsb\0"
+ "b\000lsb\0"
+ "b\000lsb\0",
+ 0xff,
+ "0xff<lsb,lsb,lsb>");
- // new-style format, single bits, hexadecimal
+ // new style single bits, empty description
h_snprintb(
"\177\020"
- "b\000bit0\0"
- "b\037bit31\0"
- "b\040bit32\0"
- "b\077bit63\0",
- 0xf000000ff000000f,
- "0xf000000ff000000f<bit0,bit31,bit32,bit63>");
+ "b\000lsb\0"
+ "b\001\0"
+ "b\002\0"
+ "b\007msb\0"
+ ,
+ 0xff,
+ "0xff<lsb,,,msb>");
- // new-style format, invalid number base 2
+ // new style single bits, invalid
+#if 0 /* undefined behavior due to out-of-bounds bit shift */
h_snprintb_error(
- "\177\002");
-
- // new-style format, invalid number base 255 or -1
+ "\177\020"
+ "b\100too-high\0");
+#endif
+#if 0 /* undefined behavior due to out-of-bounds bit shift */
h_snprintb_error(
- "\177\377");
+ "\177\020"
+ "b\377too-high\0");
+#endif
- // new-style format, single bits, edge cases
+ // new style single bits, non-printable description
//
- // The bits can be listed in arbitrary order, there can also be
- // duplicates. A bit's description can be empty, resulting in several
- // commas in a row.
- h_snprintb(
- "\177\020"
- "b\01lsb\0"
- "b\02\0"
- "b\03\0"
- "b\05NOTBOOT\0"
- "b\06FPP\0"
- "b\13SDVMA\0"
- "b\15VIDEO\0"
- "b\20LORES\0"
- "b\21FPA\0"
- "b\22DIAG\0"
- "b\16CACHE\0"
- "b\17IOCACHE\0"
- "b\22LOOPBACK\0"
- "b\04DBGCACHE\0",
- 0xe86f,
- "0xe86f<lsb,,,NOTBOOT,FPP,SDVMA,VIDEO,CACHE,IOCACHE>");
+ // Contrary to the old-style format, the new-style format allows
+ // arbitrary characters in the description, even control characters
+ // and non-ASCII characters.
+ h_snprintb(
+ "\177\020"
+ "b\000space \t \xC3\xA4\0",
+ 0x1,
+ "0x1<space \t \xC3\xA4>");
- // new-style format, octal, named bit-field
+ // new style named bit-field, octal
+ //
+ // The bit-field value gets a leading '0' iff it is nonzero.
h_snprintb(
"\177\010"
- "f\010\004Field\0"
- "=\001one\0"
- "=\002two\0",
- 0x100,
- "0400<Field=01=one>");
+ "f\000\010byte0\0"
+ "f\010\010byte1\0",
+ 0x0100,
+ "0400<byte0=0,byte1=01>");
- // new-style format, decimal, named bit-field
+ // new style named bit-field, decimal
h_snprintb(
"\177\012"
- "f\010\004Field\0"
- "=\1one\0"
- "=\2two\0",
- 0x100,
- "256<Field=1=one>");
+ "f\000\010byte0\0"
+ "f\010\010byte1\0",
+ 0x0100,
+ "256<byte0=0,byte1=1>");
- // new-style format, hexadecimal, named bit-field
+ // new style named bit-field, hexadecimal
h_snprintb(
"\177\020"
- "f\010\004Field\0"
- "=\1one\0"
- "=\2two\0",
- 0x100,
- "0x100<Field=0x1=one>");
+ "f\000\010byte0\0"
+ "f\010\010byte1\0",
+ 0x0100,
+ "0x100<byte0=0,byte1=0x1>");
- // new-style format, octal, unnamed bit-field
+ // new style bit-field, from 0 width 0
h_snprintb(
- "\177\010"
- "F\010\004Field\0"
- ":\001one\0"
- ":\002two\0",
- 0x100,
- "0400<one>");
+ "\177\020"
+ "f\000\000zero-width\0"
+ "=\000zero\0",
+ 0xffff,
+ "0xffff<zero-width=0=zero>");
- // new-style format, decimal, unnamed bit-field
+ // new style bit-field, from 0 width 1
h_snprintb(
- "\177\012"
- "F\010\004Field\0"
- ":\1one\0"
- ":\2two\0",
- 0x100,
- "256<one>");
+ "\177\020"
+ "f\000\001lsb\0"
+ "=\000zero\0"
+ "=\001one\0",
+ 0x0,
+ "0<lsb=0=zero>");
+ h_snprintb(
+ "\177\020"
+ "f\000\001lsb\0"
+ "=\000zero\0"
+ "=\001one\0",
+ 0x1,
+ "0x1<lsb=0x1=one>");
- // new-style format, hexadecimal, unnamed bit-field
+ // new style bit-field, from 0 width 63
h_snprintb(
"\177\020"
- "F\010\004Field\0"
- ":\1one\0"
- ":\2two\0",
- 0x100,
- "0x100<one>");
+ "f\000\077uint63\0"
+ "=\125match\0",
+ 0xaaaa5555aaaa5555,
+ "0xaaaa5555aaaa5555<uint63=0x2aaa5555aaaa5555>");
+
+ // new style bit-field, from 0 width 64
+#if 0 /* undefined behavior due to out-of-bounds bit shift */
+ h_snprintb(
+ "\177\020"
+ "f\000\100uint64\0"
+ "=\125match\0",
+ 0xaaaa5555aaaa5555,
+ "0xaaaa5555aaaa5555<uint64=0xaaaa5555aaaa5555>");
+#endif
+
+ // new style bit-field, from 0 width 65
+#if 0 /* undefined behavior due to out-of-bounds bit shift */
+ h_snprintb_error(
+ "\177\020"
+ "f\000\101uint65\0");
+#endif
+
+ // new style bit-field, from 1 width 8
+ h_snprintb(
+ "\177\020"
+ "f\001\010uint8\0"
+ "=\203match\0",
+ 0x0106,
+ "0x106<uint8=0x83=match>");
- // new-style format, hexadecimal, named bit-field, edge cases
+ // new style bit-field, from 1 width 9
//
- // Field values can be listed in arbitrary order, there can also be
- // duplicates. A field value's description can be empty, resulting in
- // several '=' in a row. The ':' directive can emulate the '='
- // directive, but not vice versa.
+ // The '=' and ':' directives can only match a bit-field value between
+ // 0 and 255, independent of the bit-field's width.
h_snprintb(
- "\177\20"
- "f\0\4Field\0"
- "=\1one\0"
- "=\1one-again\0"
- "=\1\0"
- "=\1\0"
- ":\1double\0"
- ":\1-colon\0"
- ":\1=equal\0"
- "=\2TWO\0",
- 1,
- "0x1<Field=0x1=one=one-again==double-colon=equal>");
+ "\177\020"
+ "f\001\011uint9\0"
+ "=\203match\0"
+ "*=other-f\0"
+ "F\001\011\0"
+ ":\203match\0"
+ "*other-F\0",
+ 0x0306,
+ "0x306<uint9=0x183=other-f,other-F>");
+
+ // new style bit-field, from 32 width 32
+ h_snprintb(
+ "\177\020"
+ "f\040\040uint32\0",
+ 0xaaaa555500000000,
+ "0xaaaa555500000000<uint32=0xaaaa5555>");
+
+ // new style bit-field, from 60 width 4
+ h_snprintb(
+ "\177\020"
+ "f\074\004uint4\0",
+ 0xf555555555555555,
+ "0xf555555555555555<uint4=0xf>");
- // new-style format, hexadecimal, unnamed bit-field, edge cases
+ // new style bit-field, from 60 width 5
//
- // Combining the 'F' and '=' directives generates output that doesn't
- // look well-formed.
+ // The end of the bit-field is out of bounds.
h_snprintb(
- "\177\20"
- "=\0all-zero\0"
- "=\1all-one\0"
- ":\1-continued\0"
- "F\0\4Field\0"
- "=\1one\0"
- "=\1one-again\0"
- "=\1\0"
- "=\1\0"
- ":\1double\0"
- ":\1-colon\0"
- ":\1=equal\0"
- "=\2TWO\0",
- 1,
- "0x1=all-one-continued<=one=one-again==double-colon=equal>");
+ "\177\020"
+ "f\074\005uint5\0",
+ 0xf555555555555555,
+ "0xf555555555555555<uint5=0xf>");
- // new-style format, bit-fields with fixed fallback value
+ // new style bit-field, from 64 width 0
//
- // Only the first fallback value is used, all others are ignored.
+ // The beginning of the bit-field is out of bounds, the end is fine.
+#if 0 /* undefined behavior due to out-of-bounds bit shift */
+ h_snprintb_error(
+ "\177\020"
+ "f\100\000uint0\0");
+#endif
+
+ // new style bit-field, from 65 width 0
+ //
+ // The beginning and end of the bit-field are out of bounds.
+#if 0 /* undefined behavior due to out-of-bounds bit shift */
+ h_snprintb_error(
+ "\177\020"
+ "f\101\000uint0\0");
+#endif
+
+ // new style bit-field, empty field description
+ //
+ // The description of a field may be empty, though this is probably a
+ // mistake, as it outputs an isolated '='.
h_snprintb(
"\177\020"
- "f\0\4Field\0"
- "=\1one\0"
- "=\2two\0"
- "*=other\0"
- "*=yet-another\0"
- "b\1separator\0"
- "F\0\4Field\0"
- ":\1one\0"
- ":\2two\0"
- "*other\0"
- "*yet-another\0",
- 3,
- "0x3<Field=0x3=other,separator,other>");
+ "f\000\004\0"
+ "=\001one\0",
+ 0x1,
+ "0x1<=0x1=one>");
- // new-style format, bit-fields with numeric fallback value
+ // new style bit-field, non-printable description
+ //
+ // Contrary to the old-style format, the new-style format allows
+ // arbitrary characters in the description, even control characters
+ // and non-ASCII characters.
h_snprintb(
"\177\020"
- "f\010\004Field\0"
- "*=other(%04ju)\0"
- "b\000separator\0"
- "F\010\004Field\0"
- "*other(%04ju)\0",
- 0x301,
- "0x301<Field=0x3=other(0003),separator,other(0003)>");
+ "f\000\010\t \xC3\xA4\0"
+ "=\001\t \xC3\xA4\0"
+ "F\000\010\0"
+ ":\001\t \xC3\xA4\0"
+ "F\000\010\0"
+ "*\t \xC3\xA4\0",
+ 0x1,
+ "0x1<\t \xC3\xA4=0x1=\t \xC3\xA4,\t \xC3\xA4,\t \xC3\xA4>");
- // new-style format, bit-field with more than 8 bits
+ // new style bit-field, '=' with empty description
//
- // The '=' and ':' directives can only match values from 0 to 255, so
- // the fallback value always steps in. The complete value of the
- // bit-field appears in the output, though.
+ // The description of a '=' directive may be empty, though this is
+ // probably a mistake, as it outputs several '=' in a row.
h_snprintb(
"\177\020"
- "f\010\020Field\0"
- "=\377ones\0"
- "*=other(%jx)\0"
- "F\010\020\0"
- ":\377ones\0"
- "*other(%jx)\0",
- 0x77ff55,
- "0x77ff55<Field=0x77ff=other(77ff),other(77ff)>");
+ "f\000\004f\0"
+ "=\001one\0"
+ "=\001\0"
+ "=\001\0",
+ 0x1,
+ "0x1<f=0x1=one==>");
- // new-style format, bit-field with 8 bits
+ // new style bit-field, 'F' followed by ':' with empty description
+ //
+ // The description of a ':' directive may be empty, though this is
+ // probably a mistake, as it leads to empty angle brackets.
h_snprintb(
"\177\020"
- "F\010\010\0"
- ":\377all\0"
- "*other\0",
- 0xff00,
- "0xff00<all>");
+ "F\000\004\0"
+ ":\001\0"
+ "*default\0",
+ 0x1,
+ "0x1<>");
+
+ // new style bit-field, 'F', ':' with empty description, '*'
+ //
+ // The ':' directive could be used to suppress a following '*'
+ // directive, but this combination is probably a mistake, as a
+ // matching ':' leads to empty angle brackets.
+ h_snprintb(
+ "\177\020"
+ "F\000\004\0"
+ ":\001\0"
+ "*default\0",
+ 0x2,
+ "0x2<default>");
- // new-style format, bit-fields with no match
+ // new style bit-field, 'f' with non-exhaustive '='
h_snprintb(
"\177\020"
- "f\010\004Field\0"
+ "f\000\004Field\0"
"=\1one\0"
"=\2two\0",
- 0x301,
- "0x301<Field=0x3>");
+ 0x3,
+ "0x3<Field=0x3>");
+
+ // new style bit-field, 'F' with non-exhaustive ':'
+ //
+ // A bit-field that does not match any values still generates empty
+ // angle brackets.
h_snprintb(
"\177\020"
- "F\010\004\0"
+ "F\000\004\0"
":\1one\0"
":\2two\0",
- 0x301,
- "0x301<>");
+ 0x3,
+ "0x3<>");
+
+ // new style bit-field, 'F' with non-exhaustive ':'
+ //
+ // A bit-field that does not match any values still generates empty
+ // angle brackets or adjacent commas.
h_snprintb(
"\177\020"
- "f\010\004Field\0"
- "=\1one\0"
- "=\2two\0"
- "b\000separator\0"
- "F\010\004\0"
+ "b\000bit0\0"
+ "F\000\004\0"
":\1one\0"
- ":\2two\0",
- 0x301,
- "0x301<Field=0x3,separator,>");
+ ":\2two\0"
+ "b\001bit1\0",
+ 0x3,
+ "0x3<bit0,,bit1>");
- // new-style format, two separate bit-fields
+ // new style, two separate bit-fields
h_snprintb(
- "\177\20"
- "f\0\4Field_1\0"
- "=\1ONE\0"
- "=\2TWO\0"
- "f\4\4Field_2\0"
- "=\1ONE\0"
- "=\2TWO\0",
+ "\177\020"
+ "f\000\004f1\0"
+ "=\001one\0"
+ "=\002two\0"
+ "f\004\004f2\0"
+ "=\001one\0"
+ "=\002two\0",
0x12,
- "0x12<Field_1=0x2=TWO,Field_2=0x1=ONE>");
+ "0x12<f1=0x2=two,f2=0x1=one>");
+
+ // new style, mixed named and unnamed bit-fields
+ h_snprintb(
+ "\177\020"
+ "f\000\004f1\0"
+ "=\001one\0"
+ "=\002two\0"
+ "F\010\004\0"
+ ":\015thirteen\0"
+ "f\004\004f2\0"
+ "=\001one\0"
+ "=\002two\0",
+ 0x0d12,
+ "0xd12<f1=0x2=two,thirteen,f2=0x1=one>");
+
+ // new style bit-field, overlapping
+ h_snprintb(
+ "\177\020"
+ "f\000\004lo\0"
+ "f\002\004mid\0"
+ "f\004\004hi\0"
+ "f\000\010all\0",
+ 0x18,
+ "0x18<lo=0x8,mid=0x6,hi=0x1,all=0x18>");
+
+ // new style bit-field, difference between '=' and ':'
+ //
+ // The ':' directive can almost emulate the '=' directive, without the
+ // numeric output and with a different separator. It's best to use
+ // either 'f' with '=' or 'F' with ':', but not mix them.
+ h_snprintb(
+ "\177\020"
+ "f\000\004field\0"
+ "=\010value\0"
+ "F\000\000\0"
+ ":\000field\0" // Since the description of 'F' is ignored.
+ "F\000\004\0"
+ ":\010value\0",
+ 0x18,
+ "0x18<field=0x8=value,field,value>");
+
+ // new style bit-field default, fixed string
+ //
+ // The 'f' directive pairs up with the '=' directive,
+ // the 'F' directive pairs up with the ':' directive,
+ // but there's only one 'default' directive for both variants,
+ // so its description should include the '=' when used with 'f' but
+ // not with 'F'.
+ h_snprintb(
+ "\177\020"
+ "f\030\010f1\0"
+ "*default\0"
+ "f\020\010f2\0"
+ "*=default\0"
+ "F\010\010\0"
+ "*default\0"
+ "F\010\010\0"
+ "*=default\0",
+ 0x11223344,
+ "0x11223344<f1=0x11default,f2=0x22=default,default,=default>");
+
+ // new style bit-field default, numeric conversion specifier
+ h_snprintb(
+ "\177\020"
+ "f\010\010f\0"
+ "*=f(%ju)\0"
+ "F\000\010F\0"
+ "*F(%ju)\0",
+ 0x1122,
+ "0x1122<f=0x11=f(17),F(34)>");
+
+ // new style bit-field default, invalid conversion specifier
+ //
+ // There is no reliable way to make snprintf return an error, as such
+ // errors are defined as undefined behavior in the C standard.
+ // Instead, here's a conversion specifier that produces a literal '%'.
+ h_snprintb(
+ "\177\020"
+ "f\000\010f\0"
+ "*=%030ju%%\0",
+ 0xff,
+ "0xff<f=0xff=000000000000000000000000000255%>");
+
+ // new style unknown directive
+ //
+ // Unknown directives are assumed to have a single byte argument
+ // followed by a description; they are skipped up to the next '\0'.
+ h_snprintb(
+ "\177\020"
+ "c\010ignored\0"
+ "c\000b\0"
+ "lsb\0"
+ "b\007msb\0",
+ 0xff,
+ "0xff<msb>");
+
+ // new style combinations, 'b' '='
+ //
+ // A '=' directive without a preceding 'f' or 'F' directive applies to
+ // the whole value; its description may appear inside or outside the
+ // angle brackets. Having such a format is likely an error.
+ h_snprintb(
+ "\177\020"
+ "b\004bit4\0"
+ "=\000clear\0"
+ "=\001set\0"
+ "=\245complete\0"
+ "b\000bit0\0"
+ "=\000clear\0"
+ "=\001set\0"
+ "=\245complete\0",
+ 0xa5,
+ "0xa5=complete<bit0=complete>");
+
+ // new style combinations, 'b' ':'
+ //
+ // A ':' directive without a preceding 'f' or 'F' directive applies to
+ // the whole value; its description may appear inside or outside the
+ // angle brackets. Having such a format is likely an error.
+ h_snprintb(
+ "\177\020"
+ "b\004bit4\0"
+ ":\000clear\0"
+ ":\001set\0"
+ ":\245complete\0"
+ "b\000bit0\0"
+ ":\000clear\0"
+ ":\001set\0"
+ ":\245complete\0",
+ 0xa5,
+ "0xa5complete<bit0complete>");
+
+ // new style combinations, 'b' '*'
+ //
+ // A '*' directive without a preceding 'f' or 'F' directive is ignored.
+ h_snprintb(
+ "\177\020"
+ "b\004bit4\0"
+ "*default(%ju)\0"
+ "b\000bit0\0"
+ "*default(%ju)\0",
+ 0xa5,
+ "0xa5<bit0>");
+
+ // new style combinations, 'f' 'b' '='
+ //
+ // Between an 'f' and an '=' directive, there may be unrelated 'b'
+ // directives, they do not affect the value of the "previous field".
+ // Formats like these are probably mistakes.
+ h_snprintb(
+ "\177\020"
+ "f\000\010f\0"
+ "b\005bit5\0"
+ "=\xa5match\0",
+ 0xa5,
+ "0xa5<f=0xa5,bit5=match>");
+
+ // new style combinations, 'f' 'b' ':'
+ //
+ // Between an 'f' and a ':' directive, there may be unrelated 'b'
+ // directives, they do not affect the value of the "previous field".
+ // Formats like these are mistakes, as the output is garbled.
+ h_snprintb(
+ "\177\020"
+ "f\000\010f\0"
+ "b\005bit5\0"
+ ":\xa5match\0",
+ 0xa5,
+ "0xa5<f=0xa5,bit5match>");
+
+ // new style combinations, 'f' ':'
+ h_snprintb(
+ "\177\20"
+ "f\000\004nibble\0"
+ ":\001one\0",
+ 0x01,
+ "0x1<nibble=0x1one>");
+
+ // new style combinations, 'F' '='
+ //
+ // Combining the 'F' and '=' directives outputs an isolated '=', which
+ // doesn't look well-formed.
+ h_snprintb(
+ "\177\20"
+ "F\000\004\0"
+ "=\001one\0",
+ 0x01,
+ "0x1<=one>");
+
+ // new style combinations, '='
+ //
+ // A '=' directive without a preceding 'f' or 'F' directive matches on
+ // the complete value. This is not documented in the manual page, and
+ // formats like these are probably mistakes.
+ h_snprintb(
+ "\177\020"
+ "=\xa5match\0",
+ 0xa5,
+ "0xa5=match");
+
+ // new style combinations, ':'
+ //
+ // A ':' directive without a preceding 'f' or 'F' directive matches on
+ // the complete value. This is not documented in the manual page, and
+ // formats like these are probably mistakes.
+ h_snprintb(
+ "\177\020"
+ ":\xa5match\0",
+ 0xa5,
+ "0xa5match");
+
+ // new style combinations, '*'
+ //
+ // A '*' directive without a preceding 'f' or 'F' is skipped. Formats
+ // like these are mistakes.
+ h_snprintb(
+ "\177\020"
+ "*match\0",
+ 0xa5,
+ "0xa5");
+
+ // new style combinations, 'f' '*' '='
+ //
+ // A '*' directive may be followed by a '=' directive. Formats like
+ // this are probably a mistake.
+ h_snprintb(
+ "\177\020"
+ "f\000\010f\0"
+ "*=default\0"
+ "=\xa5match\0",
+ 0xa5,
+ "0xa5<f=0xa5=default=match>");
+
+ // new style combinations, 'F' '*' ':'
+ //
+ // A '*' directive may be followed by a ':' directive. Formats like
+ // this are probably a mistake.
+ h_snprintb(
+ "\177\020"
+ "F\000\010F\0"
+ "*default\0"
+ ":\xa5-match\0",
+ 0xa5,
+ "0xa5<default-match>");
+
+ // new style combinations, '*' '*'
+ //
+ // The first '*' directive matches everything, so the second '*'
+ // directive cannot match anything and is thus redundant. Formats like
+ // this are a mistake.
+ h_snprintb(
+ "\177\020"
+ "f\000\010f\0"
+ "*=default-f\0"
+ "*ignored\0"
+ "F\000\010\0"
+ "*default-F\0"
+ "*ignored\0",
+ 0xa5,
+ "0xa5<f=0xa5=default-f,default-F>");
+
+ // manual page, old style octal
+ h_snprintb(
+ "\10\2BITTWO\1BITONE",
+ 3,
+ "03<BITTWO,BITONE>");
+
+ // manual page, old style hexadecimal
+ h_snprintb(
+ "\20"
+ "\x10NOTBOOT" "\x0f""FPP" "\x0eSDVMA"
+ "\x0cVIDEO" "\x0bLORES" "\x0a""FPA" "\x09""DIAG"
+ "\x07""CACHE" "\x06IOCACHE" "\x05LOOPBACK"
+ "\x04""DBGCACHE",
+ 0xe860,
+ "0xe860<NOTBOOT,FPP,SDVMA,VIDEO,CACHE,IOCACHE>");
+
+ // manual page, new style bits and fields
+ h_snprintb(
+ "\177\020"
+ "b\0LSB\0" "b\1BITONE\0"
+ "f\4\4NIBBLE2\0"
+ "f\x10\4BURST\0" "=\4FOUR\0" "=\xf""FIFTEEN\0"
+ "b\x1fMSB\0",
+ 0x800f0701,
+ "0x800f0701<LSB,NIBBLE2=0,BURST=0xf=FIFTEEN,MSB>");
- // new-style format, mixed named and unnamed bit-fields
- h_snprintb(
- "\177\20"
- "f\0\4Field_1\0"
- "=\1ONE\0"
- "=\2TWO\0"
- "F\x8\4\0"
- "*Field_3=%jd\0"
- "f\4\4Field_2\0"
- ":\1:ONE\0"
- ":\2:TWO\0",
- 0xD12,
- "0xd12<Field_1=0x2=TWO,Field_3=13,Field_2=0x1:ONE>");
-
- // new-style format, descriptions with spaces
- h_snprintb(
- "\177\020"
- "b\000has std options\0"
- "f\010\004std options\0"
- "=\000no options\0"
- "=\017all options\0"
- "F\020\004ext options\0"
- ":\000no ext options\0"
- ":\017all ext options\0",
- 0x000001,
- "0x1<has std options,std options=0=no options,no ext options>");
- h_snprintb(
- "\177\020"
- "f\010\004std options\0"
- "*=other std options\0"
- "F\020\004ext\toptions\0"
- "*other\text\toptions\0",
- 0x000001,
- "0x1<std options=0=other std options,other\text\toptions>");
+ // manual page, new style mmap
+#define MAP_FMT \
+ "\177\020" \
+ "b\0" "SHARED\0" \
+ "b\1" "PRIVATE\0" \
+ "b\2" "COPY\0" \
+ "b\4" "FIXED\0" \
+ "b\5" "RENAME\0" \
+ "b\6" "NORESERVE\0" \
+ "b\7" "INHERIT\0" \
+ "b\11" "HASSEMAPHORE\0" \
+ "b\12" "TRYFIXED\0" \
+ "b\13" "WIRED\0" \
+ "F\14\1\0" \
+ ":\0" "FILE\0" \
+ ":\1" "ANONYMOUS\0" \
+ "b\15" "STACK\0" \
+ "F\30\010\0" \
+ ":\000" "ALIGN=NONE\0" \
+ ":\015" "ALIGN=8KB\0" \
+ "*" "ALIGN=2^%ju\0"
+ h_snprintb(
+ MAP_FMT,
+ 0x0d001234,
+ "0xd001234<COPY,FIXED,RENAME,HASSEMAPHORE,ANONYMOUS,ALIGN=8KB>");
+ h_snprintb(
+ MAP_FMT,
+ 0x2e000000,
+ "0x2e000000<FILE,ALIGN=2^46>");
// It is possible but cumbersome to implement a reduced variant of
// rot13 using snprintb, shown here for lowercase letters only.
@@ -595,7 +1044,7 @@ ATF_TC_BODY(snprintb, tc)
expected);
}
- // new-style format, small buffers
+ // new style, small buffers
h_snprintb_len(
0, "\177\020", 0,
1, "");
@@ -635,29 +1084,33 @@ ATF_TC_BODY(snprintb, tc)
h_snprintb_len(
13, "\177\020b\000one\0b\001two\0", 7,
12, "0x7<one,two>");
-
}
static void
h_snprintb_m_loc(const char *file, size_t line,
- size_t bufsize, const char *fmt, size_t fmtlen, uint64_t val, size_t max,
- size_t exp_rv, const char *res, size_t reslen)
+ size_t bufsize, const char *bitfmt, size_t bitfmtlen, uint64_t val,
+ size_t max,
+ size_t want_rv, const char *want_buf, size_t want_bufsize)
{
char buf[1024];
ATF_REQUIRE(bufsize > 0);
ATF_REQUIRE(bufsize <= sizeof(buf));
- ATF_REQUIRE(reslen <= sizeof(buf));
+ ATF_REQUIRE(want_bufsize <= sizeof(buf));
+ if (bitfmtlen > 2 && bitfmt[0] == '\177')
+ ATF_REQUIRE_MSG(bitfmt[bitfmtlen - 1] == '\0',
+ "%s:%zu: missing trailing '\\0' in bitfmt",
+ file, line);
memset(buf, 'Z', sizeof(buf));
- int rv = snprintb_m(buf, bufsize, fmt, val, max);
+ int rv = snprintb_m(buf, bufsize, bitfmt, val, max);
ATF_REQUIRE_MSG(rv >= 0,
"formatting %jx with '%s' returns error %d",
- (uintmax_t)val, vis_arr(fmt, fmtlen), rv);
+ (uintmax_t)val, vis_arr(bitfmt, bitfmtlen), rv);
size_t total = rv;
ATF_CHECK_MSG(
- total == exp_rv && memcmp(buf, res, reslen) == 0,
+ total == want_rv && memcmp(buf, want_buf, want_bufsize) == 0,
"failed:\n"
"\ttest case: %s:%zu\n"
"\tformat: %s\n"
@@ -666,20 +1119,21 @@ h_snprintb_m_loc(const char *file, size_
"\twant: %zu bytes %s\n"
"\thave: %zu bytes %s\n",
file, line,
- vis_arr(fmt, fmtlen),
+ vis_arr(bitfmt, bitfmtlen),
(uintmax_t)val,
max,
- exp_rv, vis_arr(res, reslen),
- total, vis_arr(buf, reslen));
- check_unmodified_loc(file, line, buf, reslen, sizeof(buf));
+ want_rv, vis_arr(want_buf, want_bufsize),
+ total, vis_arr(buf, want_bufsize));
+ check_unmodified_loc(file, line, buf, want_bufsize, sizeof(buf));
}
-#define h_snprintb_m_len(bufsize, fmt, val, line_max, exp_rv, res) \
+#define h_snprintb_m_len(bufsize, bitfmt, val, line_max, want_rv, want_buf) \
h_snprintb_m_loc(__FILE__, __LINE__, \
- bufsize, fmt, sizeof(fmt) - 1, val, line_max, \
- exp_rv, res, sizeof(res))
-#define h_snprintb_m(fmt, val, max, res) \
- h_snprintb_m_len(1024, fmt, val, max, sizeof(res) - 1, res)
+ bufsize, bitfmt, sizeof(bitfmt) - 1, val, line_max, \
+ want_rv, want_buf, sizeof(want_buf))
+#define h_snprintb_m(bitfmt, val, line_max, want_buf) \
+ h_snprintb_m_len(1024, bitfmt, val, line_max, \
+ sizeof(want_buf) - 1, want_buf)
ATF_TC(snprintb_m);
ATF_TC_HEAD(snprintb_m, tc)
@@ -688,126 +1142,437 @@ ATF_TC_HEAD(snprintb_m, tc)
}
ATF_TC_BODY(snprintb_m, tc)
{
- // old-style format, small maximum line length
- h_snprintb_m_len(
- 68,
+
+ // old style, line_max exceeded by number in line 1
+ h_snprintb_m(
+ "\020",
+ 0xff,
+ 1,
+ "0xff\0"); // FIXME: line longer than line_max
+
+ // old style, line_max exceeded by '<' in line 1
+ h_snprintb_m(
+ "\020",
+ 0xff,
+ 4,
+ "0xff\0");
+
+ // old style, line_max exceeded by description in line 1
+ h_snprintb_m(
"\020"
"\001bit1"
- "\002bit2"
- "\003bit3",
- 0xffff,
- 6,
- 143,
- "0xffff>\0"
- "0xffff<>\0"
- "0xffffb>\0"
- "0xffffi>\0"
- "0xfffft>\0"
- "0xffff1>\0"
- "0xffff<>\0"
- "0xff\0"
- );
+ "\002bit2",
+ 0xff,
+ 4,
+ "0xff>\0" // FIXME: unbalanced angle brackets
+ "0xff<>\0" // FIXME: empty angle brackets
+ "0xffb>\0" // FIXME: partial description
+ "0xffi>\0"
+ "0xfft>\0"
+ "0xff1>\0"
+ "0xff<>\0" // FIXME: empty angle brackets
+ "0xffb>\0" // FIXME: partial description
+ "0xffi>\0"
+ "0xfft>\0"
+ "0xff2>\0");
- // new-style format, small maximum line length
- h_snprintb_m_len(
- 68,
- "\177\020"
- "b\000bit1\0"
- "b\001bit2\0"
- "b\002bit3\0",
- 0xffff,
- 6,
- 143,
- "0xffff>\0"
- "0xffff<>\0"
- "0xffffb>\0"
- "0xffffi>\0"
- "0xfffft>\0"
- "0xffff1>\0"
- "0xffff<>\0"
- "0xff\0"
- );
+ // old style, line_max exceeded by '>' in line 1
+ h_snprintb_m(
+ "\020"
+ "\001bit1"
+ "\0022",
+ 0xff,
+ 9,
+ "0xff<bit>\0"
+ "0xff1,2>\0");
- // new-style format, buffer too small for number
- h_snprintb_m_len(
- 2,
+ // old style, line_max exceeded by description in line 2
+ h_snprintb_m(
+ "\020"
+ "\0011"
+ "\002bit2",
+ 0xff,
+ 8,
+ "0xff<1>\0"
+ "0xff<bi>\0" // FIXME: incomplete description
+ "0xfft2>\0"); // FIXME: unbalanced angle brackets
+
+ // old style, line_max exceeded by '>' in line 2
+ h_snprintb_m(
+ "\020"
+ "\0011"
+ "\002bit2",
+ 0xff,
+ 9,
+ "0xff<1>\0"
+ "0xff<bit>\0" // FIXME: incomplete description
+ "0xff2>\0"); // FIXME: unbalanced angle brackets
+
+ // old style complete
+ h_snprintb_m(
+ "\020"
+ "\0011"
+ "\002bit2",
+ 0xff,
+ 10,
+ "0xff<1>\0"
+ "0xff<bit2>\0");
+
+ // new style, line_max exceeded by value in line 1
+ h_snprintb_m(
"\177\020",
- 0,
- 64,
- 2,
- "\0"
- );
+ 0xff,
+ 1,
+ "0xff\0"); // FIXME: line too long
- // new-style format, buffer too small for '<'
- h_snprintb_m_len(
- 6,
+ // new style, line_max exceeded by single-bit '<' in line 1
+ h_snprintb_m(
"\177\020"
- "b\000lsb\0",
+ "b\000bit\0",
0xff,
- 64,
- 10,
- "0xff\0"
- );
+ 4,
+ "0xff>\0" // FIXME: unbalanced angle brackets
+ "0xff<>\0"
+ "0xffb>\0"
+ "0xffi>\0"
+ "0xfft>\0"); // FIXME: line too long
- // new-style format, buffer too small for description
- h_snprintb_m_len(
+ // new style, line_max exceeded by single-bit description in line 1
+ h_snprintb_m(
+ "\177\020"
+ "b\000bit0\0"
+ "b\001two\0",
+ 0xff,
+ 8,
+ "0xff<bi>\0" // FIXME: incomplete description
+ "0xfft0>\0" // FIXME: unbalanced angle brackets
+ "0xff<tw>\0" // FIXME: incomplete description
+ "0xffo>\0"); // FIXME: unbalanced angle brackets
+
+ // new style, line_max exceeded by single-bit '>' in line 1
+ h_snprintb_m(
+ "\177\020"
+ "b\000bit0\0"
+ "b\001two\0",
+ 0xff,
+ 9,
+ "0xff<bit>\0" // FIXME: incomplete description
+ "0xff0>\0" // FIXME: empty angle brackets
+ "0xff<two>\0"); // FIXME: incomplete description
+
+ // new style, line_max exceeded by single-bit description in line 2
+ h_snprintb_m(
+ "\177\020"
+ "b\000one\0"
+ "b\001three\0",
+ 0xff,
+ 9,
+ "0xff<one>\0"
+ "0xff<thr>\0" // FIXME: incomplete description
+ "0xffee>\0"); // FIXME: unbalanced angle brackets
+
+ // new style, line_max exceeded by single-bit '>' in line 2
+ h_snprintb_m(
+ "\177\020"
+ "b\000one\0"
+ "b\001four\0",
+ 0xff,
+ 9,
+ "0xff<one>\0"
+ "0xff<fou>\0" // FIXME: incomplete description
+ "0xffr>\0"); // FIXME: unbalanced angle brackets
+
+ // new style, single-bit complete
+ h_snprintb_m(
+ "\177\020"
+ "b\000one\0"
+ "b\001three\0",
+ 0xff,
+ 11,
+ "0xff<one>\0"
+ "0xff<three>\0");
+
+ // new style, line_max exceeded by named bit-field number in line 1
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0",
+ 0xff,
+ 3,
+ "0xff>\0" // FIXME: unbalanced angle brackets
+ "0xff<>\0"
+ "0xffl>\0" // FIXME: incomplete bit-field description
+ "0xffo>\0"
+ "0xff=0xf>\0" // FIXME: line too long
+ "0xff#>\0");
+
+ // new style, line_max exceeded by named bit-field '<' in line 1
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0",
+ 0xff,
+ 4,
+ "0xff>\0" // FIXME: unbalanced angle brackets
+ "0xff<>\0"
+ "0xffl>\0" // FIXME: incomplete bit-field description
+ "0xffo>\0"
+ "0xff=0xf>\0" // FIXME: line too long
+ "0xff#>\0");
+
+ // new style, line_max exceeded by named bit-field field description in line 1
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0",
+ 0xff,
+ 6,
+ "0xff<>\0"
+ "0xffl>\0"
+ "0xffo>\0" // FIXME: incomplete bit-field description
+ "0xff=0xf>\0" // FIXME: line too long
+ "0xff#>\0");
+
+ // new style, line_max exceeded by named bit-field '=' in line 1
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0",
+ 0xff,
7,
+ "0xff<l>\0" // FIXME: unbalanced angle brackets
+ "0xffo=0xf>\0"
+ "0xff#>\0");
+
+ // new style, line_max exceeded by named bit-field value in line 1
+ h_snprintb_m(
"\177\020"
- "b\000lsb\0",
+ "f\000\004lo\0",
0xff,
- 64,
10,
- "0xff<\0"
- );
+ "0xff<lo=0xf>\0" // FIXME: line too long
+ "0xff#>\0"); // FIXME: unbalanced angle brackets
- // new-style format, buffer too small for complete description
- h_snprintb_m_len(
+ // new style, line_max exceeded by named bit-field '=' in line 1
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "=\017match\0",
+ 0xff,
+ 11,
+ "0xff<lo=0xf>\0" // FIXME: line too long
+ "0xff=match>\0"); // FIXME: unbalanced angle brackets
+
+ // new style, line_max exceeded by named bit-field value description in line 1
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "=\017match\0",
+ 0xff,
+ 16,
+ "0xff<lo=0xf=mat>\0" // FIXME: incomplete field description
+ "0xffch>\0"); // FIXME: unbalanced angle brackets
+
+ // new style, line_max exceeded by named bit-field '>' in line 1
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "=\017match\0",
+ 0xff,
+ 17,
+ "0xff<lo=0xf=matc>\0" // FIXME: incomplete field description
+ "0xffh>\0"); // FIXME: unbalanced angle brackets
+
+ // new style, line_max exceeded by named bit-field description in line 2
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "f\000\004low-bits\0"
+ "=\017match\0",
+ 0xff,
+ 12,
+ "0xff<lo=0xf>\0"
+ "0xff<low-bi>\0"
+ "0xffts=0xf=>\0"
+ "0xffmatch>\0");
+
+ // new style, line_max exceeded by named bit-field '=' in line 2
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "f\000\004low-bits\0"
+ "=\017match\0",
+ 0xff,
+ 13,
+ "0xff<lo=0xf>\0"
+ "0xff<low-bit>\0"
+ "0xffs=0xf=ma>\0"
+ "0xfftch>\0");
+
+ // new style, line_max exceeded by named bit-field value in line 2
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "f\000\004low-bits\0"
+ "=\017match\0",
+ 0xff,
+ 16,
+ "0xff<lo=0xf>\0"
+ "0xff<low-bits=0xf>\0" // FIXME: line too long
+ "0xff#=match>\0");
+
+ // new style, line_max exceeded by named bit-field '=' in line 2
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "f\000\004low-bits\0"
+ "=\017match\0",
+ 0xff,
+ 17,
+ "0xff<lo=0xf>\0"
+ "0xff<low-bits=0xf>\0" // FIXME: line too long
+ "0xff=match>\0");
+
+ // new style, line_max exceeded by named bit-field value description in line 2
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "f\000\004low-bits\0"
+ "=\017match\0",
+ 0xff,
+ 22,
+ "0xff<lo=0xf>\0"
+ "0xff<low-bits=0xf=mat>\0" // FIXME: incomplete description
+ "0xffch>\0");
+
+ // new style, line_max exceeded by named bit-field '>' in line 2
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "f\000\004low-bits\0"
+ "=\017match\0",
+ 0xff,
+ 23,
+ "0xff<lo=0xf>\0"
+ "0xff<low-bits=0xf=matc>\0" // FIXME: incomplete description
+ "0xffh>\0");
+
+ // new style, named bit-field complete
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004lo\0"
+ "f\000\004low-bits\0"
+ "=\017match\0",
+ 0xff,
+ 24,
+ "0xff<lo=0xf>\0"
+ "0xfff=match\0"); // FIXME: incomplete
+
+ // new style, line_max exceeded by unnamed bit-field number in line 1
+ h_snprintb_m(
+ "\177\020"
+ "F\000\004\0",
+ 0xff,
+ 3,
+ "0xff>\0" // FIXME: unbalanced angle brackets
+ "0xff<>\0"); // FIXME: empty angle brackets
+
+ // new style, line_max exceeded by unnamed bit-field '<' in line 1
+ h_snprintb_m(
+ "\177\020"
+ "F\000\004\0",
+ 0xff,
+ 4,
+ "0xff>\0" // FIXME: unbalanced angle brackets
+ "0xff<>\0"); // FIXME: empty angle brackets
+
+ // new style, line_max exceeded by unnamed bit-field value description in line 1
+ h_snprintb_m(
+ "\177\020"
+ "F\000\004\0"
+ ":\017match\0",
+ 0xff,
9,
+ "0xff<mat>\0"
+ "0xffch>\0"); // FIXME: unbalanced angle brackets
+
+ // new style, line_max exceeded by unnamed bit-field '>' in line 1
+ h_snprintb_m(
"\177\020"
- "b\000lsb\0",
+ "F\000\004\0"
+ ":\017match\0",
0xff,
- 64,
10,
- "0xff<ls\0"
- );
+ "0xff<matc>\0" // FIXME: unbalanced angle brackets
+ "0xffh>\0"); // FIXME: empty angle brackets
- // new-style format, buffer too small for '>'
- h_snprintb_m_len(
+ // new style, line_max exceeded by unnamed bit-field value description in line 2
+ h_snprintb_m(
+ "\177\020"
+ "F\000\004\0"
+ ":\017m1\0"
+ ":\017match\0",
+ 0xff,
10,
+ "0xff<m1ma>\0" // XXX: don't concatenate?
+ "0xfftch>\0");
+
+ // new style, line_max exceeded by unnamed bit-field '>' in line 2
+ h_snprintb_m(
"\177\020"
- "b\000lsb\0",
+ "F\000\004\0"
+ ":\017m1\0"
+ ":\017match\0",
0xff,
- 64,
10,
- "0xff<lsb\0"
- );
+ "0xff<m1ma>\0" // XXX: don't concatenate?
+ "0xfftch>\0");
- // new-style format, buffer too small for second line
- h_snprintb_m_len(
- 11,
+ // new style unnamed bit-field complete
+ h_snprintb_m(
"\177\020"
- "b\000lsb\0"
- "b\001two\0",
+ "F\000\004\0"
+ ":\017m1\0"
+ ":\017match\0",
0xff,
11,
- 20,
- "0xff<lsb>\0"
- );
+ "0xff<m1mat>\0" // XXX: don't concatenate?
+ "0xffch>\0");
- // new-style format, buffer too small for number in line 2
- h_snprintb_m_len(
- 12,
+ // new style, line_max exceeded by bit-field default
+ h_snprintb_m(
"\177\020"
- "b\000lsb\0"
- "b\001two\0",
+ "f\000\004f\0"
+ "*=default\0",
+ 0xff,
+ 17,
+ "0xff<f=0xf=default>\0"); // FIXME: line too long
+
+ // new style, line_max exceeded by unmatched field value
+ h_snprintb_m(
+ "\177\020"
+ "f\000\004bits\0"
+ ":\000other\0",
0xff,
11,
- 20,
- "0xff<lsb>\0"
- "\0"
- );
+ "0xff<bits=0xf>\0" // XXX: line too long (14 > 11)
+ "0xff#>\0"); // XXX: why '#'? unbalanced '<>'
+
+ // manual page, new style bits and fields
+ h_snprintb_m(
+ "\177\020"
+ "b\0LSB\0"
+ "b\1BITONE\0"
+ "f\4\4NIBBLE2\0"
+ "f\x10\4BURST\0"
+ "=\4FOUR\0"
+ "=\xf""FIFTEEN\0"
+ "b\x1fMSB\0",
+ 0x800f0701,
+ 34,
+ "0x800f0701<LSB,NIBBLE2=0>\0"
+ // FIXME: The '\020\004' is wrong.
+ // FIXME: The '=0xf' is missing.
+ // FIXME: The '<' is in the wrong place.
+ "0x800f0701f\020\004BURST=FIFTEEN<MSB>\0");
- // new-style format, buffer too small for complete number in line 2
+ // new style, buffer too small for complete number in line 2
h_snprintb_m_len(
15,
"\177\020"
@@ -833,56 +1598,15 @@ ATF_TC_BODY(snprintb_m, tc)
"0xff\0"
);
- // new-style format, buffer too small for description in line 2
- h_snprintb_m_len(
- 17,
- "\177\020"
- "b\000lsb\0"
- "b\001two\0",
- 0xff,
- 11,
- 20,
- "0xff<lsb>\0"
- "0xff<\0"
- );
-
- // new-style format, line too small for unmatched field value
- h_snprintb_m_len(
- 30,
- "\177\020"
- "f\000\004bits\0"
- ":\000other\0",
- 0xff,
- 11,
- 22,
- "0xff<bits=0xf>\0" // XXX: line too long (14 > 11)
- "0xff#>\0" // XXX: why '#'? unbalanced '<>'
- );
-
- // new-style format, line too small for field value
- h_snprintb_m_len(
- 30,
- "\177\020"
- "f\000\004bits\0"
- ":\017other\0",
- 0xff,
- 11,
- 27,
- "0xff<bits=0xf>\0" // XXX: line too long (14 > 11)
- "0xff#other>\0" // XXX: unbalanced '<>'
- );
-
// new-style format, buffer too small for fallback
- h_snprintb_m_len(
- 20,
+ h_snprintb_m(
"\177\020"
"f\000\004bits\0"
"*=fallback\0"
"b\0024\0",
0xff,
64,
- 26,
- "0xff<bits=0xf=fall\0"
+ "0xff<bits=0xf=fallback,4>\0"
);
// new-style format, buffer too small for numeric fallback
@@ -911,6 +1635,7 @@ ATF_TC_BODY(snprintb_m, tc)
"0xff<fallback\0"
);
+ // new style, bits and fields, line break between fields
h_snprintb_m(
"\177\020"
"b\0LSB\0"
@@ -926,6 +1651,7 @@ ATF_TC_BODY(snprintb_m, tc)
"0x800f0701<BURST=0xf=FIFTEEN,MSB>\0"
);
+ // new style, bits and fields, line break after field description
h_snprintb_m(
"\177\020"
"b\0LSB\0"