xref: /freebsd/lib/libc/tests/stdio/sscanf_test.c (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
1 /*-
2  * Copyright (c) 2023 Dag-Erling Smørgrav
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <locale.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 
11 #include <atf-c.h>
12 
13 static const struct sscanf_test_case {
14 	char input[8];
15 	struct {
16 		int ret, val, len;
17 	} b, o, d, x, i;
18 } sscanf_test_cases[] = {
19 //	input		binary		octal		decimal		hexadecimal	automatic
20 	// all digits
21 	{ "0",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 }, },
22 	{ "1",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 }, },
23 	{ "2",		{ 0,   0, 0 },	{ 1,   2, 1 },	{ 1,   2, 1 },	{ 1,   2, 1 },	{ 1,   2, 1 }, },
24 	{ "3",		{ 0,   0, 0 },	{ 1,   3, 1 },	{ 1,   3, 1 },	{ 1,   3, 1 },	{ 1,   3, 1 }, },
25 	{ "4",		{ 0,   0, 0 },	{ 1,   4, 1 },	{ 1,   4, 1 },	{ 1,   4, 1 },	{ 1,   4, 1 }, },
26 	{ "5",		{ 0,   0, 0 },	{ 1,   5, 1 },	{ 1,   5, 1 },	{ 1,   5, 1 },	{ 1,   5, 1 }, },
27 	{ "6",		{ 0,   0, 0 },	{ 1,   6, 1 },	{ 1,   6, 1 },	{ 1,   6, 1 },	{ 1,   6, 1 }, },
28 	{ "7",		{ 0,   0, 0 },	{ 1,   7, 1 },	{ 1,   7, 1 },	{ 1,   7, 1 },	{ 1,   7, 1 }, },
29 	{ "8",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,   8, 1 },	{ 1,   8, 1 },	{ 1,   8, 1 }, },
30 	{ "9",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,   9, 1 },	{ 1,   9, 1 },	{ 1,   9, 1 }, },
31 	{ "A",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  10, 1 },	{ 0,   0, 0 }, },
32 	{ "B",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  11, 1 },	{ 0,   0, 0 }, },
33 	{ "C",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  12, 1 },	{ 0,   0, 0 }, },
34 	{ "D",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  13, 1 },	{ 0,   0, 0 }, },
35 	{ "E",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  14, 1 },	{ 0,   0, 0 }, },
36 	{ "F",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  15, 1 },	{ 0,   0, 0 }, },
37 	{ "X",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 }, },
38 	{ "a",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  10, 1 },	{ 0,   0, 0 }, },
39 	{ "b",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  11, 1 },	{ 0,   0, 0 }, },
40 	{ "c",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  12, 1 },	{ 0,   0, 0 }, },
41 	{ "d",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  13, 1 },	{ 0,   0, 0 }, },
42 	{ "e",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  14, 1 },	{ 0,   0, 0 }, },
43 	{ "f",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 1,  15, 1 },	{ 0,   0, 0 }, },
44 	{ "x",		{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 },	{ 0,   0, 0 }, },
45 	// all digits with leading zero
46 	{ "00",		{ 1,   0, 2 },	{ 1,   0, 2 },	{ 1,   0, 2 },	{ 1,   0, 2 },	{ 1,   0, 2 }, },
47 	{ "01",		{ 1,   1, 2 },	{ 1,   1, 2 },	{ 1,   1, 2 },	{ 1,   1, 2 },	{ 1,   1, 2 }, },
48 	{ "02",		{ 1,   0, 1 },	{ 1,   2, 2 },	{ 1,   2, 2 },	{ 1,   2, 2 },	{ 1,   2, 2 }, },
49 	{ "03",		{ 1,   0, 1 },	{ 1,   3, 2 },	{ 1,   3, 2 },	{ 1,   3, 2 },	{ 1,   3, 2 }, },
50 	{ "04",		{ 1,   0, 1 },	{ 1,   4, 2 },	{ 1,   4, 2 },	{ 1,   4, 2 },	{ 1,   4, 2 }, },
51 	{ "05",		{ 1,   0, 1 },	{ 1,   5, 2 },	{ 1,   5, 2 },	{ 1,   5, 2 },	{ 1,   5, 2 }, },
52 	{ "06",		{ 1,   0, 1 },	{ 1,   6, 2 },	{ 1,   6, 2 },	{ 1,   6, 2 },	{ 1,   6, 2 }, },
53 	{ "07",		{ 1,   0, 1 },	{ 1,   7, 2 },	{ 1,   7, 2 },	{ 1,   7, 2 },	{ 1,   7, 2 }, },
54 	{ "08",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   8, 2 },	{ 1,   8, 2 },	{ 1,   0, 1 }, },
55 	{ "09",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   9, 2 },	{ 1,   9, 2 },	{ 1,   0, 1 }, },
56 	{ "0A",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  10, 2 },	{ 1,   0, 1 }, },
57 	{ "0B",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  11, 2 },	{ 1,   0, 1 }, },
58 	{ "0C",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  12, 2 },	{ 1,   0, 1 }, },
59 	{ "0D",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  13, 2 },	{ 1,   0, 1 }, },
60 	{ "0E",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  14, 2 },	{ 1,   0, 1 }, },
61 	{ "0F",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  15, 2 },	{ 1,   0, 1 }, },
62 	{ "0X",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 }, },
63 	{ "0a",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  10, 2 },	{ 1,   0, 1 }, },
64 	{ "0b",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  11, 2 },	{ 1,   0, 1 }, },
65 	{ "0c",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  12, 2 },	{ 1,   0, 1 }, },
66 	{ "0d",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  13, 2 },	{ 1,   0, 1 }, },
67 	{ "0e",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  14, 2 },	{ 1,   0, 1 }, },
68 	{ "0f",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  15, 2 },	{ 1,   0, 1 }, },
69 	{ "0x",		{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 }, },
70 	// all digits with leading one
71 	{ "10",		{ 1,   2, 2 },	{ 1,   8, 2 },	{ 1,  10, 2 },	{ 1,  16, 2 },	{ 1,  10, 2 }, },
72 	{ "11",		{ 1,   3, 2 },	{ 1,   9, 2 },	{ 1,  11, 2 },	{ 1,  17, 2 },	{ 1,  11, 2 }, },
73 	{ "12",		{ 1,   1, 1 },	{ 1,  10, 2 },	{ 1,  12, 2 },	{ 1,  18, 2 },	{ 1,  12, 2 }, },
74 	{ "13",		{ 1,   1, 1 },	{ 1,  11, 2 },	{ 1,  13, 2 },	{ 1,  19, 2 },	{ 1,  13, 2 }, },
75 	{ "14",		{ 1,   1, 1 },	{ 1,  12, 2 },	{ 1,  14, 2 },	{ 1,  20, 2 },	{ 1,  14, 2 }, },
76 	{ "15",		{ 1,   1, 1 },	{ 1,  13, 2 },	{ 1,  15, 2 },	{ 1,  21, 2 },	{ 1,  15, 2 }, },
77 	{ "16",		{ 1,   1, 1 },	{ 1,  14, 2 },	{ 1,  16, 2 },	{ 1,  22, 2 },	{ 1,  16, 2 }, },
78 	{ "17",		{ 1,   1, 1 },	{ 1,  15, 2 },	{ 1,  17, 2 },	{ 1,  23, 2 },	{ 1,  17, 2 }, },
79 	{ "18",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  18, 2 },	{ 1,  24, 2 },	{ 1,  18, 2 }, },
80 	{ "19",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  19, 2 },	{ 1,  25, 2 },	{ 1,  19, 2 }, },
81 	{ "1A",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  26, 2 },	{ 1,   1, 1 }, },
82 	{ "1B",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  27, 2 },	{ 1,   1, 1 }, },
83 	{ "1C",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  28, 2 },	{ 1,   1, 1 }, },
84 	{ "1D",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  29, 2 },	{ 1,   1, 1 }, },
85 	{ "1E",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  30, 2 },	{ 1,   1, 1 }, },
86 	{ "1F",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  31, 2 },	{ 1,   1, 1 }, },
87 	{ "1X",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 }, },
88 	{ "1a",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  26, 2 },	{ 1,   1, 1 }, },
89 	{ "1b",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  27, 2 },	{ 1,   1, 1 }, },
90 	{ "1c",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  28, 2 },	{ 1,   1, 1 }, },
91 	{ "1d",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  29, 2 },	{ 1,   1, 1 }, },
92 	{ "1e",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  30, 2 },	{ 1,   1, 1 }, },
93 	{ "1f",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,  31, 2 },	{ 1,   1, 1 }, },
94 	{ "1x",		{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 },	{ 1,   1, 1 }, },
95 	// all digits with leading binary prefix
96 	{ "0b0",	{ 1,   0, 3 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 176, 3 },	{ 1,   0, 3 }, },
97 	{ "0b1",	{ 1,   1, 3 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 177, 3 },	{ 1,   1, 3 }, },
98 	{ "0b2",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 178, 3 },	{ 1,   0, 1 }, },
99 	{ "0b3",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 179, 3 },	{ 1,   0, 1 }, },
100 	{ "0b4",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 180, 3 },	{ 1,   0, 1 }, },
101 	{ "0b5",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 181, 3 },	{ 1,   0, 1 }, },
102 	{ "0b6",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 182, 3 },	{ 1,   0, 1 }, },
103 	{ "0b7",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 183, 3 },	{ 1,   0, 1 }, },
104 	{ "0b8",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 184, 3 },	{ 1,   0, 1 }, },
105 	{ "0b9",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 185, 3 },	{ 1,   0, 1 }, },
106 	{ "0bA",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 186, 3 },	{ 1,   0, 1 }, },
107 	{ "0bB",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 187, 3 },	{ 1,   0, 1 }, },
108 	{ "0bC",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 188, 3 },	{ 1,   0, 1 }, },
109 	{ "0bD",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 189, 3 },	{ 1,   0, 1 }, },
110 	{ "0bE",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 190, 3 },	{ 1,   0, 1 }, },
111 	{ "0bF",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 191, 3 },	{ 1,   0, 1 }, },
112 	{ "0bX",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  11, 2 },	{ 1,   0, 1 }, },
113 	{ "0ba",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 186, 3 },	{ 1,   0, 1 }, },
114 	{ "0bb",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 187, 3 },	{ 1,   0, 1 }, },
115 	{ "0bc",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 188, 3 },	{ 1,   0, 1 }, },
116 	{ "0bd",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 189, 3 },	{ 1,   0, 1 }, },
117 	{ "0be",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 190, 3 },	{ 1,   0, 1 }, },
118 	{ "0bf",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1, 191, 3 },	{ 1,   0, 1 }, },
119 	{ "0bx",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  11, 2 },	{ 1,   0, 1 }, },
120 	// all digits with leading hexadecimal prefix
121 	{ "0x0",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 3 },	{ 1,   0, 3 }, },
122 	{ "0x1",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   1, 3 },	{ 1,   1, 3 }, },
123 	{ "0x2",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   2, 3 },	{ 1,   2, 3 }, },
124 	{ "0x3",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   3, 3 },	{ 1,   3, 3 }, },
125 	{ "0x4",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   4, 3 },	{ 1,   4, 3 }, },
126 	{ "0x5",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   5, 3 },	{ 1,   5, 3 }, },
127 	{ "0x6",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   6, 3 },	{ 1,   6, 3 }, },
128 	{ "0x7",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   7, 3 },	{ 1,   7, 3 }, },
129 	{ "0x8",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   8, 3 },	{ 1,   8, 3 }, },
130 	{ "0x9",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   9, 3 },	{ 1,   9, 3 }, },
131 	{ "0xA",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  10, 3 },	{ 1,  10, 3 }, },
132 	{ "0xB",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  11, 3 },	{ 1,  11, 3 }, },
133 	{ "0xC",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  12, 3 },	{ 1,  12, 3 }, },
134 	{ "0xD",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  13, 3 },	{ 1,  13, 3 }, },
135 	{ "0xE",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  14, 3 },	{ 1,  14, 3 }, },
136 	{ "0xF",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  15, 3 },	{ 1,  15, 3 }, },
137 	{ "0xX",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 }, },
138 	{ "0xa",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  10, 3 },	{ 1,  10, 3 }, },
139 	{ "0xb",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  11, 3 },	{ 1,  11, 3 }, },
140 	{ "0xc",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  12, 3 },	{ 1,  12, 3 }, },
141 	{ "0xd",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  13, 3 },	{ 1,  13, 3 }, },
142 	{ "0xe",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  14, 3 },	{ 1,  14, 3 }, },
143 	{ "0xf",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,  15, 3 },	{ 1,  15, 3 }, },
144 	{ "0xX",	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 },	{ 1,   0, 1 }, },
145 	// terminator
146 	{ "" }
147 };
148 
149 #define SSCANF_TEST(string, format, expret, expval, explen)		\
150 	do {								\
151 		int ret = 0, val = 0, len = 0;				\
152 		ret = sscanf(string, format "%n", &val, &len);		\
153 		ATF_CHECK_EQ(expret, ret);				\
154 		if (expret && ret) {					\
155 			ATF_CHECK_EQ(expval, val);			\
156 			ATF_CHECK_EQ(explen, len);			\
157 		}							\
158 	} while (0)
159 
160 ATF_TC_WITHOUT_HEAD(sscanf_b);
161 ATF_TC_BODY(sscanf_b, tc)
162 {
163 	const struct sscanf_test_case *stc;
164 	char input[16];
165 
166 	for (stc = sscanf_test_cases; *stc->input; stc++) {
167 		strcpy(input + 1, stc->input);
168 		SSCANF_TEST(input + 1, "%b", stc->b.ret, stc->b.val, stc->b.len);
169 		input[0] = '+';
170 		SSCANF_TEST(input, "%b", stc->b.ret, stc->b.val, stc->b.len ? stc->b.len + 1 : 0);
171 		input[0] = '-';
172 		SSCANF_TEST(input, "%b", stc->b.ret, -stc->b.val, stc->b.len ? stc->b.len + 1 : 0);
173 	}
174 }
175 
176 ATF_TC_WITHOUT_HEAD(sscanf_o);
177 ATF_TC_BODY(sscanf_o, tc)
178 {
179 	const struct sscanf_test_case *stc;
180 	char input[16];
181 
182 	for (stc = sscanf_test_cases; *stc->input; stc++) {
183 		strcpy(input + 1, stc->input);
184 		SSCANF_TEST(input + 1, "%o", stc->o.ret, stc->o.val, stc->o.len);
185 		input[0] = '+';
186 		SSCANF_TEST(input, "%o", stc->o.ret, stc->o.val, stc->o.len ? stc->o.len + 1 : 0);
187 		input[0] = '-';
188 		SSCANF_TEST(input, "%o", stc->o.ret, -stc->o.val, stc->o.len ? stc->o.len + 1 : 0);
189 	}
190 }
191 
192 ATF_TC_WITHOUT_HEAD(sscanf_d);
193 ATF_TC_BODY(sscanf_d, tc)
194 {
195 	const struct sscanf_test_case *stc;
196 	char input[16];
197 
198 	for (stc = sscanf_test_cases; *stc->input; stc++) {
199 		strcpy(input + 1, stc->input);
200 		SSCANF_TEST(input + 1, "%d", stc->d.ret, stc->d.val, stc->d.len);
201 		input[0] = '+';
202 		SSCANF_TEST(input, "%d", stc->d.ret, stc->d.val, stc->d.len ? stc->d.len + 1 : 0);
203 		input[0] = '-';
204 		SSCANF_TEST(input, "%d", stc->d.ret, -stc->d.val, stc->d.len ? stc->d.len + 1 : 0);
205 	}
206 }
207 
208 ATF_TC_WITHOUT_HEAD(sscanf_x);
209 ATF_TC_BODY(sscanf_x, tc)
210 {
211 	const struct sscanf_test_case *stc;
212 	char input[16];
213 
214 	for (stc = sscanf_test_cases; *stc->input; stc++) {
215 		strcpy(input + 1, stc->input);
216 		SSCANF_TEST(input + 1, "%x", stc->x.ret, stc->x.val, stc->x.len);
217 		input[0] = '+';
218 		SSCANF_TEST(input, "%x", stc->x.ret, stc->x.val, stc->x.len ? stc->x.len + 1 : 0);
219 		input[0] = '-';
220 		SSCANF_TEST(input, "%x", stc->x.ret, -stc->x.val, stc->x.len ? stc->x.len + 1 : 0);
221 	}
222 }
223 
224 ATF_TC_WITHOUT_HEAD(sscanf_i);
225 ATF_TC_BODY(sscanf_i, tc)
226 {
227 	const struct sscanf_test_case *stc;
228 	char input[16];
229 
230 	for (stc = sscanf_test_cases; *stc->input; stc++) {
231 		strcpy(input + 1, stc->input);
232 		SSCANF_TEST(input + 1, "%i", stc->i.ret, stc->i.val, stc->i.len);
233 		input[0] = '+';
234 		SSCANF_TEST(input, "%i", stc->i.ret, stc->i.val, stc->i.len ? stc->i.len + 1 : 0);
235 		input[0] = '-';
236 		SSCANF_TEST(input, "%i", stc->i.ret, -stc->i.val, stc->i.len ? stc->i.len + 1 : 0);
237 	}
238 }
239 
240 /*
241  * Test termination cases: non-numeric character, fixed width, EOF
242  */
243 ATF_TC_WITHOUT_HEAD(sscanf_termination);
244 ATF_TC_BODY(sscanf_termination, tc)
245 {
246 	int a = 0, b = 0, c = 0;
247 	char d = 0;
248 
249 	ATF_CHECK_EQ(4, sscanf("3.1415", "%d%c%2d%d", &a, &d, &b, &c));
250 	ATF_CHECK_EQ(3, a);
251 	ATF_CHECK_EQ(14, b);
252 	ATF_CHECK_EQ(15, c);
253 	ATF_CHECK_EQ('.', d);
254 }
255 
256 ATF_TP_ADD_TCS(tp)
257 {
258 	setlocale(LC_NUMERIC, "en_US.UTF-8");
259 	ATF_TP_ADD_TC(tp, sscanf_b);
260 	ATF_TP_ADD_TC(tp, sscanf_o);
261 	ATF_TP_ADD_TC(tp, sscanf_d);
262 	ATF_TP_ADD_TC(tp, sscanf_x);
263 	ATF_TP_ADD_TC(tp, sscanf_i);
264 	ATF_TP_ADD_TC(tp, sscanf_termination);
265 	return (atf_no_error());
266 }
267