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