...

Source file src/fmt/scan_test.go

Documentation: fmt

     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  
     5  package fmt_test
     6  
     7  import (
     8  	"bufio"
     9  	"bytes"
    10  	"errors"
    11  	. "fmt"
    12  	"io"
    13  	"math"
    14  	"reflect"
    15  	"regexp"
    16  	"strings"
    17  	"testing"
    18  	"testing/iotest"
    19  	"unicode/utf8"
    20  )
    21  
    22  type ScanTest struct {
    23  	text string
    24  	in   any
    25  	out  any
    26  }
    27  
    28  type ScanfTest struct {
    29  	format string
    30  	text   string
    31  	in     any
    32  	out    any
    33  }
    34  
    35  type ScanfMultiTest struct {
    36  	format string
    37  	text   string
    38  	in     []any
    39  	out    []any
    40  	err    string
    41  }
    42  
    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  	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
    84  type Xs string
    85  
    86  func (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  
    99  var xVal Xs
   100  
   101  // IntString accepts an integer followed immediately by a string.
   102  // It tests the embedding of a scan within a scan.
   103  type IntString struct {
   104  	i int
   105  	s string
   106  }
   107  
   108  func (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  
   121  var intStringVal IntString
   122  
   123  var 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  
   221  var 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  
   426  var 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  
   440  var truth bool
   441  var i, j, k int
   442  var f float64
   443  var s, t string
   444  var c complex128
   445  var x, y Xs
   446  var z IntString
   447  var r1, r2, r3 rune
   448  
   449  var 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  
   486  var 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  
   504  func 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  
   532  func 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  
   540  func 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  
   548  func 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  
   577  func 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  
   592  func 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  
   609  func TestNaN(t *testing.T) {
   610  	for _, s := range []string{"nan", "NAN", "NaN"} {
   611  		verifyNaN(s, t)
   612  	}
   613  }
   614  
   615  func 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  
   636  func 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  
   642  func 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  
   675  func 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  
   683  func 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.
   709  func 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  
   738  func 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  
   749  func 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  
   759  func 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.
   771  type eofCounter struct {
   772  	reader   *strings.Reader
   773  	eofCount int
   774  }
   775  
   776  func (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.
   786  func 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".
   814  func 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  
   840  var 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  
   863  func 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.
   876  func 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  
   896  type 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.
   900  func (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  
   916  func 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.
   957  func 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.
   976  type runeScanner struct {
   977  	rune rune
   978  	size int
   979  }
   980  
   981  func (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  
   988  func 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.
  1008  type RecursiveInt struct {
  1009  	i    int
  1010  	next *RecursiveInt
  1011  }
  1012  
  1013  func (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.
  1033  func 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  
  1057  func 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  
  1066  func 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.
  1076  const intCount = 800
  1077  
  1078  func 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  
  1098  func 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  
  1110  func 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  
  1122  func 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.
  1136  func 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  
  1188  func 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  
  1211  func 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  
  1238  func 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  
  1310  type hexBytes [2]byte
  1311  
  1312  func (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  
  1322  func 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  

View as plain text