github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/fmt/scan_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package fmt_test 6 7 import ( 8 "bufio" 9 "bytes" 10 "errors" 11 . "fmt" 12 "io" 13 "math" 14 "reflect" 15 "regexp" 16 "strings" 17 "testing" 18 "testing/iotest" 19 "unicode/utf8" 20 ) 21 22 type ScanTest struct { 23 text string 24 in interface{} 25 out interface{} 26 } 27 28 type ScanfTest struct { 29 format string 30 text string 31 in interface{} 32 out interface{} 33 } 34 35 type ScanfMultiTest struct { 36 format string 37 text string 38 in []interface{} 39 out []interface{} 40 err string 41 } 42 43 var ( 44 boolVal bool 45 intVal int 46 int8Val int8 47 int16Val int16 48 int32Val int32 49 int64Val int64 50 uintVal uint 51 uint8Val uint8 52 uint16Val uint16 53 uint32Val uint32 54 uint64Val uint64 55 float32Val float32 56 float64Val float64 57 stringVal string 58 bytesVal []byte 59 runeVal rune 60 complex64Val complex64 61 complex128Val complex128 62 renamedBoolVal renamedBool 63 renamedIntVal renamedInt 64 renamedInt8Val renamedInt8 65 renamedInt16Val renamedInt16 66 renamedInt32Val renamedInt32 67 renamedInt64Val renamedInt64 68 renamedUintVal renamedUint 69 renamedUint8Val renamedUint8 70 renamedUint16Val renamedUint16 71 renamedUint32Val renamedUint32 72 renamedUint64Val renamedUint64 73 renamedUintptrVal renamedUintptr 74 renamedStringVal renamedString 75 renamedBytesVal renamedBytes 76 renamedFloat32Val renamedFloat32 77 renamedFloat64Val renamedFloat64 78 renamedComplex64Val renamedComplex64 79 renamedComplex128Val renamedComplex128 80 ) 81 82 // Xs accepts any non-empty run of the verb character 83 type Xs string 84 85 func (x *Xs) Scan(state ScanState, verb rune) error { 86 tok, err := state.Token(true, func(r rune) bool { return r == verb }) 87 if err != nil { 88 return err 89 } 90 s := string(tok) 91 if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) { 92 return errors.New("syntax error for xs") 93 } 94 *x = Xs(s) 95 return nil 96 } 97 98 var xVal Xs 99 100 // IntString accepts an integer followed immediately by a string. 101 // It tests the embedding of a scan within a scan. 102 type IntString struct { 103 i int 104 s string 105 } 106 107 func (s *IntString) Scan(state ScanState, verb rune) error { 108 if _, err := Fscan(state, &s.i); err != nil { 109 return err 110 } 111 112 tok, err := state.Token(true, nil) 113 if err != nil { 114 return err 115 } 116 s.s = string(tok) 117 return nil 118 } 119 120 var intStringVal IntString 121 122 var scanTests = []ScanTest{ 123 // Basic types 124 {"T\n", &boolVal, true}, // boolean test vals toggle to be sure they are written 125 {"F\n", &boolVal, false}, // restored to zero value 126 {"21\n", &intVal, 21}, 127 {"2_1\n", &intVal, 21}, 128 {"0\n", &intVal, 0}, 129 {"000\n", &intVal, 0}, 130 {"0x10\n", &intVal, 0x10}, 131 {"0x_1_0\n", &intVal, 0x10}, 132 {"-0x10\n", &intVal, -0x10}, 133 {"0377\n", &intVal, 0377}, 134 {"0_3_7_7\n", &intVal, 0377}, 135 {"0o377\n", &intVal, 0377}, 136 {"0o_3_7_7\n", &intVal, 0377}, 137 {"-0377\n", &intVal, -0377}, 138 {"-0o377\n", &intVal, -0377}, 139 {"0\n", &uintVal, uint(0)}, 140 {"000\n", &uintVal, uint(0)}, 141 {"0x10\n", &uintVal, uint(0x10)}, 142 {"0377\n", &uintVal, uint(0377)}, 143 {"22\n", &int8Val, int8(22)}, 144 {"23\n", &int16Val, int16(23)}, 145 {"24\n", &int32Val, int32(24)}, 146 {"25\n", &int64Val, int64(25)}, 147 {"127\n", &int8Val, int8(127)}, 148 {"-21\n", &intVal, -21}, 149 {"-22\n", &int8Val, int8(-22)}, 150 {"-23\n", &int16Val, int16(-23)}, 151 {"-24\n", &int32Val, int32(-24)}, 152 {"-25\n", &int64Val, int64(-25)}, 153 {"-128\n", &int8Val, int8(-128)}, 154 {"+21\n", &intVal, +21}, 155 {"+22\n", &int8Val, int8(+22)}, 156 {"+23\n", &int16Val, int16(+23)}, 157 {"+24\n", &int32Val, int32(+24)}, 158 {"+25\n", &int64Val, int64(+25)}, 159 {"+127\n", &int8Val, int8(+127)}, 160 {"26\n", &uintVal, uint(26)}, 161 {"27\n", &uint8Val, uint8(27)}, 162 {"28\n", &uint16Val, uint16(28)}, 163 {"29\n", &uint32Val, uint32(29)}, 164 {"30\n", &uint64Val, uint64(30)}, 165 {"255\n", &uint8Val, uint8(255)}, 166 {"32767\n", &int16Val, int16(32767)}, 167 {"2.3\n", &float64Val, 2.3}, 168 {"2.3e1\n", &float32Val, float32(2.3e1)}, 169 {"2.3e2\n", &float64Val, 2.3e2}, 170 {"2.3p2\n", &float64Val, 2.3 * 4}, 171 {"2.3p+2\n", &float64Val, 2.3 * 4}, 172 {"2.3p+66\n", &float64Val, 2.3 * (1 << 66)}, 173 {"2.3p-66\n", &float64Val, 2.3 / (1 << 66)}, 174 {"0x2.3p-66\n", &float64Val, float64(0x23) / (1 << 70)}, 175 {"2_3.4_5\n", &float64Val, 23.45}, 176 {"2.35\n", &stringVal, "2.35"}, 177 {"2345678\n", &bytesVal, []byte("2345678")}, 178 {"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i}, 179 {"-3.45e1-3i\n", &complex64Val, complex64(-3.45e1 - 3i)}, 180 {"-.45e1-1e2i\n", &complex128Val, complex128(-.45e1 - 100i)}, 181 {"-.4_5e1-1E2i\n", &complex128Val, complex128(-.45e1 - 100i)}, 182 {"0x1.0p1+0x1.0P2i\n", &complex128Val, complex128(2 + 4i)}, 183 {"-0x1p1-0x1p2i\n", &complex128Val, complex128(-2 - 4i)}, 184 {"-0x1ep-1-0x1p2i\n", &complex128Val, complex128(-15 - 4i)}, 185 {"-0x1_Ep-1-0x1p0_2i\n", &complex128Val, complex128(-15 - 4i)}, 186 {"hello\n", &stringVal, "hello"}, 187 188 // Carriage-return followed by newline. (We treat \r\n as \n always.) 189 {"hello\r\n", &stringVal, "hello"}, 190 {"27\r\n", &uint8Val, uint8(27)}, 191 192 // Renamed types 193 {"true\n", &renamedBoolVal, renamedBool(true)}, 194 {"F\n", &renamedBoolVal, renamedBool(false)}, 195 {"101\n", &renamedIntVal, renamedInt(101)}, 196 {"102\n", &renamedIntVal, renamedInt(102)}, 197 {"103\n", &renamedUintVal, renamedUint(103)}, 198 {"104\n", &renamedUintVal, renamedUint(104)}, 199 {"105\n", &renamedInt8Val, renamedInt8(105)}, 200 {"106\n", &renamedInt16Val, renamedInt16(106)}, 201 {"107\n", &renamedInt32Val, renamedInt32(107)}, 202 {"108\n", &renamedInt64Val, renamedInt64(108)}, 203 {"109\n", &renamedUint8Val, renamedUint8(109)}, 204 {"110\n", &renamedUint16Val, renamedUint16(110)}, 205 {"111\n", &renamedUint32Val, renamedUint32(111)}, 206 {"112\n", &renamedUint64Val, renamedUint64(112)}, 207 {"113\n", &renamedUintptrVal, renamedUintptr(113)}, 208 {"114\n", &renamedStringVal, renamedString("114")}, 209 {"115\n", &renamedBytesVal, renamedBytes([]byte("115"))}, 210 211 // Custom scanners. 212 {" vvv ", &xVal, Xs("vvv")}, 213 {" 1234hello", &intStringVal, IntString{1234, "hello"}}, 214 215 // Fixed bugs 216 {"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow 217 } 218 219 var scanfTests = []ScanfTest{ 220 {"%v", "TRUE\n", &boolVal, true}, 221 {"%t", "false\n", &boolVal, false}, 222 {"%v", "-71\n", &intVal, -71}, 223 {"%v", "-7_1\n", &intVal, -71}, 224 {"%v", "0b111\n", &intVal, 7}, 225 {"%v", "0b_1_1_1\n", &intVal, 7}, 226 {"%v", "0377\n", &intVal, 0377}, 227 {"%v", "0_3_7_7\n", &intVal, 0377}, 228 {"%v", "0o377\n", &intVal, 0377}, 229 {"%v", "0o_3_7_7\n", &intVal, 0377}, 230 {"%v", "0x44\n", &intVal, 0x44}, 231 {"%v", "0x_4_4\n", &intVal, 0x44}, 232 {"%d", "72\n", &intVal, 72}, 233 {"%c", "a\n", &runeVal, 'a'}, 234 {"%c", "\u5072\n", &runeVal, '\u5072'}, 235 {"%c", "\u1234\n", &runeVal, '\u1234'}, 236 {"%d", "73\n", &int8Val, int8(73)}, 237 {"%d", "+74\n", &int16Val, int16(74)}, 238 {"%d", "75\n", &int32Val, int32(75)}, 239 {"%d", "76\n", &int64Val, int64(76)}, 240 {"%b", "1001001\n", &intVal, 73}, 241 {"%o", "075\n", &intVal, 075}, 242 {"%x", "a75\n", &intVal, 0xa75}, 243 {"%v", "71\n", &uintVal, uint(71)}, 244 {"%d", "72\n", &uintVal, uint(72)}, 245 {"%d", "7_2\n", &uintVal, uint(7)}, // only %v takes underscores 246 {"%d", "73\n", &uint8Val, uint8(73)}, 247 {"%d", "74\n", &uint16Val, uint16(74)}, 248 {"%d", "75\n", &uint32Val, uint32(75)}, 249 {"%d", "76\n", &uint64Val, uint64(76)}, 250 {"%b", "1001001\n", &uintVal, uint(73)}, 251 {"%b", "100_1001\n", &uintVal, uint(4)}, 252 {"%o", "075\n", &uintVal, uint(075)}, 253 {"%o", "07_5\n", &uintVal, uint(07)}, // only %v takes underscores 254 {"%x", "a75\n", &uintVal, uint(0xa75)}, 255 {"%x", "A75\n", &uintVal, uint(0xa75)}, 256 {"%x", "A7_5\n", &uintVal, uint(0xa7)}, // only %v takes underscores 257 {"%U", "U+1234\n", &intVal, int(0x1234)}, 258 {"%U", "U+4567\n", &uintVal, uint(0x4567)}, 259 260 {"%e", "2.3\n", &float64Val, 2.3}, 261 {"%E", "2.3e1\n", &float32Val, float32(2.3e1)}, 262 {"%f", "2.3e2\n", &float64Val, 2.3e2}, 263 {"%g", "2.3p2\n", &float64Val, 2.3 * 4}, 264 {"%G", "2.3p+2\n", &float64Val, 2.3 * 4}, 265 {"%v", "2.3p+66\n", &float64Val, 2.3 * (1 << 66)}, 266 {"%f", "2.3p-66\n", &float64Val, 2.3 / (1 << 66)}, 267 {"%G", "0x2.3p-66\n", &float64Val, float64(0x23) / (1 << 70)}, 268 {"%E", "2_3.4_5\n", &float64Val, 23.45}, 269 270 // Strings 271 {"%s", "using-%s\n", &stringVal, "using-%s"}, 272 {"%x", "7573696e672d2578\n", &stringVal, "using-%x"}, 273 {"%X", "7573696E672D2558\n", &stringVal, "using-%X"}, 274 {"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal, "quoted\twith\\doubles"}, 275 {"%q", "`quoted with backs`\n", &stringVal, "quoted with backs"}, 276 277 // Byte slices 278 {"%s", "bytes-%s\n", &bytesVal, []byte("bytes-%s")}, 279 {"%x", "62797465732d2578\n", &bytesVal, []byte("bytes-%x")}, 280 {"%X", "62797465732D2558\n", &bytesVal, []byte("bytes-%X")}, 281 {"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal, []byte("bytes\rwith\vdoubles")}, 282 {"%q", "`bytes with backs`\n", &bytesVal, []byte("bytes with backs")}, 283 284 // Renamed types 285 {"%v\n", "true\n", &renamedBoolVal, renamedBool(true)}, 286 {"%t\n", "F\n", &renamedBoolVal, renamedBool(false)}, 287 {"%v", "101\n", &renamedIntVal, renamedInt(101)}, 288 {"%c", "\u0101\n", &renamedIntVal, renamedInt('\u0101')}, 289 {"%o", "0146\n", &renamedIntVal, renamedInt(102)}, 290 {"%v", "103\n", &renamedUintVal, renamedUint(103)}, 291 {"%d", "104\n", &renamedUintVal, renamedUint(104)}, 292 {"%d", "105\n", &renamedInt8Val, renamedInt8(105)}, 293 {"%d", "106\n", &renamedInt16Val, renamedInt16(106)}, 294 {"%d", "107\n", &renamedInt32Val, renamedInt32(107)}, 295 {"%d", "108\n", &renamedInt64Val, renamedInt64(108)}, 296 {"%x", "6D\n", &renamedUint8Val, renamedUint8(109)}, 297 {"%o", "0156\n", &renamedUint16Val, renamedUint16(110)}, 298 {"%d", "111\n", &renamedUint32Val, renamedUint32(111)}, 299 {"%d", "112\n", &renamedUint64Val, renamedUint64(112)}, 300 {"%d", "113\n", &renamedUintptrVal, renamedUintptr(113)}, 301 {"%s", "114\n", &renamedStringVal, renamedString("114")}, 302 {"%q", "\"1155\"\n", &renamedBytesVal, renamedBytes([]byte("1155"))}, 303 {"%g", "116e1\n", &renamedFloat32Val, renamedFloat32(116e1)}, 304 {"%g", "-11.7e+1", &renamedFloat64Val, renamedFloat64(-11.7e+1)}, 305 {"%g", "11+6e1i\n", &renamedComplex64Val, renamedComplex64(11 + 6e1i)}, 306 {"%g", "-11.+7e+1i", &renamedComplex128Val, renamedComplex128(-11. + 7e+1i)}, 307 308 // Interesting formats 309 {"here is\tthe value:%d", "here is the\tvalue:118\n", &intVal, 118}, 310 {"%% %%:%d", "% %:119\n", &intVal, 119}, 311 {"%d%%", "42%", &intVal, 42}, // %% at end of string. 312 313 // Corner cases 314 {"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)}, 315 316 // Custom scanner. 317 {"%s", " sss ", &xVal, Xs("sss")}, 318 {"%2s", "sssss", &xVal, Xs("ss")}, 319 320 // Fixed bugs 321 {"%d\n", "27\n", &intVal, 27}, // ok 322 {"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline" 323 {"%v", "0", &intVal, 0}, // was: "EOF"; 0 was taken as base prefix and not counted. 324 {"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted. 325 {"%c", " ", &uintVal, uint(' ')}, // %c must accept a blank. 326 {"%c", "\t", &uintVal, uint('\t')}, // %c must accept any space. 327 {"%c", "\n", &uintVal, uint('\n')}, // %c must accept any space. 328 {"%d%%", "23%\n", &uintVal, uint(23)}, // %% matches literal %. 329 {"%%%d", "%23\n", &uintVal, uint(23)}, // %% matches literal %. 330 331 // space handling 332 {"%d", "27", &intVal, 27}, 333 {"%d", "27 ", &intVal, 27}, 334 {"%d", " 27", &intVal, 27}, 335 {"%d", " 27 ", &intVal, 27}, 336 337 {"X%d", "X27", &intVal, 27}, 338 {"X%d", "X27 ", &intVal, 27}, 339 {"X%d", "X 27", &intVal, 27}, 340 {"X%d", "X 27 ", &intVal, 27}, 341 342 {"X %d", "X27", &intVal, nil}, // expected space in input to match format 343 {"X %d", "X27 ", &intVal, nil}, // expected space in input to match format 344 {"X %d", "X 27", &intVal, 27}, 345 {"X %d", "X 27 ", &intVal, 27}, 346 347 {"%dX", "27X", &intVal, 27}, 348 {"%dX", "27 X", &intVal, nil}, // input does not match format 349 {"%dX", " 27X", &intVal, 27}, 350 {"%dX", " 27 X", &intVal, nil}, // input does not match format 351 352 {"%d X", "27X", &intVal, nil}, // expected space in input to match format 353 {"%d X", "27 X", &intVal, 27}, 354 {"%d X", " 27X", &intVal, nil}, // expected space in input to match format 355 {"%d X", " 27 X", &intVal, 27}, 356 357 {"X %d X", "X27X", &intVal, nil}, // expected space in input to match format 358 {"X %d X", "X27 X", &intVal, nil}, // expected space in input to match format 359 {"X %d X", "X 27X", &intVal, nil}, // expected space in input to match format 360 {"X %d X", "X 27 X", &intVal, 27}, 361 362 {"X %s X", "X27X", &stringVal, nil}, // expected space in input to match format 363 {"X %s X", "X27 X", &stringVal, nil}, // expected space in input to match format 364 {"X %s X", "X 27X", &stringVal, nil}, // unexpected EOF 365 {"X %s X", "X 27 X", &stringVal, "27"}, 366 367 {"X%sX", "X27X", &stringVal, nil}, // unexpected EOF 368 {"X%sX", "X27 X", &stringVal, nil}, // input does not match format 369 {"X%sX", "X 27X", &stringVal, nil}, // unexpected EOF 370 {"X%sX", "X 27 X", &stringVal, nil}, // input does not match format 371 372 {"X%s", "X27", &stringVal, "27"}, 373 {"X%s", "X27 ", &stringVal, "27"}, 374 {"X%s", "X 27", &stringVal, "27"}, 375 {"X%s", "X 27 ", &stringVal, "27"}, 376 377 {"X%dX", "X27X", &intVal, 27}, 378 {"X%dX", "X27 X", &intVal, nil}, // input does not match format 379 {"X%dX", "X 27X", &intVal, 27}, 380 {"X%dX", "X 27 X", &intVal, nil}, // input does not match format 381 382 {"X%dX", "X27X", &intVal, 27}, 383 {"X%dX", "X27X ", &intVal, 27}, 384 {"X%dX", " X27X", &intVal, nil}, // input does not match format 385 {"X%dX", " X27X ", &intVal, nil}, // input does not match format 386 387 {"X%dX\n", "X27X", &intVal, 27}, 388 {"X%dX \n", "X27X ", &intVal, 27}, 389 {"X%dX\n", "X27X\n", &intVal, 27}, 390 {"X%dX\n", "X27X \n", &intVal, 27}, 391 392 {"X%dX \n", "X27X", &intVal, 27}, 393 {"X%dX \n", "X27X ", &intVal, 27}, 394 {"X%dX \n", "X27X\n", &intVal, 27}, 395 {"X%dX \n", "X27X \n", &intVal, 27}, 396 397 {"X%c", "X\n", &runeVal, '\n'}, 398 {"X%c", "X \n", &runeVal, ' '}, 399 {"X %c", "X!", &runeVal, nil}, // expected space in input to match format 400 {"X %c", "X\n", &runeVal, nil}, // newline in input does not match format 401 {"X %c", "X !", &runeVal, '!'}, 402 {"X %c", "X \n", &runeVal, '\n'}, 403 404 {" X%dX", "X27X", &intVal, nil}, // expected space in input to match format 405 {" X%dX", "X27X ", &intVal, nil}, // expected space in input to match format 406 {" X%dX", " X27X", &intVal, 27}, 407 {" X%dX", " X27X ", &intVal, 27}, 408 409 {"X%dX ", "X27X", &intVal, 27}, 410 {"X%dX ", "X27X ", &intVal, 27}, 411 {"X%dX ", " X27X", &intVal, nil}, // input does not match format 412 {"X%dX ", " X27X ", &intVal, nil}, // input does not match format 413 414 {" X%dX ", "X27X", &intVal, nil}, // expected space in input to match format 415 {" X%dX ", "X27X ", &intVal, nil}, // expected space in input to match format 416 {" X%dX ", " X27X", &intVal, 27}, 417 {" X%dX ", " X27X ", &intVal, 27}, 418 419 {"%d\nX", "27\nX", &intVal, 27}, 420 {"%dX\n X", "27X\n X", &intVal, 27}, 421 } 422 423 var overflowTests = []ScanTest{ 424 {"128", &int8Val, 0}, 425 {"32768", &int16Val, 0}, 426 {"-129", &int8Val, 0}, 427 {"-32769", &int16Val, 0}, 428 {"256", &uint8Val, 0}, 429 {"65536", &uint16Val, 0}, 430 {"1e100", &float32Val, 0}, 431 {"1e500", &float64Val, 0}, 432 {"(1e100+0i)", &complex64Val, 0}, 433 {"(1+1e100i)", &complex64Val, 0}, 434 {"(1-1e500i)", &complex128Val, 0}, 435 } 436 437 var truth bool 438 var i, j, k int 439 var f float64 440 var s, t string 441 var c complex128 442 var x, y Xs 443 var z IntString 444 var r1, r2, r3 rune 445 446 var multiTests = []ScanfMultiTest{ 447 {"", "", []interface{}{}, []interface{}{}, ""}, 448 {"%d", "23", args(&i), args(23), ""}, 449 {"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""}, 450 {"%2d%3d", "44555", args(&i, &j), args(44, 555), ""}, 451 {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""}, 452 {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""}, 453 {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""}, 454 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""}, 455 {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""}, 456 {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""}, 457 {"%5s%d", " 1234567 ", args(&s, &i), args("12345", 67), ""}, 458 {"%5s%d", " 12 34 567 ", args(&s, &i), args("12", 34), ""}, 459 460 // Custom scanners. 461 {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""}, 462 {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""}, 463 464 // Errors 465 {"%t", "23 18", args(&i), nil, "bad verb"}, 466 {"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"}, 467 {"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"}, 468 {"%c", "\u0100", args(&int8Val), nil, "overflow"}, 469 {"X%d", "10X", args(&intVal), nil, "input does not match format"}, 470 {"%d%", "42%", args(&intVal), args(42), "missing verb: % at end of format string"}, 471 {"%d% ", "42%", args(&intVal), args(42), "too few operands for format '% '"}, // Slightly odd error, but correct. 472 {"%%%d", "xxx 42", args(&intVal), args(42), "missing literal %"}, 473 {"%%%d", "x42", args(&intVal), args(42), "missing literal %"}, 474 {"%%%d", "42", args(&intVal), args(42), "missing literal %"}, 475 476 // Bad UTF-8: should see every byte. 477 {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""}, 478 479 // Fixed bugs 480 {"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""}, 481 } 482 483 var readers = []struct { 484 name string 485 f func(string) io.Reader 486 }{ 487 {"StringReader", func(s string) io.Reader { 488 return strings.NewReader(s) 489 }}, 490 {"ReaderOnly", func(s string) io.Reader { 491 return struct{ io.Reader }{strings.NewReader(s)} 492 }}, 493 {"OneByteReader", func(s string) io.Reader { 494 return iotest.OneByteReader(strings.NewReader(s)) 495 }}, 496 {"DataErrReader", func(s string) io.Reader { 497 return iotest.DataErrReader(strings.NewReader(s)) 498 }}, 499 } 500 501 func testScan(t *testing.T, f func(string) io.Reader, scan func(r io.Reader, a ...interface{}) (int, error)) { 502 for _, test := range scanTests { 503 r := f(test.text) 504 n, err := scan(r, test.in) 505 if err != nil { 506 m := "" 507 if n > 0 { 508 m = Sprintf(" (%d fields ok)", n) 509 } 510 t.Errorf("got error scanning %q: %s%s", test.text, err, m) 511 continue 512 } 513 if n != 1 { 514 t.Errorf("count error on entry %q: got %d", test.text, n) 515 continue 516 } 517 // The incoming value may be a pointer 518 v := reflect.ValueOf(test.in) 519 if p := v; p.Kind() == reflect.Ptr { 520 v = p.Elem() 521 } 522 val := v.Interface() 523 if !reflect.DeepEqual(val, test.out) { 524 t.Errorf("scanning %q: expected %#v got %#v, type %T", test.text, test.out, val, val) 525 } 526 } 527 } 528 529 func TestScan(t *testing.T) { 530 for _, r := range readers { 531 t.Run(r.name, func(t *testing.T) { 532 testScan(t, r.f, Fscan) 533 }) 534 } 535 } 536 537 func TestScanln(t *testing.T) { 538 for _, r := range readers { 539 t.Run(r.name, func(t *testing.T) { 540 testScan(t, r.f, Fscanln) 541 }) 542 } 543 } 544 545 func TestScanf(t *testing.T) { 546 for _, test := range scanfTests { 547 n, err := Sscanf(test.text, test.format, test.in) 548 if err != nil { 549 if test.out != nil { 550 t.Errorf("Sscanf(%q, %q): unexpected error: %v", test.text, test.format, err) 551 } 552 continue 553 } 554 if test.out == nil { 555 t.Errorf("Sscanf(%q, %q): unexpected success", test.text, test.format) 556 continue 557 } 558 if n != 1 { 559 t.Errorf("Sscanf(%q, %q): parsed %d field, want 1", test.text, test.format, n) 560 continue 561 } 562 // The incoming value may be a pointer 563 v := reflect.ValueOf(test.in) 564 if p := v; p.Kind() == reflect.Ptr { 565 v = p.Elem() 566 } 567 val := v.Interface() 568 if !reflect.DeepEqual(val, test.out) { 569 t.Errorf("Sscanf(%q, %q): parsed value %T(%#v), want %T(%#v)", test.text, test.format, val, val, test.out, test.out) 570 } 571 } 572 } 573 574 func TestScanOverflow(t *testing.T) { 575 // different machines and different types report errors with different strings. 576 re := regexp.MustCompile("overflow|too large|out of range|not representable") 577 for _, test := range overflowTests { 578 _, err := Sscan(test.text, test.in) 579 if err == nil { 580 t.Errorf("expected overflow scanning %q", test.text) 581 continue 582 } 583 if !re.MatchString(err.Error()) { 584 t.Errorf("expected overflow error scanning %q: %s", test.text, err) 585 } 586 } 587 } 588 589 func verifyNaN(str string, t *testing.T) { 590 var f float64 591 var f32 float32 592 var f64 float64 593 text := str + " " + str + " " + str 594 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64) 595 if err != nil { 596 t.Errorf("got error scanning %q: %s", text, err) 597 } 598 if n != 3 { 599 t.Errorf("count error scanning %q: got %d", text, n) 600 } 601 if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) { 602 t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64) 603 } 604 } 605 606 func TestNaN(t *testing.T) { 607 for _, s := range []string{"nan", "NAN", "NaN"} { 608 verifyNaN(s, t) 609 } 610 } 611 612 func verifyInf(str string, t *testing.T) { 613 var f float64 614 var f32 float32 615 var f64 float64 616 text := str + " " + str + " " + str 617 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64) 618 if err != nil { 619 t.Errorf("got error scanning %q: %s", text, err) 620 } 621 if n != 3 { 622 t.Errorf("count error scanning %q: got %d", text, n) 623 } 624 sign := 1 625 if str[0] == '-' { 626 sign = -1 627 } 628 if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) { 629 t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64) 630 } 631 } 632 633 func TestInf(t *testing.T) { 634 for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} { 635 verifyInf(s, t) 636 } 637 } 638 639 func testScanfMulti(t *testing.T, f func(string) io.Reader) { 640 sliceType := reflect.TypeOf(make([]interface{}, 1)) 641 for _, test := range multiTests { 642 r := f(test.text) 643 n, err := Fscanf(r, test.format, test.in...) 644 if err != nil { 645 if test.err == "" { 646 t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err) 647 } else if !strings.Contains(err.Error(), test.err) { 648 t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err) 649 } 650 continue 651 } 652 if test.err != "" { 653 t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text) 654 } 655 if n != len(test.out) { 656 t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n) 657 continue 658 } 659 // Convert the slice of pointers into a slice of values 660 resultVal := reflect.MakeSlice(sliceType, n, n) 661 for i := 0; i < n; i++ { 662 v := reflect.ValueOf(test.in[i]).Elem() 663 resultVal.Index(i).Set(v) 664 } 665 result := resultVal.Interface() 666 if !reflect.DeepEqual(result, test.out) { 667 t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result) 668 } 669 } 670 } 671 672 func TestScanfMulti(t *testing.T) { 673 for _, r := range readers { 674 t.Run(r.name, func(t *testing.T) { 675 testScanfMulti(t, r.f) 676 }) 677 } 678 } 679 680 func TestScanMultiple(t *testing.T) { 681 var a int 682 var s string 683 n, err := Sscan("123abc", &a, &s) 684 if n != 2 { 685 t.Errorf("Sscan count error: expected 2: got %d", n) 686 } 687 if err != nil { 688 t.Errorf("Sscan expected no error; got %s", err) 689 } 690 if a != 123 || s != "abc" { 691 t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s) 692 } 693 n, err = Sscan("asdf", &s, &a) 694 if n != 1 { 695 t.Errorf("Sscan count error: expected 1: got %d", n) 696 } 697 if err == nil { 698 t.Errorf("Sscan expected error; got none: %s", err) 699 } 700 if s != "asdf" { 701 t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s) 702 } 703 } 704 705 // Empty strings are not valid input when scanning a string. 706 func TestScanEmpty(t *testing.T) { 707 var s1, s2 string 708 n, err := Sscan("abc", &s1, &s2) 709 if n != 1 { 710 t.Errorf("Sscan count error: expected 1: got %d", n) 711 } 712 if err == nil { 713 t.Error("Sscan <one item> expected error; got none") 714 } 715 if s1 != "abc" { 716 t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1) 717 } 718 n, err = Sscan("", &s1, &s2) 719 if n != 0 { 720 t.Errorf("Sscan count error: expected 0: got %d", n) 721 } 722 if err == nil { 723 t.Error("Sscan <empty> expected error; got none") 724 } 725 // Quoted empty string is OK. 726 n, err = Sscanf(`""`, "%q", &s1) 727 if n != 1 { 728 t.Errorf("Sscanf count error: expected 1: got %d", n) 729 } 730 if err != nil { 731 t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err) 732 } 733 } 734 735 func TestScanNotPointer(t *testing.T) { 736 r := strings.NewReader("1") 737 var a int 738 _, err := Fscan(r, a) 739 if err == nil { 740 t.Error("expected error scanning non-pointer") 741 } else if !strings.Contains(err.Error(), "pointer") { 742 t.Errorf("expected pointer error scanning non-pointer, got: %s", err) 743 } 744 } 745 746 func TestScanlnNoNewline(t *testing.T) { 747 var a int 748 _, err := Sscanln("1 x\n", &a) 749 if err == nil { 750 t.Error("expected error scanning string missing newline") 751 } else if !strings.Contains(err.Error(), "newline") { 752 t.Errorf("expected newline error scanning string missing newline, got: %s", err) 753 } 754 } 755 756 func TestScanlnWithMiddleNewline(t *testing.T) { 757 r := strings.NewReader("123\n456\n") 758 var a, b int 759 _, err := Fscanln(r, &a, &b) 760 if err == nil { 761 t.Error("expected error scanning string with extra newline") 762 } else if !strings.Contains(err.Error(), "newline") { 763 t.Errorf("expected newline error scanning string with extra newline, got: %s", err) 764 } 765 } 766 767 // eofCounter is a special Reader that counts reads at end of file. 768 type eofCounter struct { 769 reader *strings.Reader 770 eofCount int 771 } 772 773 func (ec *eofCounter) Read(b []byte) (n int, err error) { 774 n, err = ec.reader.Read(b) 775 if n == 0 { 776 ec.eofCount++ 777 } 778 return 779 } 780 781 // TestEOF verifies that when we scan, we see at most EOF once per call to a 782 // Scan function, and then only when it's really an EOF. 783 func TestEOF(t *testing.T) { 784 ec := &eofCounter{strings.NewReader("123\n"), 0} 785 var a int 786 n, err := Fscanln(ec, &a) 787 if err != nil { 788 t.Error("unexpected error", err) 789 } 790 if n != 1 { 791 t.Error("expected to scan one item, got", n) 792 } 793 if ec.eofCount != 0 { 794 t.Error("expected zero EOFs", ec.eofCount) 795 ec.eofCount = 0 // reset for next test 796 } 797 n, err = Fscanln(ec, &a) 798 if err == nil { 799 t.Error("expected error scanning empty string") 800 } 801 if n != 0 { 802 t.Error("expected to scan zero items, got", n) 803 } 804 if ec.eofCount != 1 { 805 t.Error("expected one EOF, got", ec.eofCount) 806 } 807 } 808 809 // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input. 810 // This was a buglet: we used to get "expected integer". 811 func TestEOFAtEndOfInput(t *testing.T) { 812 var i, j int 813 n, err := Sscanf("23", "%d %d", &i, &j) 814 if n != 1 || i != 23 { 815 t.Errorf("Sscanf expected one value of 23; got %d %d", n, i) 816 } 817 if err != io.EOF { 818 t.Errorf("Sscanf expected EOF; got %q", err) 819 } 820 n, err = Sscan("234", &i, &j) 821 if n != 1 || i != 234 { 822 t.Errorf("Sscan expected one value of 234; got %d %d", n, i) 823 } 824 if err != io.EOF { 825 t.Errorf("Sscan expected EOF; got %q", err) 826 } 827 // Trailing space is tougher. 828 n, err = Sscan("234 ", &i, &j) 829 if n != 1 || i != 234 { 830 t.Errorf("Sscan expected one value of 234; got %d %d", n, i) 831 } 832 if err != io.EOF { 833 t.Errorf("Sscan expected EOF; got %q", err) 834 } 835 } 836 837 var eofTests = []struct { 838 format string 839 v interface{} 840 }{ 841 {"%s", &stringVal}, 842 {"%q", &stringVal}, 843 {"%x", &stringVal}, 844 {"%v", &stringVal}, 845 {"%v", &bytesVal}, 846 {"%v", &intVal}, 847 {"%v", &uintVal}, 848 {"%v", &boolVal}, 849 {"%v", &float32Val}, 850 {"%v", &complex64Val}, 851 {"%v", &renamedStringVal}, 852 {"%v", &renamedBytesVal}, 853 {"%v", &renamedIntVal}, 854 {"%v", &renamedUintVal}, 855 {"%v", &renamedBoolVal}, 856 {"%v", &renamedFloat32Val}, 857 {"%v", &renamedComplex64Val}, 858 } 859 860 func TestEOFAllTypes(t *testing.T) { 861 for i, test := range eofTests { 862 if _, err := Sscanf("", test.format, test.v); err != io.EOF { 863 t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err) 864 } 865 if _, err := Sscanf(" ", test.format, test.v); err != io.EOF { 866 t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err) 867 } 868 } 869 } 870 871 // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive 872 // calls to Fscan do not lose runes. 873 func TestUnreadRuneWithBufio(t *testing.T) { 874 r := bufio.NewReader(strings.NewReader("123αb")) 875 var i int 876 var a string 877 n, err := Fscanf(r, "%d", &i) 878 if n != 1 || err != nil { 879 t.Errorf("reading int expected one item, no errors; got %d %q", n, err) 880 } 881 if i != 123 { 882 t.Errorf("expected 123; got %d", i) 883 } 884 n, err = Fscanf(r, "%s", &a) 885 if n != 1 || err != nil { 886 t.Errorf("reading string expected one item, no errors; got %d %q", n, err) 887 } 888 if a != "αb" { 889 t.Errorf("expected αb; got %q", a) 890 } 891 } 892 893 type TwoLines string 894 895 // Scan attempts to read two lines into the object. Scanln should prevent this 896 // because it stops at newline; Scan and Scanf should be fine. 897 func (t *TwoLines) Scan(state ScanState, verb rune) error { 898 chars := make([]rune, 0, 100) 899 for nlCount := 0; nlCount < 2; { 900 c, _, err := state.ReadRune() 901 if err != nil { 902 return err 903 } 904 chars = append(chars, c) 905 if c == '\n' { 906 nlCount++ 907 } 908 } 909 *t = TwoLines(string(chars)) 910 return nil 911 } 912 913 func TestMultiLine(t *testing.T) { 914 input := "abc\ndef\n" 915 // Sscan should work 916 var tscan TwoLines 917 n, err := Sscan(input, &tscan) 918 if n != 1 { 919 t.Errorf("Sscan: expected 1 item; got %d", n) 920 } 921 if err != nil { 922 t.Errorf("Sscan: expected no error; got %s", err) 923 } 924 if string(tscan) != input { 925 t.Errorf("Sscan: expected %q; got %q", input, tscan) 926 } 927 // Sscanf should work 928 var tscanf TwoLines 929 n, err = Sscanf(input, "%s", &tscanf) 930 if n != 1 { 931 t.Errorf("Sscanf: expected 1 item; got %d", n) 932 } 933 if err != nil { 934 t.Errorf("Sscanf: expected no error; got %s", err) 935 } 936 if string(tscanf) != input { 937 t.Errorf("Sscanf: expected %q; got %q", input, tscanf) 938 } 939 // Sscanln should not work 940 var tscanln TwoLines 941 n, err = Sscanln(input, &tscanln) 942 if n != 0 { 943 t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln) 944 } 945 if err == nil { 946 t.Error("Sscanln: expected error; got none") 947 } else if err != io.ErrUnexpectedEOF { 948 t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err) 949 } 950 } 951 952 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue 953 // 3481. 954 func TestLineByLineFscanf(t *testing.T) { 955 r := struct{ io.Reader }{strings.NewReader("1\n2\n")} 956 var i, j int 957 n, err := Fscanf(r, "%v\n", &i) 958 if n != 1 || err != nil { 959 t.Fatalf("first read: %d %q", n, err) 960 } 961 n, err = Fscanf(r, "%v\n", &j) 962 if n != 1 || err != nil { 963 t.Fatalf("second read: %d %q", n, err) 964 } 965 if i != 1 || j != 2 { 966 t.Errorf("wrong values; wanted 1 2 got %d %d", i, j) 967 } 968 } 969 970 // TestScanStateCount verifies the correct byte count is returned. Issue 8512. 971 972 // runeScanner implements the Scanner interface for TestScanStateCount. 973 type runeScanner struct { 974 rune rune 975 size int 976 } 977 978 func (rs *runeScanner) Scan(state ScanState, verb rune) error { 979 r, size, err := state.ReadRune() 980 rs.rune = r 981 rs.size = size 982 return err 983 } 984 985 func TestScanStateCount(t *testing.T) { 986 var a, b, c runeScanner 987 n, err := Sscanf("12➂", "%c%c%c", &a, &b, &c) 988 if err != nil { 989 t.Fatal(err) 990 } 991 if n != 3 { 992 t.Fatalf("expected 3 items consumed, got %d", n) 993 } 994 if a.rune != '1' || b.rune != '2' || c.rune != '➂' { 995 t.Errorf("bad scan rune: %q %q %q should be '1' '2' '➂'", a.rune, b.rune, c.rune) 996 } 997 if a.size != 1 || b.size != 1 || c.size != 3 { 998 t.Errorf("bad scan size: %q %q %q should be 1 1 3", a.size, b.size, c.size) 999 } 1000 } 1001 1002 // RecursiveInt accepts a string matching %d.%d.%d.... 1003 // and parses it into a linked list. 1004 // It allows us to benchmark recursive descent style scanners. 1005 type RecursiveInt struct { 1006 i int 1007 next *RecursiveInt 1008 } 1009 1010 func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) { 1011 _, err = Fscan(state, &r.i) 1012 if err != nil { 1013 return 1014 } 1015 next := new(RecursiveInt) 1016 _, err = Fscanf(state, ".%v", next) 1017 if err != nil { 1018 if err == io.ErrUnexpectedEOF { 1019 err = nil 1020 } 1021 return 1022 } 1023 r.next = next 1024 return 1025 } 1026 1027 // scanInts performs the same scanning task as RecursiveInt.Scan 1028 // but without recurring through scanner, so we can compare 1029 // performance more directly. 1030 func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) { 1031 r.next = nil 1032 _, err = Fscan(b, &r.i) 1033 if err != nil { 1034 return 1035 } 1036 c, _, err := b.ReadRune() 1037 if err != nil { 1038 if err == io.EOF { 1039 err = nil 1040 } 1041 return 1042 } 1043 if c != '.' { 1044 return 1045 } 1046 next := new(RecursiveInt) 1047 err = scanInts(next, b) 1048 if err == nil { 1049 r.next = next 1050 } 1051 return 1052 } 1053 1054 func makeInts(n int) []byte { 1055 var buf bytes.Buffer 1056 Fprintf(&buf, "1") 1057 for i := 1; i < n; i++ { 1058 Fprintf(&buf, ".%d", i+1) 1059 } 1060 return buf.Bytes() 1061 } 1062 1063 func TestScanInts(t *testing.T) { 1064 testScanInts(t, scanInts) 1065 testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) { 1066 _, err = Fscan(b, r) 1067 return 1068 }) 1069 } 1070 1071 // 800 is small enough to not overflow the stack when using gccgo on a 1072 // platform that does not support split stack. 1073 const intCount = 800 1074 1075 func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) { 1076 r := new(RecursiveInt) 1077 ints := makeInts(intCount) 1078 buf := bytes.NewBuffer(ints) 1079 err := scan(r, buf) 1080 if err != nil { 1081 t.Error("unexpected error", err) 1082 } 1083 i := 1 1084 for ; r != nil; r = r.next { 1085 if r.i != i { 1086 t.Fatalf("bad scan: expected %d got %d", i, r.i) 1087 } 1088 i++ 1089 } 1090 if i-1 != intCount { 1091 t.Fatalf("bad scan count: expected %d got %d", intCount, i-1) 1092 } 1093 } 1094 1095 func BenchmarkScanInts(b *testing.B) { 1096 b.ResetTimer() 1097 ints := makeInts(intCount) 1098 var r RecursiveInt 1099 for i := b.N - 1; i >= 0; i-- { 1100 buf := bytes.NewBuffer(ints) 1101 b.StartTimer() 1102 scanInts(&r, buf) 1103 b.StopTimer() 1104 } 1105 } 1106 1107 func BenchmarkScanRecursiveInt(b *testing.B) { 1108 b.ResetTimer() 1109 ints := makeInts(intCount) 1110 var r RecursiveInt 1111 for i := b.N - 1; i >= 0; i-- { 1112 buf := bytes.NewBuffer(ints) 1113 b.StartTimer() 1114 Fscan(buf, &r) 1115 b.StopTimer() 1116 } 1117 } 1118 1119 func BenchmarkScanRecursiveIntReaderWrapper(b *testing.B) { 1120 b.ResetTimer() 1121 ints := makeInts(intCount) 1122 var r RecursiveInt 1123 for i := b.N - 1; i >= 0; i-- { 1124 buf := struct{ io.Reader }{strings.NewReader(string(ints))} 1125 b.StartTimer() 1126 Fscan(buf, &r) 1127 b.StopTimer() 1128 } 1129 } 1130 1131 // Issue 9124. 1132 // %x on bytes couldn't handle non-space bytes terminating the scan. 1133 func TestHexBytes(t *testing.T) { 1134 var a, b []byte 1135 n, err := Sscanf("00010203", "%x", &a) 1136 if n != 1 || err != nil { 1137 t.Errorf("simple: got count, err = %d, %v; expected 1, nil", n, err) 1138 } 1139 check := func(msg string, x []byte) { 1140 if len(x) != 4 { 1141 t.Errorf("%s: bad length %d", msg, len(x)) 1142 } 1143 for i, b := range x { 1144 if int(b) != i { 1145 t.Errorf("%s: bad x[%d] = %x", msg, i, x[i]) 1146 } 1147 } 1148 } 1149 check("simple", a) 1150 a = nil 1151 1152 n, err = Sscanf("00010203 00010203", "%x %x", &a, &b) 1153 if n != 2 || err != nil { 1154 t.Errorf("simple pair: got count, err = %d, %v; expected 2, nil", n, err) 1155 } 1156 check("simple pair a", a) 1157 check("simple pair b", b) 1158 a = nil 1159 b = nil 1160 1161 n, err = Sscanf("00010203:", "%x", &a) 1162 if n != 1 || err != nil { 1163 t.Errorf("colon: got count, err = %d, %v; expected 1, nil", n, err) 1164 } 1165 check("colon", a) 1166 a = nil 1167 1168 n, err = Sscanf("00010203:00010203", "%x:%x", &a, &b) 1169 if n != 2 || err != nil { 1170 t.Errorf("colon pair: got count, err = %d, %v; expected 2, nil", n, err) 1171 } 1172 check("colon pair a", a) 1173 check("colon pair b", b) 1174 a = nil 1175 b = nil 1176 1177 // This one fails because there is a hex byte after the data, 1178 // that is, an odd number of hex input bytes. 1179 n, err = Sscanf("000102034:", "%x", &a) 1180 if n != 0 || err == nil { 1181 t.Errorf("odd count: got count, err = %d, %v; expected 0, error", n, err) 1182 } 1183 } 1184 1185 func TestScanNewlinesAreSpaces(t *testing.T) { 1186 var a, b int 1187 var tests = []struct { 1188 name string 1189 text string 1190 count int 1191 }{ 1192 {"newlines", "1\n2\n", 2}, 1193 {"no final newline", "1\n2", 2}, 1194 {"newlines with spaces ", "1 \n 2 \n", 2}, 1195 {"no final newline with spaces", "1 \n 2", 2}, 1196 } 1197 for _, test := range tests { 1198 n, err := Sscan(test.text, &a, &b) 1199 if n != test.count { 1200 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n) 1201 } 1202 if err != nil { 1203 t.Errorf("%s: unexpected error: %s", test.name, err) 1204 } 1205 } 1206 } 1207 1208 func TestScanlnNewlinesTerminate(t *testing.T) { 1209 var a, b int 1210 var tests = []struct { 1211 name string 1212 text string 1213 count int 1214 ok bool 1215 }{ 1216 {"one line one item", "1\n", 1, false}, 1217 {"one line two items with spaces ", " 1 2 \n", 2, true}, 1218 {"one line two items no newline", " 1 2", 2, true}, 1219 {"two lines two items", "1\n2\n", 1, false}, 1220 } 1221 for _, test := range tests { 1222 n, err := Sscanln(test.text, &a, &b) 1223 if n != test.count { 1224 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n) 1225 } 1226 if test.ok && err != nil { 1227 t.Errorf("%s: unexpected error: %s", test.name, err) 1228 } 1229 if !test.ok && err == nil { 1230 t.Errorf("%s: expected error; got none", test.name) 1231 } 1232 } 1233 } 1234 1235 func TestScanfNewlineMatchFormat(t *testing.T) { 1236 var a, b int 1237 var tests = []struct { 1238 name string 1239 text string 1240 format string 1241 count int 1242 ok bool 1243 }{ 1244 {"newline in both", "1\n2", "%d\n%d\n", 2, true}, 1245 {"newline in input", "1\n2", "%d %d", 1, false}, 1246 {"space-newline in input", "1 \n2", "%d %d", 1, false}, 1247 {"newline in format", "1 2", "%d\n%d", 1, false}, 1248 {"space-newline in format", "1 2", "%d \n%d", 1, false}, 1249 {"space-newline in both", "1 \n2", "%d \n%d", 2, true}, 1250 {"extra space in format", "1\n2", "%d\n %d", 2, true}, 1251 {"two extra spaces in format", "1\n2", "%d \n %d", 2, true}, 1252 {"space vs newline 0000", "1\n2", "%d\n%d", 2, true}, 1253 {"space vs newline 0001", "1\n2", "%d\n %d", 2, true}, 1254 {"space vs newline 0010", "1\n2", "%d \n%d", 2, true}, 1255 {"space vs newline 0011", "1\n2", "%d \n %d", 2, true}, 1256 {"space vs newline 0100", "1\n 2", "%d\n%d", 2, true}, 1257 {"space vs newline 0101", "1\n 2", "%d\n%d ", 2, true}, 1258 {"space vs newline 0110", "1\n 2", "%d \n%d", 2, true}, 1259 {"space vs newline 0111", "1\n 2", "%d \n %d", 2, true}, 1260 {"space vs newline 1000", "1 \n2", "%d\n%d", 2, true}, 1261 {"space vs newline 1001", "1 \n2", "%d\n %d", 2, true}, 1262 {"space vs newline 1010", "1 \n2", "%d \n%d", 2, true}, 1263 {"space vs newline 1011", "1 \n2", "%d \n %d", 2, true}, 1264 {"space vs newline 1100", "1 \n 2", "%d\n%d", 2, true}, 1265 {"space vs newline 1101", "1 \n 2", "%d\n %d", 2, true}, 1266 {"space vs newline 1110", "1 \n 2", "%d \n%d", 2, true}, 1267 {"space vs newline 1111", "1 \n 2", "%d \n %d", 2, true}, 1268 {"space vs newline no-percent 0000", "1\n2", "1\n2", 0, true}, 1269 {"space vs newline no-percent 0001", "1\n2", "1\n 2", 0, true}, 1270 {"space vs newline no-percent 0010", "1\n2", "1 \n2", 0, true}, 1271 {"space vs newline no-percent 0011", "1\n2", "1 \n 2", 0, true}, 1272 {"space vs newline no-percent 0100", "1\n 2", "1\n2", 0, false}, // fails: space after nl in input but not pattern 1273 {"space vs newline no-percent 0101", "1\n 2", "1\n2 ", 0, false}, // fails: space after nl in input but not pattern 1274 {"space vs newline no-percent 0110", "1\n 2", "1 \n2", 0, false}, // fails: space after nl in input but not pattern 1275 {"space vs newline no-percent 0111", "1\n 2", "1 \n 2", 0, true}, 1276 {"space vs newline no-percent 1000", "1 \n2", "1\n2", 0, true}, 1277 {"space vs newline no-percent 1001", "1 \n2", "1\n 2", 0, true}, 1278 {"space vs newline no-percent 1010", "1 \n2", "1 \n2", 0, true}, 1279 {"space vs newline no-percent 1011", "1 \n2", "1 \n 2", 0, true}, 1280 {"space vs newline no-percent 1100", "1 \n 2", "1\n2", 0, false}, // fails: space after nl in input but not pattern 1281 {"space vs newline no-percent 1101", "1 \n 2", "1\n 2", 0, true}, 1282 {"space vs newline no-percent 1110", "1 \n 2", "1 \n2", 0, false}, // fails: space after nl in input but not pattern 1283 {"space vs newline no-percent 1111", "1 \n 2", "1 \n 2", 0, true}, 1284 } 1285 for _, test := range tests { 1286 var n int 1287 var err error 1288 if strings.Contains(test.format, "%") { 1289 n, err = Sscanf(test.text, test.format, &a, &b) 1290 } else { 1291 n, err = Sscanf(test.text, test.format) 1292 } 1293 if n != test.count { 1294 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n) 1295 } 1296 if test.ok && err != nil { 1297 t.Errorf("%s: unexpected error: %s", test.name, err) 1298 } 1299 if !test.ok && err == nil { 1300 t.Errorf("%s: expected error; got none", test.name) 1301 } 1302 } 1303 } 1304 1305 // Test for issue 12090: Was unreading at EOF, double-scanning a byte. 1306 1307 type hexBytes [2]byte 1308 1309 func (h *hexBytes) Scan(ss ScanState, verb rune) error { 1310 var b []byte 1311 _, err := Fscanf(ss, "%4x", &b) 1312 if err != nil { 1313 panic(err) // Really shouldn't happen. 1314 } 1315 copy((*h)[:], b) 1316 return err 1317 } 1318 1319 func TestHexByte(t *testing.T) { 1320 var h hexBytes 1321 n, err := Sscanln("0123\n", &h) 1322 if err != nil { 1323 t.Fatal(err) 1324 } 1325 if n != 1 { 1326 t.Fatalf("expected 1 item; scanned %d", n) 1327 } 1328 if h[0] != 0x01 || h[1] != 0x23 { 1329 t.Fatalf("expected 0123 got %x", h) 1330 } 1331 }