github.com/letsencrypt/go@v0.0.0-20160714163537-4054769a31f6/src/fmt/scan_test.go (about)

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