OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [fmt/] [scan_test.go] - Blame information for rev 774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// 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
        "unicode/utf8"
19
)
20
 
21
type ScanTest struct {
22
        text string
23
        in   interface{}
24
        out  interface{}
25
}
26
 
27
type ScanfTest struct {
28
        format string
29
        text   string
30
        in     interface{}
31
        out    interface{}
32
}
33
 
34
type ScanfMultiTest struct {
35
        format string
36
        text   string
37
        in     []interface{}
38
        out    []interface{}
39
        err    string
40
}
41
 
42
var (
43
        boolVal              bool
44
        intVal               int
45
        int8Val              int8
46
        int16Val             int16
47
        int32Val             int32
48
        int64Val             int64
49
        uintVal              uint
50
        uint8Val             uint8
51
        uint16Val            uint16
52
        uint32Val            uint32
53
        uint64Val            uint64
54
        float32Val           float32
55
        float64Val           float64
56
        stringVal            string
57
        stringVal1           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
type FloatTest struct {
83
        text string
84
        in   float64
85
        out  float64
86
}
87
 
88
// Xs accepts any non-empty run of the verb character
89
type Xs string
90
 
91
func (x *Xs) Scan(state ScanState, verb rune) error {
92
        tok, err := state.Token(true, func(r rune) bool { return r == verb })
93
        if err != nil {
94
                return err
95
        }
96
        s := string(tok)
97
        if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) {
98
                return errors.New("syntax error for xs")
99
        }
100
        *x = Xs(s)
101
        return nil
102
}
103
 
104
var xVal Xs
105
 
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 {
109
        i int
110
        s string
111
}
112
 
113
func (s *IntString) Scan(state ScanState, verb rune) error {
114
        if _, err := Fscan(state, &s.i); err != nil {
115
                return err
116
        }
117
 
118
        tok, err := state.Token(true, nil)
119
        if err != nil {
120
                return err
121
        }
122
        s.s = string(tok)
123
        return nil
124
}
125
 
126
var intStringVal IntString
127
 
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 {
131
        r *strings.Reader
132
}
133
 
134
func (s *myStringReader) Read(p []byte) (n int, err error) {
135
        return s.r.Read(p)
136
}
137
 
138
func newReader(s string) *myStringReader {
139
        return &myStringReader{strings.NewReader(s)}
140
}
141
 
142
var scanTests = []ScanTest{
143
        // Basic types
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},
147
        {"0\n", &intVal, 0},
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"},
194
 
195
        // Renamed types
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"))},
213
 
214
        // Custom scanners.
215
        {"  vvv ", &xVal, Xs("vvv")},
216
        {" 1234hello", &intStringVal, IntString{1234, "hello"}},
217
 
218
        // Fixed bugs
219
        {"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow
220
}
221
 
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)},
251
 
252
        // Strings
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"},
257
 
258
        // Byte slices
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")},
263
 
264
        // Renamed types
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)},
287
 
288
        // Interesting formats
289
        {"here is\tthe value:%d", "here is   the\tvalue:118\n", &intVal, 118},
290
        {"%% %%:%d", "% %:119\n", &intVal, 119},
291
 
292
        // Corner cases
293
        {"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)},
294
 
295
        // Custom scanner.
296
        {"%s", "  sss ", &xVal, Xs("sss")},
297
        {"%2s", "sssss", &xVal, Xs("ss")},
298
 
299
        // Fixed bugs
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.
304
}
305
 
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},
318
}
319
 
320
var i, j, k int
321
var f float64
322
var s, t string
323
var c complex128
324
var x, y Xs
325
var z IntString
326
var r1, r2, r3 rune
327
 
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'), ""},
339
 
340
        // Custom scanners.
341
        {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
342
        {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""},
343
 
344
        // Errors
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"},
350
 
351
        // Bad UTF-8: should see every byte.
352
        {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
353
}
354
 
355
func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {
356
        for _, test := range scanTests {
357
                var r io.Reader
358
                if name == "StringReader" {
359
                        r = strings.NewReader(test.text)
360
                } else {
361
                        r = newReader(test.text)
362
                }
363
                n, err := scan(r, test.in)
364
                if err != nil {
365
                        m := ""
366
                        if n > 0 {
367
                                m = Sprintf(" (%d fields ok)", n)
368
                        }
369
                        t.Errorf("%s got error scanning %q: %s%s", name, test.text, err, m)
370
                        continue
371
                }
372
                if n != 1 {
373
                        t.Errorf("%s count error on entry %q: got %d", name, test.text, n)
374
                        continue
375
                }
376
                // The incoming value may be a pointer
377
                v := reflect.ValueOf(test.in)
378
                if p := v; p.Kind() == reflect.Ptr {
379
                        v = p.Elem()
380
                }
381
                val := v.Interface()
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)
384
                }
385
        }
386
}
387
 
388
func TestScan(t *testing.T) {
389
        testScan("StringReader", t, Fscan)
390
}
391
 
392
func TestMyReaderScan(t *testing.T) {
393
        testScan("myStringReader", t, Fscan)
394
}
395
 
396
func TestScanln(t *testing.T) {
397
        testScan("StringReader", t, Fscanln)
398
}
399
 
400
func TestMyReaderScanln(t *testing.T) {
401
        testScan("myStringReader", t, Fscanln)
402
}
403
 
404
func TestScanf(t *testing.T) {
405
        for _, test := range scanfTests {
406
                n, err := Sscanf(test.text, test.format, test.in)
407
                if err != nil {
408
                        t.Errorf("got error scanning (%q, %q): %s", test.format, test.text, err)
409
                        continue
410
                }
411
                if n != 1 {
412
                        t.Errorf("count error on entry (%q, %q): got %d", test.format, test.text, n)
413
                        continue
414
                }
415
                // The incoming value may be a pointer
416
                v := reflect.ValueOf(test.in)
417
                if p := v; p.Kind() == reflect.Ptr {
418
                        v = p.Elem()
419
                }
420
                val := v.Interface()
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)
423
                }
424
        }
425
}
426
 
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)
432
                if err == nil {
433
                        t.Errorf("expected overflow scanning %q", test.text)
434
                        continue
435
                }
436
                if !re.MatchString(err.Error()) {
437
                        t.Errorf("expected overflow error scanning %q: %s", test.text, err)
438
                }
439
        }
440
}
441
 
442
func verifyNaN(str string, t *testing.T) {
443
        var f float64
444
        var f32 float32
445
        var f64 float64
446
        text := str + " " + str + " " + str
447
        n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
448
        if err != nil {
449
                t.Errorf("got error scanning %q: %s", text, err)
450
        }
451
        if n != 3 {
452
                t.Errorf("count error scanning %q: got %d", text, n)
453
        }
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)
456
        }
457
}
458
 
459
func TestNaN(t *testing.T) {
460
        for _, s := range []string{"nan", "NAN", "NaN"} {
461
                verifyNaN(s, t)
462
        }
463
}
464
 
465
func verifyInf(str string, t *testing.T) {
466
        var f float64
467
        var f32 float32
468
        var f64 float64
469
        text := str + " " + str + " " + str
470
        n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
471
        if err != nil {
472
                t.Errorf("got error scanning %q: %s", text, err)
473
        }
474
        if n != 3 {
475
                t.Errorf("count error scanning %q: got %d", text, n)
476
        }
477
        sign := 1
478
        if str[0] == '-' {
479
                sign = -1
480
        }
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)
483
        }
484
}
485
 
486
func TestInf(t *testing.T) {
487
        for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
488
                verifyInf(s, t)
489
        }
490
}
491
 
492
func testScanfMulti(name string, t *testing.T) {
493
        sliceType := reflect.TypeOf(make([]interface{}, 1))
494
        for _, test := range multiTests {
495
                var r io.Reader
496
                if name == "StringReader" {
497
                        r = strings.NewReader(test.text)
498
                } else {
499
                        r = newReader(test.text)
500
                }
501
                n, err := Fscanf(r, test.format, test.in...)
502
                if err != nil {
503
                        if test.err == "" {
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)
507
                        }
508
                        continue
509
                }
510
                if test.err != "" {
511
                        t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text)
512
                }
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)
515
                        continue
516
                }
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)
522
                }
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)
526
                }
527
        }
528
}
529
 
530
func TestScanfMulti(t *testing.T) {
531
        testScanfMulti("StringReader", t)
532
}
533
 
534
func TestMyReaderScanfMulti(t *testing.T) {
535
        testScanfMulti("myStringReader", t)
536
}
537
 
538
func TestScanMultiple(t *testing.T) {
539
        var a int
540
        var s string
541
        n, err := Sscan("123abc", &a, &s)
542
        if n != 2 {
543
                t.Errorf("Sscan count error: expected 2: got %d", n)
544
        }
545
        if err != nil {
546
                t.Errorf("Sscan expected no error; got %s", err)
547
        }
548
        if a != 123 || s != "abc" {
549
                t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s)
550
        }
551
        n, err = Sscan("asdf", &s, &a)
552
        if n != 1 {
553
                t.Errorf("Sscan count error: expected 1: got %d", n)
554
        }
555
        if err == nil {
556
                t.Errorf("Sscan expected error; got none: %s", err)
557
        }
558
        if s != "asdf" {
559
                t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s)
560
        }
561
}
562
 
563
// Empty strings are not valid input when scanning a string.
564
func TestScanEmpty(t *testing.T) {
565
        var s1, s2 string
566
        n, err := Sscan("abc", &s1, &s2)
567
        if n != 1 {
568
                t.Errorf("Sscan count error: expected 1: got %d", n)
569
        }
570
        if err == nil {
571
                t.Error("Sscan  expected error; got none")
572
        }
573
        if s1 != "abc" {
574
                t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1)
575
        }
576
        n, err = Sscan("", &s1, &s2)
577
        if n != 0 {
578
                t.Errorf("Sscan count error: expected 0: got %d", n)
579
        }
580
        if err == nil {
581
                t.Error("Sscan  expected error; got none")
582
        }
583
        // Quoted empty string is OK.
584
        n, err = Sscanf(`""`, "%q", &s1)
585
        if n != 1 {
586
                t.Errorf("Sscanf count error: expected 1: got %d", n)
587
        }
588
        if err != nil {
589
                t.Errorf("Sscanf  expected no error with quoted string; got %s", err)
590
        }
591
}
592
 
593
func TestScanNotPointer(t *testing.T) {
594
        r := strings.NewReader("1")
595
        var a int
596
        _, err := Fscan(r, a)
597
        if err == nil {
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)
601
        }
602
}
603
 
604
func TestScanlnNoNewline(t *testing.T) {
605
        var a int
606
        _, err := Sscanln("1 x\n", &a)
607
        if err == nil {
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)
611
        }
612
}
613
 
614
func TestScanlnWithMiddleNewline(t *testing.T) {
615
        r := strings.NewReader("123\n456\n")
616
        var a, b int
617
        _, err := Fscanln(r, &a, &b)
618
        if err == nil {
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)
622
        }
623
}
624
 
625
// Special Reader that counts reads at end of file.
626
type eofCounter struct {
627
        reader   *strings.Reader
628
        eofCount int
629
}
630
 
631
func (ec *eofCounter) Read(b []byte) (n int, err error) {
632
        n, err = ec.reader.Read(b)
633
        if n == 0 {
634
                ec.eofCount++
635
        }
636
        return
637
}
638
 
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}
643
        var a int
644
        n, err := Fscanln(ec, &a)
645
        if err != nil {
646
                t.Error("unexpected error", err)
647
        }
648
        if n != 1 {
649
                t.Error("expected to scan one item, got", n)
650
        }
651
        if ec.eofCount != 0 {
652
                t.Error("expected zero EOFs", ec.eofCount)
653
                ec.eofCount = 0 // reset for next test
654
        }
655
        n, err = Fscanln(ec, &a)
656
        if err == nil {
657
                t.Error("expected error scanning empty string")
658
        }
659
        if n != 0 {
660
                t.Error("expected to scan zero items, got", n)
661
        }
662
        if ec.eofCount != 1 {
663
                t.Error("expected one EOF, got", ec.eofCount)
664
        }
665
}
666
 
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) {
670
        var i, j int
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)
674
        }
675
        if err != io.EOF {
676
                t.Errorf("Sscanf expected EOF; got %q", err)
677
        }
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)
681
        }
682
        if err != io.EOF {
683
                t.Errorf("Sscan expected EOF; got %q", err)
684
        }
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)
689
        }
690
        if err != io.EOF {
691
                t.Errorf("Sscan expected EOF; got %q", err)
692
        }
693
}
694
 
695
var eofTests = []struct {
696
        format string
697
        v      interface{}
698
}{
699
        {"%s", &stringVal},
700
        {"%q", &stringVal},
701
        {"%x", &stringVal},
702
        {"%v", &stringVal},
703
        {"%v", &bytesVal},
704
        {"%v", &intVal},
705
        {"%v", &uintVal},
706
        {"%v", &boolVal},
707
        {"%v", &float32Val},
708
        {"%v", &complex64Val},
709
        {"%v", &renamedStringVal},
710
        {"%v", &renamedBytesVal},
711
        {"%v", &renamedIntVal},
712
        {"%v", &renamedUintVal},
713
        {"%v", &renamedBoolVal},
714
        {"%v", &renamedFloat32Val},
715
        {"%v", &renamedComplex64Val},
716
}
717
 
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)
722
                }
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)
725
                }
726
        }
727
}
728
 
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"))
732
        var i int
733
        var a string
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)
737
        }
738
        if i != 123 {
739
                t.Errorf("expected 123; got %d", i)
740
        }
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)
744
        }
745
        if a != "αb" {
746
                t.Errorf("expected αb; got %q", a)
747
        }
748
}
749
 
750
type TwoLines string
751
 
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()
758
                if err != nil {
759
                        return err
760
                }
761
                chars = append(chars, c)
762
                if c == '\n' {
763
                        nlCount++
764
                }
765
        }
766
        *t = TwoLines(string(chars))
767
        return nil
768
}
769
 
770
func TestMultiLine(t *testing.T) {
771
        input := "abc\ndef\n"
772
        // Sscan should work
773
        var tscan TwoLines
774
        n, err := Sscan(input, &tscan)
775
        if n != 1 {
776
                t.Errorf("Sscan: expected 1 item; got %d", n)
777
        }
778
        if err != nil {
779
                t.Errorf("Sscan: expected no error; got %s", err)
780
        }
781
        if string(tscan) != input {
782
                t.Errorf("Sscan: expected %q; got %q", input, tscan)
783
        }
784
        // Sscanf should work
785
        var tscanf TwoLines
786
        n, err = Sscanf(input, "%s", &tscanf)
787
        if n != 1 {
788
                t.Errorf("Sscanf: expected 1 item; got %d", n)
789
        }
790
        if err != nil {
791
                t.Errorf("Sscanf: expected no error; got %s", err)
792
        }
793
        if string(tscanf) != input {
794
                t.Errorf("Sscanf: expected %q; got %q", input, tscanf)
795
        }
796
        // Sscanln should not work
797
        var tscanln TwoLines
798
        n, err = Sscanln(input, &tscanln)
799
        if n != 0 {
800
                t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln)
801
        }
802
        if err == nil {
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)
806
        }
807
}
808
 
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 {
813
        i    int
814
        next *RecursiveInt
815
}
816
 
817
func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
818
        _, err = Fscan(state, &r.i)
819
        if err != nil {
820
                return
821
        }
822
        next := new(RecursiveInt)
823
        _, err = Fscanf(state, ".%v", next)
824
        if err != nil {
825
                if err == errors.New("input does not match format") || err == io.ErrUnexpectedEOF {
826
                        err = nil
827
                }
828
                return
829
        }
830
        r.next = next
831
        return
832
}
833
 
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) {
838
        r.next = nil
839
        _, err = Fscan(b, &r.i)
840
        if err != nil {
841
                return
842
        }
843
        c, _, err := b.ReadRune()
844
        if err != nil {
845
                if err == io.EOF {
846
                        err = nil
847
                }
848
                return
849
        }
850
        if c != '.' {
851
                return
852
        }
853
        next := new(RecursiveInt)
854
        err = scanInts(next, b)
855
        if err == nil {
856
                r.next = next
857
        }
858
        return
859
}
860
 
861
func makeInts(n int) []byte {
862
        var buf bytes.Buffer
863
        Fprintf(&buf, "1")
864
        for i := 1; i < n; i++ {
865
                Fprintf(&buf, ".%d", i+1)
866
        }
867
        return buf.Bytes()
868
}
869
 
870
func TestScanInts(t *testing.T) {
871
        testScanInts(t, scanInts)
872
        testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) {
873
                _, err = Fscan(b, r)
874
                return
875
        })
876
}
877
 
878
// 800 is small enough to not overflow the stack when using gccgo on a
879
// platform that does not support split stack.
880
const intCount = 800
881
 
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)
886
        err := scan(r, buf)
887
        if err != nil {
888
                t.Error("unexpected error", err)
889
        }
890
        i := 1
891
        for ; r != nil; r = r.next {
892
                if r.i != i {
893
                        t.Fatalf("bad scan: expected %d got %d", i, r.i)
894
                }
895
                i++
896
        }
897
        if i-1 != intCount {
898
                t.Fatalf("bad scan count: expected %d got %d", intCount, i-1)
899
        }
900
}
901
 
902
func BenchmarkScanInts(b *testing.B) {
903
        b.ResetTimer()
904
        ints := makeInts(intCount)
905
        var r RecursiveInt
906
        for i := b.N - 1; i >= 0; i-- {
907
                buf := bytes.NewBuffer(ints)
908
                b.StartTimer()
909
                scanInts(&r, buf)
910
                b.StopTimer()
911
        }
912
}
913
 
914
func BenchmarkScanRecursiveInt(b *testing.B) {
915
        b.ResetTimer()
916
        ints := makeInts(intCount)
917
        var r RecursiveInt
918
        for i := b.N - 1; i >= 0; i-- {
919
                buf := bytes.NewBuffer(ints)
920
                b.StartTimer()
921
                Fscan(buf, &r)
922
                b.StopTimer()
923
        }
924
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.