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