[PR rtl-optimization/115877][6/n] Add testcase from pr115877
[official-gcc.git] / libgo / go / fmt / scan_test.go
blobda0dfd19a2d4f992e0512cd7d0f5a127b709414f
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.
5 package fmt_test
7 import (
8 "bufio"
9 "bytes"
10 "errors"
11 . "fmt"
12 "io"
13 "math"
14 "reflect"
15 "regexp"
16 "strings"
17 "testing"
18 "testing/iotest"
19 "unicode/utf8"
22 type ScanTest struct {
23 text string
24 in any
25 out any
28 type ScanfTest struct {
29 format string
30 text string
31 in any
32 out any
35 type ScanfMultiTest struct {
36 format string
37 text string
38 in []any
39 out []any
40 err string
43 var (
44 boolVal bool
45 intVal int
46 int8Val int8
47 int16Val int16
48 int32Val int32
49 int64Val int64
50 uintVal uint
51 uint8Val uint8
52 uint16Val uint16
53 uint32Val uint32
54 uint64Val uint64
55 float32Val float32
56 float64Val float64
57 stringVal string
58 bytesVal []byte
59 runeVal rune
60 complex64Val complex64
61 complex128Val complex128
62 renamedBoolVal renamedBool
63 renamedIntVal renamedInt
64 renamedInt8Val renamedInt8
65 renamedInt16Val renamedInt16
66 renamedInt32Val renamedInt32
67 renamedInt64Val renamedInt64
68 renamedUintVal renamedUint
69 renamedUint8Val renamedUint8
70 renamedUint16Val renamedUint16
71 renamedUint32Val renamedUint32
72 renamedUint64Val renamedUint64
73 renamedUintptrVal renamedUintptr
74 renamedStringVal renamedString
75 renamedBytesVal renamedBytes
76 renamedFloat32Val renamedFloat32
77 renamedFloat64Val renamedFloat64
78 renamedComplex64Val renamedComplex64
79 renamedComplex128Val renamedComplex128
82 // Xs accepts any non-empty run of the verb character
83 type Xs string
85 func (x *Xs) Scan(state ScanState, verb rune) error {
86 tok, err := state.Token(true, func(r rune) bool { return r == verb })
87 if err != nil {
88 return err
90 s := string(tok)
91 if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) {
92 return errors.New("syntax error for xs")
94 *x = Xs(s)
95 return nil
98 var xVal Xs
100 // IntString accepts an integer followed immediately by a string.
101 // It tests the embedding of a scan within a scan.
102 type IntString struct {
103 i int
104 s string
107 func (s *IntString) Scan(state ScanState, verb rune) error {
108 if _, err := Fscan(state, &s.i); err != nil {
109 return err
112 tok, err := state.Token(true, nil)
113 if err != nil {
114 return err
116 s.s = string(tok)
117 return nil
120 var intStringVal IntString
122 var scanTests = []ScanTest{
123 // Basic types
124 {"T\n", &boolVal, true}, // boolean test vals toggle to be sure they are written
125 {"F\n", &boolVal, false}, // restored to zero value
126 {"21\n", &intVal, 21},
127 {"2_1\n", &intVal, 21},
128 {"0\n", &intVal, 0},
129 {"000\n", &intVal, 0},
130 {"0x10\n", &intVal, 0x10},
131 {"0x_1_0\n", &intVal, 0x10},
132 {"-0x10\n", &intVal, -0x10},
133 {"0377\n", &intVal, 0377},
134 {"0_3_7_7\n", &intVal, 0377},
135 {"0o377\n", &intVal, 0377},
136 {"0o_3_7_7\n", &intVal, 0377},
137 {"-0377\n", &intVal, -0377},
138 {"-0o377\n", &intVal, -0377},
139 {"0\n", &uintVal, uint(0)},
140 {"000\n", &uintVal, uint(0)},
141 {"0x10\n", &uintVal, uint(0x10)},
142 {"0377\n", &uintVal, uint(0377)},
143 {"22\n", &int8Val, int8(22)},
144 {"23\n", &int16Val, int16(23)},
145 {"24\n", &int32Val, int32(24)},
146 {"25\n", &int64Val, int64(25)},
147 {"127\n", &int8Val, int8(127)},
148 {"-21\n", &intVal, -21},
149 {"-22\n", &int8Val, int8(-22)},
150 {"-23\n", &int16Val, int16(-23)},
151 {"-24\n", &int32Val, int32(-24)},
152 {"-25\n", &int64Val, int64(-25)},
153 {"-128\n", &int8Val, int8(-128)},
154 {"+21\n", &intVal, +21},
155 {"+22\n", &int8Val, int8(+22)},
156 {"+23\n", &int16Val, int16(+23)},
157 {"+24\n", &int32Val, int32(+24)},
158 {"+25\n", &int64Val, int64(+25)},
159 {"+127\n", &int8Val, int8(+127)},
160 {"26\n", &uintVal, uint(26)},
161 {"27\n", &uint8Val, uint8(27)},
162 {"28\n", &uint16Val, uint16(28)},
163 {"29\n", &uint32Val, uint32(29)},
164 {"30\n", &uint64Val, uint64(30)},
165 {"255\n", &uint8Val, uint8(255)},
166 {"32767\n", &int16Val, int16(32767)},
167 {"2.3\n", &float64Val, 2.3},
168 {"2.3e1\n", &float32Val, float32(2.3e1)},
169 {"2.3e2\n", &float64Val, 2.3e2},
170 {"2.3p2\n", &float64Val, 2.3 * 4},
171 {"2.3p+2\n", &float64Val, 2.3 * 4},
172 {"2.3p+66\n", &float64Val, 2.3 * (1 << 66)},
173 {"2.3p-66\n", &float64Val, 2.3 / (1 << 66)},
174 {"0x2.3p-66\n", &float64Val, float64(0x23) / (1 << 70)},
175 {"2_3.4_5\n", &float64Val, 23.45},
176 {"2.35\n", &stringVal, "2.35"},
177 {"2345678\n", &bytesVal, []byte("2345678")},
178 {"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i},
179 {"-3.45e1-3i\n", &complex64Val, complex64(-3.45e1 - 3i)},
180 {"-.45e1-1e2i\n", &complex128Val, complex128(-.45e1 - 100i)},
181 {"-.4_5e1-1E2i\n", &complex128Val, complex128(-.45e1 - 100i)},
182 {"0x1.0p1+0x1.0P2i\n", &complex128Val, complex128(2 + 4i)},
183 {"-0x1p1-0x1p2i\n", &complex128Val, complex128(-2 - 4i)},
184 {"-0x1ep-1-0x1p2i\n", &complex128Val, complex128(-15 - 4i)},
185 {"-0x1_Ep-1-0x1p0_2i\n", &complex128Val, complex128(-15 - 4i)},
186 {"hello\n", &stringVal, "hello"},
188 // Carriage-return followed by newline. (We treat \r\n as \n always.)
189 {"hello\r\n", &stringVal, "hello"},
190 {"27\r\n", &uint8Val, uint8(27)},
192 // Renamed types
193 {"true\n", &renamedBoolVal, renamedBool(true)},
194 {"F\n", &renamedBoolVal, renamedBool(false)},
195 {"101\n", &renamedIntVal, renamedInt(101)},
196 {"102\n", &renamedIntVal, renamedInt(102)},
197 {"103\n", &renamedUintVal, renamedUint(103)},
198 {"104\n", &renamedUintVal, renamedUint(104)},
199 {"105\n", &renamedInt8Val, renamedInt8(105)},
200 {"106\n", &renamedInt16Val, renamedInt16(106)},
201 {"107\n", &renamedInt32Val, renamedInt32(107)},
202 {"108\n", &renamedInt64Val, renamedInt64(108)},
203 {"109\n", &renamedUint8Val, renamedUint8(109)},
204 {"110\n", &renamedUint16Val, renamedUint16(110)},
205 {"111\n", &renamedUint32Val, renamedUint32(111)},
206 {"112\n", &renamedUint64Val, renamedUint64(112)},
207 {"113\n", &renamedUintptrVal, renamedUintptr(113)},
208 {"114\n", &renamedStringVal, renamedString("114")},
209 {"115\n", &renamedBytesVal, renamedBytes([]byte("115"))},
211 // Custom scanners.
212 {" vvv ", &xVal, Xs("vvv")},
213 {" 1234hello", &intStringVal, IntString{1234, "hello"}},
215 // Fixed bugs
216 {"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow
219 var scanfTests = []ScanfTest{
220 {"%v", "TRUE\n", &boolVal, true},
221 {"%t", "false\n", &boolVal, false},
222 {"%v", "-71\n", &intVal, -71},
223 {"%v", "-7_1\n", &intVal, -71},
224 {"%v", "0b111\n", &intVal, 7},
225 {"%v", "0b_1_1_1\n", &intVal, 7},
226 {"%v", "0377\n", &intVal, 0377},
227 {"%v", "0_3_7_7\n", &intVal, 0377},
228 {"%v", "0o377\n", &intVal, 0377},
229 {"%v", "0o_3_7_7\n", &intVal, 0377},
230 {"%v", "0x44\n", &intVal, 0x44},
231 {"%v", "0x_4_4\n", &intVal, 0x44},
232 {"%d", "72\n", &intVal, 72},
233 {"%c", "a\n", &runeVal, 'a'},
234 {"%c", "\u5072\n", &runeVal, '\u5072'},
235 {"%c", "\u1234\n", &runeVal, '\u1234'},
236 {"%d", "73\n", &int8Val, int8(73)},
237 {"%d", "+74\n", &int16Val, int16(74)},
238 {"%d", "75\n", &int32Val, int32(75)},
239 {"%d", "76\n", &int64Val, int64(76)},
240 {"%b", "1001001\n", &intVal, 73},
241 {"%o", "075\n", &intVal, 075},
242 {"%x", "a75\n", &intVal, 0xa75},
243 {"%v", "71\n", &uintVal, uint(71)},
244 {"%d", "72\n", &uintVal, uint(72)},
245 {"%d", "7_2\n", &uintVal, uint(7)}, // only %v takes underscores
246 {"%d", "73\n", &uint8Val, uint8(73)},
247 {"%d", "74\n", &uint16Val, uint16(74)},
248 {"%d", "75\n", &uint32Val, uint32(75)},
249 {"%d", "76\n", &uint64Val, uint64(76)},
250 {"%b", "1001001\n", &uintVal, uint(73)},
251 {"%b", "100_1001\n", &uintVal, uint(4)},
252 {"%o", "075\n", &uintVal, uint(075)},
253 {"%o", "07_5\n", &uintVal, uint(07)}, // only %v takes underscores
254 {"%x", "a75\n", &uintVal, uint(0xa75)},
255 {"%x", "A75\n", &uintVal, uint(0xa75)},
256 {"%x", "A7_5\n", &uintVal, uint(0xa7)}, // only %v takes underscores
257 {"%U", "U+1234\n", &intVal, int(0x1234)},
258 {"%U", "U+4567\n", &uintVal, uint(0x4567)},
260 {"%e", "2.3\n", &float64Val, 2.3},
261 {"%E", "2.3e1\n", &float32Val, float32(2.3e1)},
262 {"%f", "2.3e2\n", &float64Val, 2.3e2},
263 {"%g", "2.3p2\n", &float64Val, 2.3 * 4},
264 {"%G", "2.3p+2\n", &float64Val, 2.3 * 4},
265 {"%v", "2.3p+66\n", &float64Val, 2.3 * (1 << 66)},
266 {"%f", "2.3p-66\n", &float64Val, 2.3 / (1 << 66)},
267 {"%G", "0x2.3p-66\n", &float64Val, float64(0x23) / (1 << 70)},
268 {"%E", "2_3.4_5\n", &float64Val, 23.45},
270 // Strings
271 {"%s", "using-%s\n", &stringVal, "using-%s"},
272 {"%x", "7573696e672d2578\n", &stringVal, "using-%x"},
273 {"%X", "7573696E672D2558\n", &stringVal, "using-%X"},
274 {"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal, "quoted\twith\\doubles"},
275 {"%q", "`quoted with backs`\n", &stringVal, "quoted with backs"},
277 // Byte slices
278 {"%s", "bytes-%s\n", &bytesVal, []byte("bytes-%s")},
279 {"%x", "62797465732d2578\n", &bytesVal, []byte("bytes-%x")},
280 {"%X", "62797465732D2558\n", &bytesVal, []byte("bytes-%X")},
281 {"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal, []byte("bytes\rwith\vdoubles")},
282 {"%q", "`bytes with backs`\n", &bytesVal, []byte("bytes with backs")},
284 // Renamed types
285 {"%v\n", "true\n", &renamedBoolVal, renamedBool(true)},
286 {"%t\n", "F\n", &renamedBoolVal, renamedBool(false)},
287 {"%v", "101\n", &renamedIntVal, renamedInt(101)},
288 {"%c", "\u0101\n", &renamedIntVal, renamedInt('\u0101')},
289 {"%o", "0146\n", &renamedIntVal, renamedInt(102)},
290 {"%v", "103\n", &renamedUintVal, renamedUint(103)},
291 {"%d", "104\n", &renamedUintVal, renamedUint(104)},
292 {"%d", "105\n", &renamedInt8Val, renamedInt8(105)},
293 {"%d", "106\n", &renamedInt16Val, renamedInt16(106)},
294 {"%d", "107\n", &renamedInt32Val, renamedInt32(107)},
295 {"%d", "108\n", &renamedInt64Val, renamedInt64(108)},
296 {"%x", "6D\n", &renamedUint8Val, renamedUint8(109)},
297 {"%o", "0156\n", &renamedUint16Val, renamedUint16(110)},
298 {"%d", "111\n", &renamedUint32Val, renamedUint32(111)},
299 {"%d", "112\n", &renamedUint64Val, renamedUint64(112)},
300 {"%d", "113\n", &renamedUintptrVal, renamedUintptr(113)},
301 {"%s", "114\n", &renamedStringVal, renamedString("114")},
302 {"%q", "\"1155\"\n", &renamedBytesVal, renamedBytes([]byte("1155"))},
303 {"%g", "116e1\n", &renamedFloat32Val, renamedFloat32(116e1)},
304 {"%g", "-11.7e+1", &renamedFloat64Val, renamedFloat64(-11.7e+1)},
305 {"%g", "11+6e1i\n", &renamedComplex64Val, renamedComplex64(11 + 6e1i)},
306 {"%g", "-11.+7e+1i", &renamedComplex128Val, renamedComplex128(-11. + 7e+1i)},
308 // Interesting formats
309 {"here is\tthe value:%d", "here is the\tvalue:118\n", &intVal, 118},
310 {"%% %%:%d", "% %:119\n", &intVal, 119},
311 {"%d%%", "42%", &intVal, 42}, // %% at end of string.
313 // Corner cases
314 {"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)},
316 // Custom scanner.
317 {"%s", " sss ", &xVal, Xs("sss")},
318 {"%2s", "sssss", &xVal, Xs("ss")},
320 // Fixed bugs
321 {"%d\n", "27\n", &intVal, 27}, // ok
322 {"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
323 {"%v", "0", &intVal, 0}, // was: "EOF"; 0 was taken as base prefix and not counted.
324 {"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
325 {"%c", " ", &uintVal, uint(' ')}, // %c must accept a blank.
326 {"%c", "\t", &uintVal, uint('\t')}, // %c must accept any space.
327 {"%c", "\n", &uintVal, uint('\n')}, // %c must accept any space.
328 {"%d%%", "23%\n", &uintVal, uint(23)}, // %% matches literal %.
329 {"%%%d", "%23\n", &uintVal, uint(23)}, // %% matches literal %.
331 // space handling
332 {"%d", "27", &intVal, 27},
333 {"%d", "27 ", &intVal, 27},
334 {"%d", " 27", &intVal, 27},
335 {"%d", " 27 ", &intVal, 27},
337 {"X%d", "X27", &intVal, 27},
338 {"X%d", "X27 ", &intVal, 27},
339 {"X%d", "X 27", &intVal, 27},
340 {"X%d", "X 27 ", &intVal, 27},
342 {"X %d", "X27", &intVal, nil}, // expected space in input to match format
343 {"X %d", "X27 ", &intVal, nil}, // expected space in input to match format
344 {"X %d", "X 27", &intVal, 27},
345 {"X %d", "X 27 ", &intVal, 27},
347 {"%dX", "27X", &intVal, 27},
348 {"%dX", "27 X", &intVal, nil}, // input does not match format
349 {"%dX", " 27X", &intVal, 27},
350 {"%dX", " 27 X", &intVal, nil}, // input does not match format
352 {"%d X", "27X", &intVal, nil}, // expected space in input to match format
353 {"%d X", "27 X", &intVal, 27},
354 {"%d X", " 27X", &intVal, nil}, // expected space in input to match format
355 {"%d X", " 27 X", &intVal, 27},
357 {"X %d X", "X27X", &intVal, nil}, // expected space in input to match format
358 {"X %d X", "X27 X", &intVal, nil}, // expected space in input to match format
359 {"X %d X", "X 27X", &intVal, nil}, // expected space in input to match format
360 {"X %d X", "X 27 X", &intVal, 27},
362 {"X %s X", "X27X", &stringVal, nil}, // expected space in input to match format
363 {"X %s X", "X27 X", &stringVal, nil}, // expected space in input to match format
364 {"X %s X", "X 27X", &stringVal, nil}, // unexpected EOF
365 {"X %s X", "X 27 X", &stringVal, "27"},
367 {"X%sX", "X27X", &stringVal, nil}, // unexpected EOF
368 {"X%sX", "X27 X", &stringVal, nil}, // input does not match format
369 {"X%sX", "X 27X", &stringVal, nil}, // unexpected EOF
370 {"X%sX", "X 27 X", &stringVal, nil}, // input does not match format
372 {"X%s", "X27", &stringVal, "27"},
373 {"X%s", "X27 ", &stringVal, "27"},
374 {"X%s", "X 27", &stringVal, "27"},
375 {"X%s", "X 27 ", &stringVal, "27"},
377 {"X%dX", "X27X", &intVal, 27},
378 {"X%dX", "X27 X", &intVal, nil}, // input does not match format
379 {"X%dX", "X 27X", &intVal, 27},
380 {"X%dX", "X 27 X", &intVal, nil}, // input does not match format
382 {"X%dX", "X27X", &intVal, 27},
383 {"X%dX", "X27X ", &intVal, 27},
384 {"X%dX", " X27X", &intVal, nil}, // input does not match format
385 {"X%dX", " X27X ", &intVal, nil}, // input does not match format
387 {"X%dX\n", "X27X", &intVal, 27},
388 {"X%dX \n", "X27X ", &intVal, 27},
389 {"X%dX\n", "X27X\n", &intVal, 27},
390 {"X%dX\n", "X27X \n", &intVal, 27},
392 {"X%dX \n", "X27X", &intVal, 27},
393 {"X%dX \n", "X27X ", &intVal, 27},
394 {"X%dX \n", "X27X\n", &intVal, 27},
395 {"X%dX \n", "X27X \n", &intVal, 27},
397 {"X%c", "X\n", &runeVal, '\n'},
398 {"X%c", "X \n", &runeVal, ' '},
399 {"X %c", "X!", &runeVal, nil}, // expected space in input to match format
400 {"X %c", "X\n", &runeVal, nil}, // newline in input does not match format
401 {"X %c", "X !", &runeVal, '!'},
402 {"X %c", "X \n", &runeVal, '\n'},
404 {" X%dX", "X27X", &intVal, nil}, // expected space in input to match format
405 {" X%dX", "X27X ", &intVal, nil}, // expected space in input to match format
406 {" X%dX", " X27X", &intVal, 27},
407 {" X%dX", " X27X ", &intVal, 27},
409 {"X%dX ", "X27X", &intVal, 27},
410 {"X%dX ", "X27X ", &intVal, 27},
411 {"X%dX ", " X27X", &intVal, nil}, // input does not match format
412 {"X%dX ", " X27X ", &intVal, nil}, // input does not match format
414 {" X%dX ", "X27X", &intVal, nil}, // expected space in input to match format
415 {" X%dX ", "X27X ", &intVal, nil}, // expected space in input to match format
416 {" X%dX ", " X27X", &intVal, 27},
417 {" X%dX ", " X27X ", &intVal, 27},
419 {"%d\nX", "27\nX", &intVal, 27},
420 {"%dX\n X", "27X\n X", &intVal, 27},
423 var overflowTests = []ScanTest{
424 {"128", &int8Val, 0},
425 {"32768", &int16Val, 0},
426 {"-129", &int8Val, 0},
427 {"-32769", &int16Val, 0},
428 {"256", &uint8Val, 0},
429 {"65536", &uint16Val, 0},
430 {"1e100", &float32Val, 0},
431 {"1e500", &float64Val, 0},
432 {"(1e100+0i)", &complex64Val, 0},
433 {"(1+1e100i)", &complex64Val, 0},
434 {"(1-1e500i)", &complex128Val, 0},
437 var truth bool
438 var i, j, k int
439 var f float64
440 var s, t string
441 var c complex128
442 var x, y Xs
443 var z IntString
444 var r1, r2, r3 rune
446 var multiTests = []ScanfMultiTest{
447 {"", "", []any{}, []any{}, ""},
448 {"%d", "23", args(&i), args(23), ""},
449 {"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""},
450 {"%2d%3d", "44555", args(&i, &j), args(44, 555), ""},
451 {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""},
452 {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""},
453 {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
454 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
455 {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
456 {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
457 {"%5s%d", " 1234567 ", args(&s, &i), args("12345", 67), ""},
458 {"%5s%d", " 12 34 567 ", args(&s, &i), args("12", 34), ""},
460 // Custom scanners.
461 {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
462 {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""},
464 // Errors
465 {"%t", "23 18", args(&i), nil, "bad verb"},
466 {"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"},
467 {"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"},
468 {"%c", "\u0100", args(&int8Val), nil, "overflow"},
469 {"X%d", "10X", args(&intVal), nil, "input does not match format"},
470 {"%d%", "42%", args(&intVal), args(42), "missing verb: % at end of format string"},
471 {"%d% ", "42%", args(&intVal), args(42), "too few operands for format '% '"}, // Slightly odd error, but correct.
472 {"%%%d", "xxx 42", args(&intVal), args(42), "missing literal %"},
473 {"%%%d", "x42", args(&intVal), args(42), "missing literal %"},
474 {"%%%d", "42", args(&intVal), args(42), "missing literal %"},
476 // Bad UTF-8: should see every byte.
477 {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
479 // Fixed bugs
480 {"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""},
483 var readers = []struct {
484 name string
485 f func(string) io.Reader
487 {"StringReader", func(s string) io.Reader {
488 return strings.NewReader(s)
490 {"ReaderOnly", func(s string) io.Reader {
491 return struct{ io.Reader }{strings.NewReader(s)}
493 {"OneByteReader", func(s string) io.Reader {
494 return iotest.OneByteReader(strings.NewReader(s))
496 {"DataErrReader", func(s string) io.Reader {
497 return iotest.DataErrReader(strings.NewReader(s))
501 func testScan(t *testing.T, f func(string) io.Reader, scan func(r io.Reader, a ...any) (int, error)) {
502 for _, test := range scanTests {
503 r := f(test.text)
504 n, err := scan(r, test.in)
505 if err != nil {
506 m := ""
507 if n > 0 {
508 m = Sprintf(" (%d fields ok)", n)
510 t.Errorf("got error scanning %q: %s%s", test.text, err, m)
511 continue
513 if n != 1 {
514 t.Errorf("count error on entry %q: got %d", test.text, n)
515 continue
517 // The incoming value may be a pointer
518 v := reflect.ValueOf(test.in)
519 if p := v; p.Kind() == reflect.Pointer {
520 v = p.Elem()
522 val := v.Interface()
523 if !reflect.DeepEqual(val, test.out) {
524 t.Errorf("scanning %q: expected %#v got %#v, type %T", test.text, test.out, val, val)
529 func TestScan(t *testing.T) {
530 for _, r := range readers {
531 t.Run(r.name, func(t *testing.T) {
532 testScan(t, r.f, Fscan)
537 func TestScanln(t *testing.T) {
538 for _, r := range readers {
539 t.Run(r.name, func(t *testing.T) {
540 testScan(t, r.f, Fscanln)
545 func TestScanf(t *testing.T) {
546 for _, test := range scanfTests {
547 n, err := Sscanf(test.text, test.format, test.in)
548 if err != nil {
549 if test.out != nil {
550 t.Errorf("Sscanf(%q, %q): unexpected error: %v", test.text, test.format, err)
552 continue
554 if test.out == nil {
555 t.Errorf("Sscanf(%q, %q): unexpected success", test.text, test.format)
556 continue
558 if n != 1 {
559 t.Errorf("Sscanf(%q, %q): parsed %d field, want 1", test.text, test.format, n)
560 continue
562 // The incoming value may be a pointer
563 v := reflect.ValueOf(test.in)
564 if p := v; p.Kind() == reflect.Pointer {
565 v = p.Elem()
567 val := v.Interface()
568 if !reflect.DeepEqual(val, test.out) {
569 t.Errorf("Sscanf(%q, %q): parsed value %T(%#v), want %T(%#v)", test.text, test.format, val, val, test.out, test.out)
574 func TestScanOverflow(t *testing.T) {
575 // different machines and different types report errors with different strings.
576 re := regexp.MustCompile("overflow|too large|out of range|not representable")
577 for _, test := range overflowTests {
578 _, err := Sscan(test.text, test.in)
579 if err == nil {
580 t.Errorf("expected overflow scanning %q", test.text)
581 continue
583 if !re.MatchString(err.Error()) {
584 t.Errorf("expected overflow error scanning %q: %s", test.text, err)
589 func verifyNaN(str string, t *testing.T) {
590 var f float64
591 var f32 float32
592 var f64 float64
593 text := str + " " + str + " " + str
594 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
595 if err != nil {
596 t.Errorf("got error scanning %q: %s", text, err)
598 if n != 3 {
599 t.Errorf("count error scanning %q: got %d", text, n)
601 if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) {
602 t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64)
606 func TestNaN(t *testing.T) {
607 for _, s := range []string{"nan", "NAN", "NaN"} {
608 verifyNaN(s, t)
612 func verifyInf(str string, t *testing.T) {
613 var f float64
614 var f32 float32
615 var f64 float64
616 text := str + " " + str + " " + str
617 n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
618 if err != nil {
619 t.Errorf("got error scanning %q: %s", text, err)
621 if n != 3 {
622 t.Errorf("count error scanning %q: got %d", text, n)
624 sign := 1
625 if str[0] == '-' {
626 sign = -1
628 if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) {
629 t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64)
633 func TestInf(t *testing.T) {
634 for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
635 verifyInf(s, t)
639 func testScanfMulti(t *testing.T, f func(string) io.Reader) {
640 sliceType := reflect.TypeOf(make([]any, 1))
641 for _, test := range multiTests {
642 r := f(test.text)
643 n, err := Fscanf(r, test.format, test.in...)
644 if err != nil {
645 if test.err == "" {
646 t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err)
647 } else if !strings.Contains(err.Error(), test.err) {
648 t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
650 continue
652 if test.err != "" {
653 t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text)
655 if n != len(test.out) {
656 t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n)
657 continue
659 // Convert the slice of pointers into a slice of values
660 resultVal := reflect.MakeSlice(sliceType, n, n)
661 for i := 0; i < n; i++ {
662 v := reflect.ValueOf(test.in[i]).Elem()
663 resultVal.Index(i).Set(v)
665 result := resultVal.Interface()
666 if !reflect.DeepEqual(result, test.out) {
667 t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result)
672 func TestScanfMulti(t *testing.T) {
673 for _, r := range readers {
674 t.Run(r.name, func(t *testing.T) {
675 testScanfMulti(t, r.f)
680 func TestScanMultiple(t *testing.T) {
681 var a int
682 var s string
683 n, err := Sscan("123abc", &a, &s)
684 if n != 2 {
685 t.Errorf("Sscan count error: expected 2: got %d", n)
687 if err != nil {
688 t.Errorf("Sscan expected no error; got %s", err)
690 if a != 123 || s != "abc" {
691 t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s)
693 n, err = Sscan("asdf", &s, &a)
694 if n != 1 {
695 t.Errorf("Sscan count error: expected 1: got %d", n)
697 if err == nil {
698 t.Errorf("Sscan expected error; got none: %s", err)
700 if s != "asdf" {
701 t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s)
705 // Empty strings are not valid input when scanning a string.
706 func TestScanEmpty(t *testing.T) {
707 var s1, s2 string
708 n, err := Sscan("abc", &s1, &s2)
709 if n != 1 {
710 t.Errorf("Sscan count error: expected 1: got %d", n)
712 if err == nil {
713 t.Error("Sscan <one item> expected error; got none")
715 if s1 != "abc" {
716 t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1)
718 n, err = Sscan("", &s1, &s2)
719 if n != 0 {
720 t.Errorf("Sscan count error: expected 0: got %d", n)
722 if err == nil {
723 t.Error("Sscan <empty> expected error; got none")
725 // Quoted empty string is OK.
726 n, err = Sscanf(`""`, "%q", &s1)
727 if n != 1 {
728 t.Errorf("Sscanf count error: expected 1: got %d", n)
730 if err != nil {
731 t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err)
735 func TestScanNotPointer(t *testing.T) {
736 r := strings.NewReader("1")
737 var a int
738 _, err := Fscan(r, a)
739 if err == nil {
740 t.Error("expected error scanning non-pointer")
741 } else if !strings.Contains(err.Error(), "pointer") {
742 t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
746 func TestScanlnNoNewline(t *testing.T) {
747 var a int
748 _, err := Sscanln("1 x\n", &a)
749 if err == nil {
750 t.Error("expected error scanning string missing newline")
751 } else if !strings.Contains(err.Error(), "newline") {
752 t.Errorf("expected newline error scanning string missing newline, got: %s", err)
756 func TestScanlnWithMiddleNewline(t *testing.T) {
757 r := strings.NewReader("123\n456\n")
758 var a, b int
759 _, err := Fscanln(r, &a, &b)
760 if err == nil {
761 t.Error("expected error scanning string with extra newline")
762 } else if !strings.Contains(err.Error(), "newline") {
763 t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
767 // eofCounter is a special Reader that counts reads at end of file.
768 type eofCounter struct {
769 reader *strings.Reader
770 eofCount int
773 func (ec *eofCounter) Read(b []byte) (n int, err error) {
774 n, err = ec.reader.Read(b)
775 if n == 0 {
776 ec.eofCount++
778 return
781 // TestEOF verifies that when we scan, we see at most EOF once per call to a
782 // Scan function, and then only when it's really an EOF.
783 func TestEOF(t *testing.T) {
784 ec := &eofCounter{strings.NewReader("123\n"), 0}
785 var a int
786 n, err := Fscanln(ec, &a)
787 if err != nil {
788 t.Error("unexpected error", err)
790 if n != 1 {
791 t.Error("expected to scan one item, got", n)
793 if ec.eofCount != 0 {
794 t.Error("expected zero EOFs", ec.eofCount)
795 ec.eofCount = 0 // reset for next test
797 n, err = Fscanln(ec, &a)
798 if err == nil {
799 t.Error("expected error scanning empty string")
801 if n != 0 {
802 t.Error("expected to scan zero items, got", n)
804 if ec.eofCount != 1 {
805 t.Error("expected one EOF, got", ec.eofCount)
809 // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
810 // This was a buglet: we used to get "expected integer".
811 func TestEOFAtEndOfInput(t *testing.T) {
812 var i, j int
813 n, err := Sscanf("23", "%d %d", &i, &j)
814 if n != 1 || i != 23 {
815 t.Errorf("Sscanf expected one value of 23; got %d %d", n, i)
817 if err != io.EOF {
818 t.Errorf("Sscanf expected EOF; got %q", err)
820 n, err = Sscan("234", &i, &j)
821 if n != 1 || i != 234 {
822 t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
824 if err != io.EOF {
825 t.Errorf("Sscan expected EOF; got %q", err)
827 // Trailing space is tougher.
828 n, err = Sscan("234 ", &i, &j)
829 if n != 1 || i != 234 {
830 t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
832 if err != io.EOF {
833 t.Errorf("Sscan expected EOF; got %q", err)
837 var eofTests = []struct {
838 format string
839 v any
841 {"%s", &stringVal},
842 {"%q", &stringVal},
843 {"%x", &stringVal},
844 {"%v", &stringVal},
845 {"%v", &bytesVal},
846 {"%v", &intVal},
847 {"%v", &uintVal},
848 {"%v", &boolVal},
849 {"%v", &float32Val},
850 {"%v", &complex64Val},
851 {"%v", &renamedStringVal},
852 {"%v", &renamedBytesVal},
853 {"%v", &renamedIntVal},
854 {"%v", &renamedUintVal},
855 {"%v", &renamedBoolVal},
856 {"%v", &renamedFloat32Val},
857 {"%v", &renamedComplex64Val},
860 func TestEOFAllTypes(t *testing.T) {
861 for i, test := range eofTests {
862 if _, err := Sscanf("", test.format, test.v); err != io.EOF {
863 t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err)
865 if _, err := Sscanf(" ", test.format, test.v); err != io.EOF {
866 t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err)
871 // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
872 // calls to Fscan do not lose runes.
873 func TestUnreadRuneWithBufio(t *testing.T) {
874 r := bufio.NewReader(strings.NewReader("123αb"))
875 var i int
876 var a string
877 n, err := Fscanf(r, "%d", &i)
878 if n != 1 || err != nil {
879 t.Errorf("reading int expected one item, no errors; got %d %q", n, err)
881 if i != 123 {
882 t.Errorf("expected 123; got %d", i)
884 n, err = Fscanf(r, "%s", &a)
885 if n != 1 || err != nil {
886 t.Errorf("reading string expected one item, no errors; got %d %q", n, err)
888 if a != "αb" {
889 t.Errorf("expected αb; got %q", a)
893 type TwoLines string
895 // Scan attempts to read two lines into the object. Scanln should prevent this
896 // because it stops at newline; Scan and Scanf should be fine.
897 func (t *TwoLines) Scan(state ScanState, verb rune) error {
898 chars := make([]rune, 0, 100)
899 for nlCount := 0; nlCount < 2; {
900 c, _, err := state.ReadRune()
901 if err != nil {
902 return err
904 chars = append(chars, c)
905 if c == '\n' {
906 nlCount++
909 *t = TwoLines(string(chars))
910 return nil
913 func TestMultiLine(t *testing.T) {
914 input := "abc\ndef\n"
915 // Sscan should work
916 var tscan TwoLines
917 n, err := Sscan(input, &tscan)
918 if n != 1 {
919 t.Errorf("Sscan: expected 1 item; got %d", n)
921 if err != nil {
922 t.Errorf("Sscan: expected no error; got %s", err)
924 if string(tscan) != input {
925 t.Errorf("Sscan: expected %q; got %q", input, tscan)
927 // Sscanf should work
928 var tscanf TwoLines
929 n, err = Sscanf(input, "%s", &tscanf)
930 if n != 1 {
931 t.Errorf("Sscanf: expected 1 item; got %d", n)
933 if err != nil {
934 t.Errorf("Sscanf: expected no error; got %s", err)
936 if string(tscanf) != input {
937 t.Errorf("Sscanf: expected %q; got %q", input, tscanf)
939 // Sscanln should not work
940 var tscanln TwoLines
941 n, err = Sscanln(input, &tscanln)
942 if n != 0 {
943 t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln)
945 if err == nil {
946 t.Error("Sscanln: expected error; got none")
947 } else if err != io.ErrUnexpectedEOF {
948 t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err)
952 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
953 // 3481.
954 func TestLineByLineFscanf(t *testing.T) {
955 r := struct{ io.Reader }{strings.NewReader("1\n2\n")}
956 var i, j int
957 n, err := Fscanf(r, "%v\n", &i)
958 if n != 1 || err != nil {
959 t.Fatalf("first read: %d %q", n, err)
961 n, err = Fscanf(r, "%v\n", &j)
962 if n != 1 || err != nil {
963 t.Fatalf("second read: %d %q", n, err)
965 if i != 1 || j != 2 {
966 t.Errorf("wrong values; wanted 1 2 got %d %d", i, j)
970 // TestScanStateCount verifies the correct byte count is returned. Issue 8512.
972 // runeScanner implements the Scanner interface for TestScanStateCount.
973 type runeScanner struct {
974 rune rune
975 size int
978 func (rs *runeScanner) Scan(state ScanState, verb rune) error {
979 r, size, err := state.ReadRune()
980 rs.rune = r
981 rs.size = size
982 return err
985 func TestScanStateCount(t *testing.T) {
986 var a, b, c runeScanner
987 n, err := Sscanf("12âž‚", "%c%c%c", &a, &b, &c)
988 if err != nil {
989 t.Fatal(err)
991 if n != 3 {
992 t.Fatalf("expected 3 items consumed, got %d", n)
994 if a.rune != '1' || b.rune != '2' || c.rune != 'âž‚' {
995 t.Errorf("bad scan rune: %q %q %q should be '1' '2' 'âž‚'", a.rune, b.rune, c.rune)
997 if a.size != 1 || b.size != 1 || c.size != 3 {
998 t.Errorf("bad scan size: %q %q %q should be 1 1 3", a.size, b.size, c.size)
1002 // RecursiveInt accepts a string matching %d.%d.%d....
1003 // and parses it into a linked list.
1004 // It allows us to benchmark recursive descent style scanners.
1005 type RecursiveInt struct {
1006 i int
1007 next *RecursiveInt
1010 func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
1011 _, err = Fscan(state, &r.i)
1012 if err != nil {
1013 return
1015 next := new(RecursiveInt)
1016 _, err = Fscanf(state, ".%v", next)
1017 if err != nil {
1018 if err == io.ErrUnexpectedEOF {
1019 err = nil
1021 return
1023 r.next = next
1024 return
1027 // scanInts performs the same scanning task as RecursiveInt.Scan
1028 // but without recurring through scanner, so we can compare
1029 // performance more directly.
1030 func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) {
1031 r.next = nil
1032 _, err = Fscan(b, &r.i)
1033 if err != nil {
1034 return
1036 c, _, err := b.ReadRune()
1037 if err != nil {
1038 if err == io.EOF {
1039 err = nil
1041 return
1043 if c != '.' {
1044 return
1046 next := new(RecursiveInt)
1047 err = scanInts(next, b)
1048 if err == nil {
1049 r.next = next
1051 return
1054 func makeInts(n int) []byte {
1055 var buf bytes.Buffer
1056 Fprintf(&buf, "1")
1057 for i := 1; i < n; i++ {
1058 Fprintf(&buf, ".%d", i+1)
1060 return buf.Bytes()
1063 func TestScanInts(t *testing.T) {
1064 testScanInts(t, scanInts)
1065 testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) {
1066 _, err = Fscan(b, r)
1067 return
1071 // 800 is small enough to not overflow the stack when using gccgo on a
1072 // platform that does not support split stack.
1073 const intCount = 800
1075 func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) {
1076 r := new(RecursiveInt)
1077 ints := makeInts(intCount)
1078 buf := bytes.NewBuffer(ints)
1079 err := scan(r, buf)
1080 if err != nil {
1081 t.Error("unexpected error", err)
1083 i := 1
1084 for ; r != nil; r = r.next {
1085 if r.i != i {
1086 t.Fatalf("bad scan: expected %d got %d", i, r.i)
1090 if i-1 != intCount {
1091 t.Fatalf("bad scan count: expected %d got %d", intCount, i-1)
1095 func BenchmarkScanInts(b *testing.B) {
1096 b.ResetTimer()
1097 ints := makeInts(intCount)
1098 var r RecursiveInt
1099 for i := b.N - 1; i >= 0; i-- {
1100 buf := bytes.NewBuffer(ints)
1101 b.StartTimer()
1102 scanInts(&r, buf)
1103 b.StopTimer()
1107 func BenchmarkScanRecursiveInt(b *testing.B) {
1108 b.ResetTimer()
1109 ints := makeInts(intCount)
1110 var r RecursiveInt
1111 for i := b.N - 1; i >= 0; i-- {
1112 buf := bytes.NewBuffer(ints)
1113 b.StartTimer()
1114 Fscan(buf, &r)
1115 b.StopTimer()
1119 func BenchmarkScanRecursiveIntReaderWrapper(b *testing.B) {
1120 b.ResetTimer()
1121 ints := makeInts(intCount)
1122 var r RecursiveInt
1123 for i := b.N - 1; i >= 0; i-- {
1124 buf := struct{ io.Reader }{strings.NewReader(string(ints))}
1125 b.StartTimer()
1126 Fscan(buf, &r)
1127 b.StopTimer()
1131 // Issue 9124.
1132 // %x on bytes couldn't handle non-space bytes terminating the scan.
1133 func TestHexBytes(t *testing.T) {
1134 var a, b []byte
1135 n, err := Sscanf("00010203", "%x", &a)
1136 if n != 1 || err != nil {
1137 t.Errorf("simple: got count, err = %d, %v; expected 1, nil", n, err)
1139 check := func(msg string, x []byte) {
1140 if len(x) != 4 {
1141 t.Errorf("%s: bad length %d", msg, len(x))
1143 for i, b := range x {
1144 if int(b) != i {
1145 t.Errorf("%s: bad x[%d] = %x", msg, i, x[i])
1149 check("simple", a)
1150 a = nil
1152 n, err = Sscanf("00010203 00010203", "%x %x", &a, &b)
1153 if n != 2 || err != nil {
1154 t.Errorf("simple pair: got count, err = %d, %v; expected 2, nil", n, err)
1156 check("simple pair a", a)
1157 check("simple pair b", b)
1158 a = nil
1159 b = nil
1161 n, err = Sscanf("00010203:", "%x", &a)
1162 if n != 1 || err != nil {
1163 t.Errorf("colon: got count, err = %d, %v; expected 1, nil", n, err)
1165 check("colon", a)
1166 a = nil
1168 n, err = Sscanf("00010203:00010203", "%x:%x", &a, &b)
1169 if n != 2 || err != nil {
1170 t.Errorf("colon pair: got count, err = %d, %v; expected 2, nil", n, err)
1172 check("colon pair a", a)
1173 check("colon pair b", b)
1174 a = nil
1175 b = nil
1177 // This one fails because there is a hex byte after the data,
1178 // that is, an odd number of hex input bytes.
1179 n, err = Sscanf("000102034:", "%x", &a)
1180 if n != 0 || err == nil {
1181 t.Errorf("odd count: got count, err = %d, %v; expected 0, error", n, err)
1185 func TestScanNewlinesAreSpaces(t *testing.T) {
1186 var a, b int
1187 var tests = []struct {
1188 name string
1189 text string
1190 count int
1192 {"newlines", "1\n2\n", 2},
1193 {"no final newline", "1\n2", 2},
1194 {"newlines with spaces ", "1 \n 2 \n", 2},
1195 {"no final newline with spaces", "1 \n 2", 2},
1197 for _, test := range tests {
1198 n, err := Sscan(test.text, &a, &b)
1199 if n != test.count {
1200 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
1202 if err != nil {
1203 t.Errorf("%s: unexpected error: %s", test.name, err)
1208 func TestScanlnNewlinesTerminate(t *testing.T) {
1209 var a, b int
1210 var tests = []struct {
1211 name string
1212 text string
1213 count int
1214 ok bool
1216 {"one line one item", "1\n", 1, false},
1217 {"one line two items with spaces ", " 1 2 \n", 2, true},
1218 {"one line two items no newline", " 1 2", 2, true},
1219 {"two lines two items", "1\n2\n", 1, false},
1221 for _, test := range tests {
1222 n, err := Sscanln(test.text, &a, &b)
1223 if n != test.count {
1224 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
1226 if test.ok && err != nil {
1227 t.Errorf("%s: unexpected error: %s", test.name, err)
1229 if !test.ok && err == nil {
1230 t.Errorf("%s: expected error; got none", test.name)
1235 func TestScanfNewlineMatchFormat(t *testing.T) {
1236 var a, b int
1237 var tests = []struct {
1238 name string
1239 text string
1240 format string
1241 count int
1242 ok bool
1244 {"newline in both", "1\n2", "%d\n%d\n", 2, true},
1245 {"newline in input", "1\n2", "%d %d", 1, false},
1246 {"space-newline in input", "1 \n2", "%d %d", 1, false},
1247 {"newline in format", "1 2", "%d\n%d", 1, false},
1248 {"space-newline in format", "1 2", "%d \n%d", 1, false},
1249 {"space-newline in both", "1 \n2", "%d \n%d", 2, true},
1250 {"extra space in format", "1\n2", "%d\n %d", 2, true},
1251 {"two extra spaces in format", "1\n2", "%d \n %d", 2, true},
1252 {"space vs newline 0000", "1\n2", "%d\n%d", 2, true},
1253 {"space vs newline 0001", "1\n2", "%d\n %d", 2, true},
1254 {"space vs newline 0010", "1\n2", "%d \n%d", 2, true},
1255 {"space vs newline 0011", "1\n2", "%d \n %d", 2, true},
1256 {"space vs newline 0100", "1\n 2", "%d\n%d", 2, true},
1257 {"space vs newline 0101", "1\n 2", "%d\n%d ", 2, true},
1258 {"space vs newline 0110", "1\n 2", "%d \n%d", 2, true},
1259 {"space vs newline 0111", "1\n 2", "%d \n %d", 2, true},
1260 {"space vs newline 1000", "1 \n2", "%d\n%d", 2, true},
1261 {"space vs newline 1001", "1 \n2", "%d\n %d", 2, true},
1262 {"space vs newline 1010", "1 \n2", "%d \n%d", 2, true},
1263 {"space vs newline 1011", "1 \n2", "%d \n %d", 2, true},
1264 {"space vs newline 1100", "1 \n 2", "%d\n%d", 2, true},
1265 {"space vs newline 1101", "1 \n 2", "%d\n %d", 2, true},
1266 {"space vs newline 1110", "1 \n 2", "%d \n%d", 2, true},
1267 {"space vs newline 1111", "1 \n 2", "%d \n %d", 2, true},
1268 {"space vs newline no-percent 0000", "1\n2", "1\n2", 0, true},
1269 {"space vs newline no-percent 0001", "1\n2", "1\n 2", 0, true},
1270 {"space vs newline no-percent 0010", "1\n2", "1 \n2", 0, true},
1271 {"space vs newline no-percent 0011", "1\n2", "1 \n 2", 0, true},
1272 {"space vs newline no-percent 0100", "1\n 2", "1\n2", 0, false}, // fails: space after nl in input but not pattern
1273 {"space vs newline no-percent 0101", "1\n 2", "1\n2 ", 0, false}, // fails: space after nl in input but not pattern
1274 {"space vs newline no-percent 0110", "1\n 2", "1 \n2", 0, false}, // fails: space after nl in input but not pattern
1275 {"space vs newline no-percent 0111", "1\n 2", "1 \n 2", 0, true},
1276 {"space vs newline no-percent 1000", "1 \n2", "1\n2", 0, true},
1277 {"space vs newline no-percent 1001", "1 \n2", "1\n 2", 0, true},
1278 {"space vs newline no-percent 1010", "1 \n2", "1 \n2", 0, true},
1279 {"space vs newline no-percent 1011", "1 \n2", "1 \n 2", 0, true},
1280 {"space vs newline no-percent 1100", "1 \n 2", "1\n2", 0, false}, // fails: space after nl in input but not pattern
1281 {"space vs newline no-percent 1101", "1 \n 2", "1\n 2", 0, true},
1282 {"space vs newline no-percent 1110", "1 \n 2", "1 \n2", 0, false}, // fails: space after nl in input but not pattern
1283 {"space vs newline no-percent 1111", "1 \n 2", "1 \n 2", 0, true},
1285 for _, test := range tests {
1286 var n int
1287 var err error
1288 if strings.Contains(test.format, "%") {
1289 n, err = Sscanf(test.text, test.format, &a, &b)
1290 } else {
1291 n, err = Sscanf(test.text, test.format)
1293 if n != test.count {
1294 t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
1296 if test.ok && err != nil {
1297 t.Errorf("%s: unexpected error: %s", test.name, err)
1299 if !test.ok && err == nil {
1300 t.Errorf("%s: expected error; got none", test.name)
1305 // Test for issue 12090: Was unreading at EOF, double-scanning a byte.
1307 type hexBytes [2]byte
1309 func (h *hexBytes) Scan(ss ScanState, verb rune) error {
1310 var b []byte
1311 _, err := Fscanf(ss, "%4x", &b)
1312 if err != nil {
1313 panic(err) // Really shouldn't happen.
1315 copy((*h)[:], b)
1316 return err
1319 func TestHexByte(t *testing.T) {
1320 var h hexBytes
1321 n, err := Sscanln("0123\n", &h)
1322 if err != nil {
1323 t.Fatal(err)
1325 if n != 1 {
1326 t.Fatalf("expected 1 item; scanned %d", n)
1328 if h[0] != 0x01 || h[1] != 0x23 {
1329 t.Fatalf("expected 0123 got %x", h)