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.
21 type ScanTest struct {
27 type ScanfTest struct {
34 type ScanfMultiTest struct {
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
82 type FloatTest struct {
88 // Xs accepts any non-empty run of the verb character
91 func (x *Xs) Scan(state ScanState, verb rune) error {
92 tok, err := state.Token(true, func(r rune) bool { return r == verb })
97 if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) {
98 return errors.New("syntax error for xs")
106 // IntString accepts an integer followed immediately by a string.
107 // It tests the embedding of a scan within a scan.
108 type IntString struct {
113 func (s *IntString) Scan(state ScanState, verb rune) error {
114 if _, err := Fscan(state, &s.i); err != nil {
118 tok, err := state.Token(true, nil)
126 var intStringVal IntString
128 // myStringReader implements Read but not ReadRune, allowing us to test our readRune wrapper
129 // type that creates something that can read runes given only Read().
130 type myStringReader struct {
134 func (s *myStringReader) Read(p []byte) (n int, err error) {
138 func newReader(s string) *myStringReader {
139 return &myStringReader{strings.NewReader(s)}
142 var scanTests = []ScanTest{
144 {"T\n", &boolVal, true}, // boolean test vals toggle to be sure they are written
145 {"F\n", &boolVal, false}, // restored to zero value
146 {"21\n", &intVal, 21},
148 {"000\n", &intVal, 0},
149 {"0x10\n", &intVal, 0x10},
150 {"-0x10\n", &intVal, -0x10},
151 {"0377\n", &intVal, 0377},
152 {"-0377\n", &intVal, -0377},
153 {"0\n", &uintVal, uint(0)},
154 {"000\n", &uintVal, uint(0)},
155 {"0x10\n", &uintVal, uint(0x10)},
156 {"0377\n", &uintVal, uint(0377)},
157 {"22\n", &int8Val, int8(22)},
158 {"23\n", &int16Val, int16(23)},
159 {"24\n", &int32Val, int32(24)},
160 {"25\n", &int64Val, int64(25)},
161 {"127\n", &int8Val, int8(127)},
162 {"-21\n", &intVal, -21},
163 {"-22\n", &int8Val, int8(-22)},
164 {"-23\n", &int16Val, int16(-23)},
165 {"-24\n", &int32Val, int32(-24)},
166 {"-25\n", &int64Val, int64(-25)},
167 {"-128\n", &int8Val, int8(-128)},
168 {"+21\n", &intVal, +21},
169 {"+22\n", &int8Val, int8(+22)},
170 {"+23\n", &int16Val, int16(+23)},
171 {"+24\n", &int32Val, int32(+24)},
172 {"+25\n", &int64Val, int64(+25)},
173 {"+127\n", &int8Val, int8(+127)},
174 {"26\n", &uintVal, uint(26)},
175 {"27\n", &uint8Val, uint8(27)},
176 {"28\n", &uint16Val, uint16(28)},
177 {"29\n", &uint32Val, uint32(29)},
178 {"30\n", &uint64Val, uint64(30)},
179 {"255\n", &uint8Val, uint8(255)},
180 {"32767\n", &int16Val, int16(32767)},
181 {"2.3\n", &float64Val, 2.3},
182 {"2.3e1\n", &float32Val, float32(2.3e1)},
183 {"2.3e2\n", &float64Val, 2.3e2},
184 {"2.3p2\n", &float64Val, 2.3 * 4},
185 {"2.3p+2\n", &float64Val, 2.3 * 4},
186 {"2.3p+66\n", &float64Val, 2.3 * (1 << 32) * (1 << 32) * 4},
187 {"2.3p-66\n", &float64Val, 2.3 / ((1 << 32) * (1 << 32) * 4)},
188 {"2.35\n", &stringVal, "2.35"},
189 {"2345678\n", &bytesVal, []byte("2345678")},
190 {"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i},
191 {"-3.45e1-3i\n", &complex64Val, complex64(-3.45e1 - 3i)},
192 {"-.45e1-1e2i\n", &complex128Val, complex128(-.45e1 - 100i)},
193 {"hello\n", &stringVal, "hello"},
196 {"true\n", &renamedBoolVal, renamedBool(true)},
197 {"F\n", &renamedBoolVal, renamedBool(false)},
198 {"101\n", &renamedIntVal, renamedInt(101)},
199 {"102\n", &renamedIntVal, renamedInt(102)},
200 {"103\n", &renamedUintVal, renamedUint(103)},
201 {"104\n", &renamedUintVal, renamedUint(104)},
202 {"105\n", &renamedInt8Val, renamedInt8(105)},
203 {"106\n", &renamedInt16Val, renamedInt16(106)},
204 {"107\n", &renamedInt32Val, renamedInt32(107)},
205 {"108\n", &renamedInt64Val, renamedInt64(108)},
206 {"109\n", &renamedUint8Val, renamedUint8(109)},
207 {"110\n", &renamedUint16Val, renamedUint16(110)},
208 {"111\n", &renamedUint32Val, renamedUint32(111)},
209 {"112\n", &renamedUint64Val, renamedUint64(112)},
210 {"113\n", &renamedUintptrVal, renamedUintptr(113)},
211 {"114\n", &renamedStringVal, renamedString("114")},
212 {"115\n", &renamedBytesVal, renamedBytes([]byte("115"))},
215 {" vvv ", &xVal, Xs("vvv")},
216 {" 1234hello", &intStringVal, IntString{1234, "hello"}},
219 {"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow
222 var scanfTests = []ScanfTest{
223 {"%v", "TRUE\n", &boolVal, true},
224 {"%t", "false\n", &boolVal, false},
225 {"%v", "-71\n", &intVal, -71},
226 {"%v", "0377\n", &intVal, 0377},
227 {"%v", "0x44\n", &intVal, 0x44},
228 {"%d", "72\n", &intVal, 72},
229 {"%c", "a\n", &runeVal, 'a'},
230 {"%c", "\u5072\n", &runeVal, '\u5072'},
231 {"%c", "\u1234\n", &runeVal, '\u1234'},
232 {"%d", "73\n", &int8Val, int8(73)},
233 {"%d", "+74\n", &int16Val, int16(74)},
234 {"%d", "75\n", &int32Val, int32(75)},
235 {"%d", "76\n", &int64Val, int64(76)},
236 {"%b", "1001001\n", &intVal, 73},
237 {"%o", "075\n", &intVal, 075},
238 {"%x", "a75\n", &intVal, 0xa75},
239 {"%v", "71\n", &uintVal, uint(71)},
240 {"%d", "72\n", &uintVal, uint(72)},
241 {"%d", "73\n", &uint8Val, uint8(73)},
242 {"%d", "74\n", &uint16Val, uint16(74)},
243 {"%d", "75\n", &uint32Val, uint32(75)},
244 {"%d", "76\n", &uint64Val, uint64(76)},
245 {"%b", "1001001\n", &uintVal, uint(73)},
246 {"%o", "075\n", &uintVal, uint(075)},
247 {"%x", "a75\n", &uintVal, uint(0xa75)},
248 {"%x", "A75\n", &uintVal, uint(0xa75)},
249 {"%U", "U+1234\n", &intVal, int(0x1234)},
250 {"%U", "U+4567\n", &uintVal, uint(0x4567)},
253 {"%s", "using-%s\n", &stringVal, "using-%s"},
254 {"%x", "7573696e672d2578\n", &stringVal, "using-%x"},
255 {"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal, "quoted\twith\\doubles"},
256 {"%q", "`quoted with backs`\n", &stringVal, "quoted with backs"},
259 {"%s", "bytes-%s\n", &bytesVal, []byte("bytes-%s")},
260 {"%x", "62797465732d2578\n", &bytesVal, []byte("bytes-%x")},
261 {"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal, []byte("bytes\rwith\vdoubles")},
262 {"%q", "`bytes with backs`\n", &bytesVal, []byte("bytes with backs")},
265 {"%v\n", "true\n", &renamedBoolVal, renamedBool(true)},
266 {"%t\n", "F\n", &renamedBoolVal, renamedBool(false)},
267 {"%v", "101\n", &renamedIntVal, renamedInt(101)},
268 {"%c", "\u0101\n", &renamedIntVal, renamedInt('\u0101')},
269 {"%o", "0146\n", &renamedIntVal, renamedInt(102)},
270 {"%v", "103\n", &renamedUintVal, renamedUint(103)},
271 {"%d", "104\n", &renamedUintVal, renamedUint(104)},
272 {"%d", "105\n", &renamedInt8Val, renamedInt8(105)},
273 {"%d", "106\n", &renamedInt16Val, renamedInt16(106)},
274 {"%d", "107\n", &renamedInt32Val, renamedInt32(107)},
275 {"%d", "108\n", &renamedInt64Val, renamedInt64(108)},
276 {"%x", "6D\n", &renamedUint8Val, renamedUint8(109)},
277 {"%o", "0156\n", &renamedUint16Val, renamedUint16(110)},
278 {"%d", "111\n", &renamedUint32Val, renamedUint32(111)},
279 {"%d", "112\n", &renamedUint64Val, renamedUint64(112)},
280 {"%d", "113\n", &renamedUintptrVal, renamedUintptr(113)},
281 {"%s", "114\n", &renamedStringVal, renamedString("114")},
282 {"%q", "\"1155\"\n", &renamedBytesVal, renamedBytes([]byte("1155"))},
283 {"%g", "116e1\n", &renamedFloat32Val, renamedFloat32(116e1)},
284 {"%g", "-11.7e+1", &renamedFloat64Val, renamedFloat64(-11.7e+1)},
285 {"%g", "11+6e1i\n", &renamedComplex64Val, renamedComplex64(11 + 6e1i)},
286 {"%g", "-11.+7e+1i", &renamedComplex128Val, renamedComplex128(-11. + 7e+1i)},
288 // Interesting formats
289 {"here is\tthe value:%d", "here is the\tvalue:118\n", &intVal, 118},
290 {"%% %%:%d", "% %:119\n", &intVal, 119},
293 {"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)},
296 {"%s", " sss ", &xVal, Xs("sss")},
297 {"%2s", "sssss", &xVal, Xs("ss")},
300 {"%d\n", "27\n", &intVal, 27}, // ok
301 {"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
302 {"%v", "0", &intVal, 0}, // was: "EOF"; 0 was taken as base prefix and not counted.
303 {"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
306 var overflowTests = []ScanTest{
307 {"128", &int8Val, 0},
308 {"32768", &int16Val, 0},
309 {"-129", &int8Val, 0},
310 {"-32769", &int16Val, 0},
311 {"256", &uint8Val, 0},
312 {"65536", &uint16Val, 0},
313 {"1e100", &float32Val, 0},
314 {"1e500", &float64Val, 0},
315 {"(1e100+0i)", &complex64Val, 0},
316 {"(1+1e100i)", &complex64Val, 0},
317 {"(1-1e500i)", &complex128Val, 0},
329 var multiTests = []ScanfMultiTest{
330 {"", "", []interface{}{}, []interface{}{}, ""},
331 {"%d", "23", args(&i), args(23), ""},
332 {"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""},
333 {"%2d%3d", "44555", args(&i, &j), args(44, 555), ""},
334 {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""},
335 {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""},
336 {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
337 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
338 {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
339 {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
342 {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
343 {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""},
346 {"%t", "23 18", args(&i), nil, "bad verb"},
347 {"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"},
348 {"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"},
349 {"%c", "\u0100", args(&int8Val), nil, "overflow"},
350 {"X%d", "10X", args(&intVal), nil, "input does not match format"},
352 // Bad UTF-8: should see every byte.
353 {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
356 {"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""},
359 func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {
360 for _, test := range scanTests {
362 if name == "StringReader" {
363 r = strings.NewReader(test.text)
365 r = newReader(test.text)
367 n, err := scan(r, test.in)
371 m = Sprintf(" (%d fields ok)", n)
373 t.Errorf("%s got error scanning %q: %s%s", name, test.text, err, m)
377 t.Errorf("%s count error on entry %q: got %d", name, test.text, n)
380 // The incoming value may be a pointer
381 v := reflect.ValueOf(test.in)
382 if p := v; p.Kind() == reflect.Ptr {
386 if !reflect.DeepEqual(val, test.out) {
387 t.Errorf("%s scanning %q: expected %#v got %#v, type %T", name, test.text, test.out, val, val)
392 func TestScan(t *testing.T) {
393 testScan("StringReader", t, Fscan)
396 func TestMyReaderScan(t *testing.T) {
397 testScan("myStringReader", t, Fscan)
400 func TestScanln(t *testing.T) {
401 testScan("StringReader", t, Fscanln)
404 func TestMyReaderScanln(t *testing.T) {
405 testScan("myStringReader", t, Fscanln)
408 func TestScanf(t *testing.T) {
409 for _, test := range scanfTests {
410 n, err := Sscanf(test.text, test.format, test.in)
412 t.Errorf("got error scanning (%q, %q): %s", test.format, test.text, err)
416 t.Errorf("count error on entry (%q, %q): got %d", test.format, test.text, n)
419 // The incoming value may be a pointer
420 v := reflect.ValueOf(test.in)
421 if p := v; p.Kind() == reflect.Ptr {
425 if !reflect.DeepEqual(val, test.out) {
426 t.Errorf("scanning (%q, %q): expected %#v got %#v, type %T", test.format, test.text, test.out, val, val)
431 func TestScanOverflow(t *testing.T) {
432 // different machines and different types report errors with different strings.
433 re := regexp.MustCompile("overflow|too large|out of range|not representable")
434 for _, test := range overflowTests {
435 _, err := Sscan(test.text, test.in)
437 t.Errorf("expected overflow scanning %q", test.text)
440 if !re.MatchString(err.Error()) {
441 t.Errorf("expected overflow error scanning %q: %s", test.text, err)
446 func verifyNaN(str string, t *testing.T) {
450 text := str + " " + str + " " + str
451 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
453 t.Errorf("got error scanning %q: %s", text, err)
456 t.Errorf("count error scanning %q: got %d", text, n)
458 if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) {
459 t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64)
463 func TestNaN(t *testing.T) {
464 for _, s := range []string{"nan", "NAN", "NaN"} {
469 func verifyInf(str string, t *testing.T) {
473 text := str + " " + str + " " + str
474 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
476 t.Errorf("got error scanning %q: %s", text, err)
479 t.Errorf("count error scanning %q: got %d", text, n)
485 if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) {
486 t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64)
490 func TestInf(t *testing.T) {
491 for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
496 func testScanfMulti(name string, t *testing.T) {
497 sliceType := reflect.TypeOf(make([]interface{}, 1))
498 for _, test := range multiTests {
500 if name == "StringReader" {
501 r = strings.NewReader(test.text)
503 r = newReader(test.text)
505 n, err := Fscanf(r, test.format, test.in...)
508 t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err)
509 } else if strings.Index(err.Error(), test.err) < 0 {
510 t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
515 t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text)
517 if n != len(test.out) {
518 t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n)
521 // Convert the slice of pointers into a slice of values
522 resultVal := reflect.MakeSlice(sliceType, n, n)
523 for i := 0; i < n; i++ {
524 v := reflect.ValueOf(test.in[i]).Elem()
525 resultVal.Index(i).Set(v)
527 result := resultVal.Interface()
528 if !reflect.DeepEqual(result, test.out) {
529 t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result)
534 func TestScanfMulti(t *testing.T) {
535 testScanfMulti("StringReader", t)
538 func TestMyReaderScanfMulti(t *testing.T) {
539 testScanfMulti("myStringReader", t)
542 func TestScanMultiple(t *testing.T) {
545 n, err := Sscan("123abc", &a, &s)
547 t.Errorf("Sscan count error: expected 2: got %d", n)
550 t.Errorf("Sscan expected no error; got %s", err)
552 if a != 123 || s != "abc" {
553 t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s)
555 n, err = Sscan("asdf", &s, &a)
557 t.Errorf("Sscan count error: expected 1: got %d", n)
560 t.Errorf("Sscan expected error; got none: %s", err)
563 t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s)
567 // Empty strings are not valid input when scanning a string.
568 func TestScanEmpty(t *testing.T) {
570 n, err := Sscan("abc", &s1, &s2)
572 t.Errorf("Sscan count error: expected 1: got %d", n)
575 t.Error("Sscan <one item> expected error; got none")
578 t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1)
580 n, err = Sscan("", &s1, &s2)
582 t.Errorf("Sscan count error: expected 0: got %d", n)
585 t.Error("Sscan <empty> expected error; got none")
587 // Quoted empty string is OK.
588 n, err = Sscanf(`""`, "%q", &s1)
590 t.Errorf("Sscanf count error: expected 1: got %d", n)
593 t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err)
597 func TestScanNotPointer(t *testing.T) {
598 r := strings.NewReader("1")
600 _, err := Fscan(r, a)
602 t.Error("expected error scanning non-pointer")
603 } else if strings.Index(err.Error(), "pointer") < 0 {
604 t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
608 func TestScanlnNoNewline(t *testing.T) {
610 _, err := Sscanln("1 x\n", &a)
612 t.Error("expected error scanning string missing newline")
613 } else if strings.Index(err.Error(), "newline") < 0 {
614 t.Errorf("expected newline error scanning string missing newline, got: %s", err)
618 func TestScanlnWithMiddleNewline(t *testing.T) {
619 r := strings.NewReader("123\n456\n")
621 _, err := Fscanln(r, &a, &b)
623 t.Error("expected error scanning string with extra newline")
624 } else if strings.Index(err.Error(), "newline") < 0 {
625 t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
629 // eofCounter is a special Reader that counts reads at end of file.
630 type eofCounter struct {
631 reader *strings.Reader
635 func (ec *eofCounter) Read(b []byte) (n int, err error) {
636 n, err = ec.reader.Read(b)
643 // TestEOF verifies that when we scan, we see at most EOF once per call to a
644 // Scan function, and then only when it's really an EOF.
645 func TestEOF(t *testing.T) {
646 ec := &eofCounter{strings.NewReader("123\n"), 0}
648 n, err := Fscanln(ec, &a)
650 t.Error("unexpected error", err)
653 t.Error("expected to scan one item, got", n)
655 if ec.eofCount != 0 {
656 t.Error("expected zero EOFs", ec.eofCount)
657 ec.eofCount = 0 // reset for next test
659 n, err = Fscanln(ec, &a)
661 t.Error("expected error scanning empty string")
664 t.Error("expected to scan zero items, got", n)
666 if ec.eofCount != 1 {
667 t.Error("expected one EOF, got", ec.eofCount)
671 // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
672 // This was a buglet: we used to get "expected integer".
673 func TestEOFAtEndOfInput(t *testing.T) {
675 n, err := Sscanf("23", "%d %d", &i, &j)
676 if n != 1 || i != 23 {
677 t.Errorf("Sscanf expected one value of 23; got %d %d", n, i)
680 t.Errorf("Sscanf expected EOF; got %q", err)
682 n, err = Sscan("234", &i, &j)
683 if n != 1 || i != 234 {
684 t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
687 t.Errorf("Sscan expected EOF; got %q", err)
689 // Trailing space is tougher.
690 n, err = Sscan("234 ", &i, &j)
691 if n != 1 || i != 234 {
692 t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
695 t.Errorf("Sscan expected EOF; got %q", err)
699 var eofTests = []struct {
712 {"%v", &complex64Val},
713 {"%v", &renamedStringVal},
714 {"%v", &renamedBytesVal},
715 {"%v", &renamedIntVal},
716 {"%v", &renamedUintVal},
717 {"%v", &renamedBoolVal},
718 {"%v", &renamedFloat32Val},
719 {"%v", &renamedComplex64Val},
722 func TestEOFAllTypes(t *testing.T) {
723 for i, test := range eofTests {
724 if _, err := Sscanf("", test.format, test.v); err != io.EOF {
725 t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err)
727 if _, err := Sscanf(" ", test.format, test.v); err != io.EOF {
728 t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err)
733 // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
734 // calls to Fscan do not lose runes.
735 func TestUnreadRuneWithBufio(t *testing.T) {
736 r := bufio.NewReader(strings.NewReader("123αb"))
739 n, err := Fscanf(r, "%d", &i)
740 if n != 1 || err != nil {
741 t.Errorf("reading int expected one item, no errors; got %d %q", n, err)
744 t.Errorf("expected 123; got %d", i)
746 n, err = Fscanf(r, "%s", &a)
747 if n != 1 || err != nil {
748 t.Errorf("reading string expected one item, no errors; got %d %q", n, err)
751 t.Errorf("expected αb; got %q", a)
757 // Scan attempts to read two lines into the object. Scanln should prevent this
758 // because it stops at newline; Scan and Scanf should be fine.
759 func (t *TwoLines) Scan(state ScanState, verb rune) error {
760 chars := make([]rune, 0, 100)
761 for nlCount := 0; nlCount < 2; {
762 c, _, err := state.ReadRune()
766 chars = append(chars, c)
771 *t = TwoLines(string(chars))
775 func TestMultiLine(t *testing.T) {
776 input := "abc\ndef\n"
779 n, err := Sscan(input, &tscan)
781 t.Errorf("Sscan: expected 1 item; got %d", n)
784 t.Errorf("Sscan: expected no error; got %s", err)
786 if string(tscan) != input {
787 t.Errorf("Sscan: expected %q; got %q", input, tscan)
789 // Sscanf should work
791 n, err = Sscanf(input, "%s", &tscanf)
793 t.Errorf("Sscanf: expected 1 item; got %d", n)
796 t.Errorf("Sscanf: expected no error; got %s", err)
798 if string(tscanf) != input {
799 t.Errorf("Sscanf: expected %q; got %q", input, tscanf)
801 // Sscanln should not work
803 n, err = Sscanln(input, &tscanln)
805 t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln)
808 t.Error("Sscanln: expected error; got none")
809 } else if err != io.ErrUnexpectedEOF {
810 t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err)
814 // simpleReader is a strings.Reader that implements only Read, not ReadRune.
815 // Good for testing readahead.
816 type simpleReader struct {
820 func (s *simpleReader) Read(b []byte) (n int, err error) {
824 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
826 func TestLineByLineFscanf(t *testing.T) {
827 r := &simpleReader{strings.NewReader("1\n2\n")}
829 n, err := Fscanf(r, "%v\n", &i)
830 if n != 1 || err != nil {
831 t.Fatalf("first read: %d %q", n, err)
833 n, err = Fscanf(r, "%v\n", &j)
834 if n != 1 || err != nil {
835 t.Fatalf("second read: %d %q", n, err)
837 if i != 1 || j != 2 {
838 t.Errorf("wrong values; wanted 1 2 got %d %d", i, j)
842 // RecursiveInt accepts a string matching %d.%d.%d....
843 // and parses it into a linked list.
844 // It allows us to benchmark recursive descent style scanners.
845 type RecursiveInt struct {
850 func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
851 _, err = Fscan(state, &r.i)
855 next := new(RecursiveInt)
856 _, err = Fscanf(state, ".%v", next)
858 if err == io.ErrUnexpectedEOF {
867 // scanInts performs the same scanning task as RecursiveInt.Scan
868 // but without recurring through scanner, so we can compare
869 // performance more directly.
870 func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) {
872 _, err = Fscan(b, &r.i)
876 c, _, err := b.ReadRune()
886 next := new(RecursiveInt)
887 err = scanInts(next, b)
894 func makeInts(n int) []byte {
897 for i := 1; i < n; i++ {
898 Fprintf(&buf, ".%d", i+1)
903 func TestScanInts(t *testing.T) {
904 testScanInts(t, scanInts)
905 testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) {
911 // 800 is small enough to not overflow the stack when using gccgo on a
912 // platform that does not support split stack.
915 func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) {
916 r := new(RecursiveInt)
917 ints := makeInts(intCount)
918 buf := bytes.NewBuffer(ints)
921 t.Error("unexpected error", err)
924 for ; r != nil; r = r.next {
926 t.Fatalf("bad scan: expected %d got %d", i, r.i)
931 t.Fatalf("bad scan count: expected %d got %d", intCount, i-1)
935 func BenchmarkScanInts(b *testing.B) {
937 ints := makeInts(intCount)
939 for i := b.N - 1; i >= 0; i-- {
940 buf := bytes.NewBuffer(ints)
947 func BenchmarkScanRecursiveInt(b *testing.B) {
949 ints := makeInts(intCount)
951 for i := b.N - 1; i >= 0; i-- {
952 buf := bytes.NewBuffer(ints)