LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package fmt_test | 5 package fmt_test |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | 8 "bufio" |
9 . "fmt" | 9 . "fmt" |
10 "io" | 10 "io" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 type FloatTest struct { | 80 type FloatTest struct { |
81 text string | 81 text string |
82 in float64 | 82 in float64 |
83 out float64 | 83 out float64 |
84 } | 84 } |
85 | 85 |
86 // Xs accepts any non-empty run of the verb character | 86 // Xs accepts any non-empty run of the verb character |
87 type Xs string | 87 type Xs string |
88 | 88 |
89 func (x *Xs) Scan(state ScanState, verb int) os.Error { | 89 func (x *Xs) Scan(state ScanState, verb int) os.Error { |
90 » var tok string | 90 » tok, err := state.Token() |
91 » var c int | |
92 » var err os.Error | |
93 » wid, present := state.Width() | |
94 » if !present { | |
95 » » tok, err = state.Token() | |
96 » } else { | |
97 » » for i := 0; i < wid; i++ { | |
98 » » » c, _, err = state.ReadRune() | |
99 » » » if err != nil { | |
100 » » » » break | |
101 » » » } | |
102 » » » tok += string(c) | |
103 » » } | |
104 » } | |
105 if err != nil { | 91 if err != nil { |
106 return err | 92 return err |
107 } | 93 } |
108 if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(tok) { | 94 if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(tok) { |
109 return os.ErrorString("syntax error for xs") | 95 return os.ErrorString("syntax error for xs") |
110 } | 96 } |
111 *x = Xs(tok) | 97 *x = Xs(tok) |
112 return nil | 98 return nil |
113 } | 99 } |
114 | 100 |
115 var xVal Xs | 101 var xVal Xs |
| 102 |
| 103 // IntString accepts an integer followed immediately by a string. |
| 104 // It tests the embedding of a scan within a scan. |
| 105 type IntString struct { |
| 106 i int |
| 107 s string |
| 108 } |
| 109 |
| 110 func (s *IntString) Scan(state ScanState, verb int) os.Error { |
| 111 if _, err := Fscan(state, &s.i); err != nil { |
| 112 return err |
| 113 } |
| 114 |
| 115 if _, err := Fscan(state, &s.s); err != nil { |
| 116 return err |
| 117 } |
| 118 return nil |
| 119 } |
| 120 |
| 121 var intStringVal IntString |
116 | 122 |
117 // myStringReader implements Read but not ReadRune, allowing us to test our read
Rune wrapper | 123 // myStringReader implements Read but not ReadRune, allowing us to test our read
Rune wrapper |
118 // type that creates something that can read runes given only Read(). | 124 // type that creates something that can read runes given only Read(). |
119 type myStringReader struct { | 125 type myStringReader struct { |
120 r *strings.Reader | 126 r *strings.Reader |
121 } | 127 } |
122 | 128 |
123 func (s *myStringReader) Read(p []byte) (n int, err os.Error) { | 129 func (s *myStringReader) Read(p []byte) (n int, err os.Error) { |
124 return s.r.Read(p) | 130 return s.r.Read(p) |
125 } | 131 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 {"107\n", &renamedInt32Val, renamedInt32(107)}, | 199 {"107\n", &renamedInt32Val, renamedInt32(107)}, |
194 {"108\n", &renamedInt64Val, renamedInt64(108)}, | 200 {"108\n", &renamedInt64Val, renamedInt64(108)}, |
195 {"109\n", &renamedUint8Val, renamedUint8(109)}, | 201 {"109\n", &renamedUint8Val, renamedUint8(109)}, |
196 {"110\n", &renamedUint16Val, renamedUint16(110)}, | 202 {"110\n", &renamedUint16Val, renamedUint16(110)}, |
197 {"111\n", &renamedUint32Val, renamedUint32(111)}, | 203 {"111\n", &renamedUint32Val, renamedUint32(111)}, |
198 {"112\n", &renamedUint64Val, renamedUint64(112)}, | 204 {"112\n", &renamedUint64Val, renamedUint64(112)}, |
199 {"113\n", &renamedUintptrVal, renamedUintptr(113)}, | 205 {"113\n", &renamedUintptrVal, renamedUintptr(113)}, |
200 {"114\n", &renamedStringVal, renamedString("114")}, | 206 {"114\n", &renamedStringVal, renamedString("114")}, |
201 {"115\n", &renamedBytesVal, renamedBytes([]byte("115"))}, | 207 {"115\n", &renamedBytesVal, renamedBytes([]byte("115"))}, |
202 | 208 |
203 » // Custom scanner. | 209 » // Custom scanners. |
204 {" vvv ", &xVal, Xs("vvv")}, | 210 {" vvv ", &xVal, Xs("vvv")}, |
| 211 {" 1234hello", &intStringVal, IntString{1234, "hello"}}, |
205 | 212 |
206 // Fixed bugs | 213 // Fixed bugs |
207 {"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow | 214 {"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow |
208 } | 215 } |
209 | 216 |
210 var scanfTests = []ScanfTest{ | 217 var scanfTests = []ScanfTest{ |
211 {"%v", "TRUE\n", &boolVal, true}, | 218 {"%v", "TRUE\n", &boolVal, true}, |
212 {"%t", "false\n", &boolVal, false}, | 219 {"%t", "false\n", &boolVal, false}, |
213 {"%v", "-71\n", &intVal, -71}, | 220 {"%v", "-71\n", &intVal, -71}, |
214 {"%v", "0377\n", &intVal, 0377}, | 221 {"%v", "0377\n", &intVal, 0377}, |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 {"(1e100+0i)", &complex64Val, 0}, | 308 {"(1e100+0i)", &complex64Val, 0}, |
302 {"(1+1e100i)", &complex64Val, 0}, | 309 {"(1+1e100i)", &complex64Val, 0}, |
303 {"(1-1e500i)", &complex128Val, 0}, | 310 {"(1-1e500i)", &complex128Val, 0}, |
304 } | 311 } |
305 | 312 |
306 var i, j, k int | 313 var i, j, k int |
307 var f float64 | 314 var f float64 |
308 var s, t string | 315 var s, t string |
309 var c complex128 | 316 var c complex128 |
310 var x, y Xs | 317 var x, y Xs |
| 318 var z IntString |
311 | 319 |
312 var multiTests = []ScanfMultiTest{ | 320 var multiTests = []ScanfMultiTest{ |
313 {"", "", nil, nil, ""}, | 321 {"", "", nil, nil, ""}, |
314 {"%d", "23", args(&i), args(23), ""}, | 322 {"%d", "23", args(&i), args(23), ""}, |
315 {"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""}, | 323 {"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""}, |
316 {"%2d%3d", "44555", args(&i, &j), args(44, 555), ""}, | 324 {"%2d%3d", "44555", args(&i, &j), args(44, 555), ""}, |
317 {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""}, | 325 {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""}, |
318 {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""}, | 326 {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""}, |
319 {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""}, | 327 {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""}, |
320 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""}, | 328 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""}, |
321 {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""}, | 329 {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""}, |
322 {"%c%c%c", "2\u50c2X", args(&i, &j, &k), args('2', '\u50c2', 'X'), ""}, | 330 {"%c%c%c", "2\u50c2X", args(&i, &j, &k), args('2', '\u50c2', 'X'), ""}, |
323 | 331 |
324 » // Custom scanner. | 332 » // Custom scanners. |
325 {"%2e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""}, | 333 {"%2e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""}, |
| 334 {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""}, |
326 | 335 |
327 // Errors | 336 // Errors |
328 {"%t", "23 18", args(&i), nil, "bad verb"}, | 337 {"%t", "23 18", args(&i), nil, "bad verb"}, |
329 {"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"}, | 338 {"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"}, |
330 {"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands
"}, | 339 {"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands
"}, |
331 {"%c", "\u0100", args(&int8Val), nil, "overflow"}, | 340 {"%c", "\u0100", args(&int8Val), nil, "overflow"}, |
332 {"X%d", "10X", args(&intVal), nil, "input does not match format"}, | 341 {"X%d", "10X", args(&intVal), nil, "input does not match format"}, |
333 | 342 |
334 // Bad UTF-8: should see every byte. | 343 // Bad UTF-8: should see every byte. |
335 {"%c%c%c", "\xc2X\xc2", args(&i, &j, &k), args(utf8.RuneError, 'X', utf8
.RuneError), ""}, | 344 {"%c%c%c", "\xc2X\xc2", args(&i, &j, &k), args(utf8.RuneError, 'X', utf8
.RuneError), ""}, |
336 } | 345 } |
337 | 346 |
338 func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}
) (int, os.Error)) { | 347 func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}
) (int, os.Error)) { |
339 for _, test := range scanTests { | 348 for _, test := range scanTests { |
340 var r io.Reader | 349 var r io.Reader |
341 if name == "StringReader" { | 350 if name == "StringReader" { |
342 r = strings.NewReader(test.text) | 351 r = strings.NewReader(test.text) |
343 } else { | 352 } else { |
344 r = newReader(test.text) | 353 r = newReader(test.text) |
345 } | 354 } |
346 n, err := scan(r, test.in) | 355 n, err := scan(r, test.in) |
347 if err != nil { | 356 if err != nil { |
348 » » » t.Errorf("%s got error scanning %q: %s", name, test.text
, err) | 357 » » » m := "" |
| 358 » » » if n > 0 { |
| 359 » » » » m = Sprintf(" (%d fields ok)", n) |
| 360 » » » } |
| 361 » » » t.Errorf("%s got error scanning %q: %s%s", name, test.te
xt, err, m) |
349 continue | 362 continue |
350 } | 363 } |
351 if n != 1 { | 364 if n != 1 { |
352 t.Errorf("%s count error on entry %q: got %d", name, tes
t.text, n) | 365 t.Errorf("%s count error on entry %q: got %d", name, tes
t.text, n) |
353 continue | 366 continue |
354 } | 367 } |
355 // The incoming value may be a pointer | 368 // The incoming value may be a pointer |
356 v := reflect.NewValue(test.in) | 369 v := reflect.NewValue(test.in) |
357 if p, ok := v.(*reflect.PtrValue); ok { | 370 if p, ok := v.(*reflect.PtrValue); ok { |
358 v = p.Elem() | 371 v = p.Elem() |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 n, err = Sscanln(input, &tscanln) | 738 n, err = Sscanln(input, &tscanln) |
726 if n != 0 { | 739 if n != 0 { |
727 t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln) | 740 t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln) |
728 } | 741 } |
729 if err == nil { | 742 if err == nil { |
730 t.Error("Sscanln: expected error; got none") | 743 t.Error("Sscanln: expected error; got none") |
731 } else if err != io.ErrUnexpectedEOF { | 744 } else if err != io.ErrUnexpectedEOF { |
732 t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s",
err) | 745 t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s",
err) |
733 } | 746 } |
734 } | 747 } |
LEFT | RIGHT |