Black Lives Matter. Support the Equal Justice Initiative.

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

View as plain text