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},
328 var multiTests = []ScanfMultiTest{
329 {"", "", []interface{}{}, []interface{}{}, ""},
330 {"%d", "23", args(&i), args(23), ""},
331 {"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""},
332 {"%2d%3d", "44555", args(&i, &j), args(44, 555), ""},
333 {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""},
334 {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""},
335 {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
336 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
337 {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
338 {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
341 {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
342 {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""},
345 {"%t", "23 18", args(&i), nil, "bad verb"},
346 {"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"},
347 {"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"},
348 {"%c", "\u0100", args(&int8Val), nil, "overflow"},
349 {"X%d", "10X", args(&intVal), nil, "input does not match format"},
351 // Bad UTF-8: should see every byte.
352 {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
355 func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {
356 for _, test := range scanTests {
358 if name == "StringReader" {
359 r = strings.NewReader(test.text)
361 r = newReader(test.text)
363 n, err := scan(r, test.in)
367 m = Sprintf(" (%d fields ok)", n)
369 t.Errorf("%s got error scanning %q: %s%s", name, test.text, err, m)
373 t.Errorf("%s count error on entry %q: got %d", name, test.text, n)
376 // The incoming value may be a pointer
377 v := reflect.ValueOf(test.in)
378 if p := v; p.Kind() == reflect.Ptr {
382 if !reflect.DeepEqual(val, test.out) {
383 t.Errorf("%s scanning %q: expected %#v got %#v, type %T", name, test.text, test.out, val, val)
388 func TestScan(t *testing.T) {
389 testScan("StringReader", t, Fscan)
392 func TestMyReaderScan(t *testing.T) {
393 testScan("myStringReader", t, Fscan)
396 func TestScanln(t *testing.T) {
397 testScan("StringReader", t, Fscanln)
400 func TestMyReaderScanln(t *testing.T) {
401 testScan("myStringReader", t, Fscanln)
404 func TestScanf(t *testing.T) {
405 for _, test := range scanfTests {
406 n, err := Sscanf(test.text, test.format, test.in)
408 t.Errorf("got error scanning (%q, %q): %s", test.format, test.text, err)
412 t.Errorf("count error on entry (%q, %q): got %d", test.format, test.text, n)
415 // The incoming value may be a pointer
416 v := reflect.ValueOf(test.in)
417 if p := v; p.Kind() == reflect.Ptr {
421 if !reflect.DeepEqual(val, test.out) {
422 t.Errorf("scanning (%q, %q): expected %#v got %#v, type %T", test.format, test.text, test.out, val, val)
427 func TestScanOverflow(t *testing.T) {
428 // different machines and different types report errors with different strings.
429 re := regexp.MustCompile("overflow|too large|out of range|not representable")
430 for _, test := range overflowTests {
431 _, err := Sscan(test.text, test.in)
433 t.Errorf("expected overflow scanning %q", test.text)
436 if !re.MatchString(err.Error()) {
437 t.Errorf("expected overflow error scanning %q: %s", test.text, err)
442 func verifyNaN(str string, t *testing.T) {
446 text := str + " " + str + " " + str
447 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
449 t.Errorf("got error scanning %q: %s", text, err)
452 t.Errorf("count error scanning %q: got %d", text, n)
454 if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) {
455 t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64)
459 func TestNaN(t *testing.T) {
460 for _, s := range []string{"nan", "NAN", "NaN"} {
465 func verifyInf(str string, t *testing.T) {
469 text := str + " " + str + " " + str
470 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
472 t.Errorf("got error scanning %q: %s", text, err)
475 t.Errorf("count error scanning %q: got %d", text, n)
481 if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) {
482 t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64)
486 func TestInf(t *testing.T) {
487 for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
492 func testScanfMulti(name string, t *testing.T) {
493 sliceType := reflect.TypeOf(make([]interface{}, 1))
494 for _, test := range multiTests {
496 if name == "StringReader" {
497 r = strings.NewReader(test.text)
499 r = newReader(test.text)
501 n, err := Fscanf(r, test.format, test.in...)
504 t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err)
505 } else if strings.Index(err.Error(), test.err) < 0 {
506 t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
511 t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text)
513 if n != len(test.out) {
514 t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n)
517 // Convert the slice of pointers into a slice of values
518 resultVal := reflect.MakeSlice(sliceType, n, n)
519 for i := 0; i < n; i++ {
520 v := reflect.ValueOf(test.in[i]).Elem()
521 resultVal.Index(i).Set(v)
523 result := resultVal.Interface()
524 if !reflect.DeepEqual(result, test.out) {
525 t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result)
530 func TestScanfMulti(t *testing.T) {
531 testScanfMulti("StringReader", t)
534 func TestMyReaderScanfMulti(t *testing.T) {
535 testScanfMulti("myStringReader", t)
538 func TestScanMultiple(t *testing.T) {
541 n, err := Sscan("123abc", &a, &s)
543 t.Errorf("Sscan count error: expected 2: got %d", n)
546 t.Errorf("Sscan expected no error; got %s", err)
548 if a != 123 || s != "abc" {
549 t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s)
551 n, err = Sscan("asdf", &s, &a)
553 t.Errorf("Sscan count error: expected 1: got %d", n)
556 t.Errorf("Sscan expected error; got none: %s", err)
559 t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s)
563 // Empty strings are not valid input when scanning a string.
564 func TestScanEmpty(t *testing.T) {
566 n, err := Sscan("abc", &s1, &s2)
568 t.Errorf("Sscan count error: expected 1: got %d", n)
571 t.Error("Sscan <one item> expected error; got none")
574 t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1)
576 n, err = Sscan("", &s1, &s2)
578 t.Errorf("Sscan count error: expected 0: got %d", n)
581 t.Error("Sscan <empty> expected error; got none")
583 // Quoted empty string is OK.
584 n, err = Sscanf(`""`, "%q", &s1)
586 t.Errorf("Sscanf count error: expected 1: got %d", n)
589 t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err)
593 func TestScanNotPointer(t *testing.T) {
594 r := strings.NewReader("1")
596 _, err := Fscan(r, a)
598 t.Error("expected error scanning non-pointer")
599 } else if strings.Index(err.Error(), "pointer") < 0 {
600 t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
604 func TestScanlnNoNewline(t *testing.T) {
606 _, err := Sscanln("1 x\n", &a)
608 t.Error("expected error scanning string missing newline")
609 } else if strings.Index(err.Error(), "newline") < 0 {
610 t.Errorf("expected newline error scanning string missing newline, got: %s", err)
614 func TestScanlnWithMiddleNewline(t *testing.T) {
615 r := strings.NewReader("123\n456\n")
617 _, err := Fscanln(r, &a, &b)
619 t.Error("expected error scanning string with extra newline")
620 } else if strings.Index(err.Error(), "newline") < 0 {
621 t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
625 // Special Reader that counts reads at end of file.
626 type eofCounter struct {
627 reader *strings.Reader
631 func (ec *eofCounter) Read(b []byte) (n int, err error) {
632 n, err = ec.reader.Read(b)
639 // Verify that when we scan, we see at most EOF once per call to a Scan function,
640 // and then only when it's really an EOF
641 func TestEOF(t *testing.T) {
642 ec := &eofCounter{strings.NewReader("123\n"), 0}
644 n, err := Fscanln(ec, &a)
646 t.Error("unexpected error", err)
649 t.Error("expected to scan one item, got", n)
651 if ec.eofCount != 0 {
652 t.Error("expected zero EOFs", ec.eofCount)
653 ec.eofCount = 0 // reset for next test
655 n, err = Fscanln(ec, &a)
657 t.Error("expected error scanning empty string")
660 t.Error("expected to scan zero items, got", n)
662 if ec.eofCount != 1 {
663 t.Error("expected one EOF, got", ec.eofCount)
667 // Verify that we see an EOF error if we run out of input.
668 // This was a buglet: we used to get "expected integer".
669 func TestEOFAtEndOfInput(t *testing.T) {
671 n, err := Sscanf("23", "%d %d", &i, &j)
672 if n != 1 || i != 23 {
673 t.Errorf("Sscanf expected one value of 23; got %d %d", n, i)
676 t.Errorf("Sscanf expected EOF; got %q", err)
678 n, err = Sscan("234", &i, &j)
679 if n != 1 || i != 234 {
680 t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
683 t.Errorf("Sscan expected EOF; got %q", err)
685 // Trailing space is tougher.
686 n, err = Sscan("234 ", &i, &j)
687 if n != 1 || i != 234 {
688 t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
691 t.Errorf("Sscan expected EOF; got %q", err)
695 var eofTests = []struct {
708 {"%v", &complex64Val},
709 {"%v", &renamedStringVal},
710 {"%v", &renamedBytesVal},
711 {"%v", &renamedIntVal},
712 {"%v", &renamedUintVal},
713 {"%v", &renamedBoolVal},
714 {"%v", &renamedFloat32Val},
715 {"%v", &renamedComplex64Val},
718 func TestEOFAllTypes(t *testing.T) {
719 for i, test := range eofTests {
720 if _, err := Sscanf("", test.format, test.v); err != io.EOF {
721 t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err)
723 if _, err := Sscanf(" ", test.format, test.v); err != io.EOF {
724 t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err)
729 // Verify that, at least when using bufio, successive calls to Fscan do not lose runes.
730 func TestUnreadRuneWithBufio(t *testing.T) {
731 r := bufio.NewReader(strings.NewReader("123αb"))
734 n, err := Fscanf(r, "%d", &i)
735 if n != 1 || err != nil {
736 t.Errorf("reading int expected one item, no errors; got %d %q", n, err)
739 t.Errorf("expected 123; got %d", i)
741 n, err = Fscanf(r, "%s", &a)
742 if n != 1 || err != nil {
743 t.Errorf("reading string expected one item, no errors; got %d %q", n, err)
746 t.Errorf("expected αb; got %q", a)
752 // Attempt to read two lines into the object. Scanln should prevent this
753 // because it stops at newline; Scan and Scanf should be fine.
754 func (t *TwoLines) Scan(state ScanState, verb rune) error {
755 chars := make([]rune, 0, 100)
756 for nlCount := 0; nlCount < 2; {
757 c, _, err := state.ReadRune()
761 chars = append(chars, c)
766 *t = TwoLines(string(chars))
770 func TestMultiLine(t *testing.T) {
771 input := "abc\ndef\n"
774 n, err := Sscan(input, &tscan)
776 t.Errorf("Sscan: expected 1 item; got %d", n)
779 t.Errorf("Sscan: expected no error; got %s", err)
781 if string(tscan) != input {
782 t.Errorf("Sscan: expected %q; got %q", input, tscan)
784 // Sscanf should work
786 n, err = Sscanf(input, "%s", &tscanf)
788 t.Errorf("Sscanf: expected 1 item; got %d", n)
791 t.Errorf("Sscanf: expected no error; got %s", err)
793 if string(tscanf) != input {
794 t.Errorf("Sscanf: expected %q; got %q", input, tscanf)
796 // Sscanln should not work
798 n, err = Sscanln(input, &tscanln)
800 t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln)
803 t.Error("Sscanln: expected error; got none")
804 } else if err != io.ErrUnexpectedEOF {
805 t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err)
809 // RecursiveInt accepts an string matching %d.%d.%d....
810 // and parses it into a linked list.
811 // It allows us to benchmark recursive descent style scanners.
812 type RecursiveInt struct {
817 func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
818 _, err = Fscan(state, &r.i)
822 next := new(RecursiveInt)
823 _, err = Fscanf(state, ".%v", next)
825 if err == errors.New("input does not match format") || err == io.ErrUnexpectedEOF {
834 // Perform the same scanning task as RecursiveInt.Scan
835 // but without recurring through scanner, so we can compare
836 // performance more directly.
837 func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) {
839 _, err = Fscan(b, &r.i)
843 c, _, err := b.ReadRune()
853 next := new(RecursiveInt)
854 err = scanInts(next, b)
861 func makeInts(n int) []byte {
864 for i := 1; i < n; i++ {
865 Fprintf(&buf, ".%d", i+1)
870 func TestScanInts(t *testing.T) {
871 testScanInts(t, scanInts)
872 testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) {
878 // 800 is small enough to not overflow the stack when using gccgo on a
879 // platform that does not support split stack.
882 func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) {
883 r := new(RecursiveInt)
884 ints := makeInts(intCount)
885 buf := bytes.NewBuffer(ints)
888 t.Error("unexpected error", err)
891 for ; r != nil; r = r.next {
893 t.Fatalf("bad scan: expected %d got %d", i, r.i)
898 t.Fatalf("bad scan count: expected %d got %d", intCount, i-1)
902 func BenchmarkScanInts(b *testing.B) {
904 ints := makeInts(intCount)
906 for i := b.N - 1; i >= 0; i-- {
907 buf := bytes.NewBuffer(ints)
914 func BenchmarkScanRecursiveInt(b *testing.B) {
916 ints := makeInts(intCount)
918 for i := b.N - 1; i >= 0; i-- {
919 buf := bytes.NewBuffer(ints)