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