]> Cypherpunks repositories - gostls13.git/commitdiff
fmt.Scan: %c
authorRob Pike <r@golang.org>
Fri, 4 Jun 2010 00:03:22 +0000 (17:03 -0700)
committerRob Pike <r@golang.org>
Fri, 4 Jun 2010 00:03:22 +0000 (17:03 -0700)
R=rsc
CC=golang-dev
https://golang.org/cl/1518042

src/pkg/fmt/scan.go
src/pkg/fmt/scan_test.go

index 66c5577501152174aab9d6df4569386cd04555c3..92990b421c21399febc32d151fff1eee1d2806d0 100644 (file)
@@ -219,7 +219,6 @@ func (s *ss) Token() (tok string, err os.Error) {
 // readRune is a structure to enable reading UTF-8 encoded code points
 // from an io.Reader.  It is used if the Reader given to the scanner does
 // not already implement ReadRuner.
-// TODO: readByteRune for things that can read bytes.
 type readRune struct {
        reader io.Reader
        buf    [utf8.UTFMax]byte
@@ -435,9 +434,22 @@ func (s *ss) scanNumber(digits string) string {
        return s.buf.String()
 }
 
+// scanRune returns the next rune value in the input.
+func (s *ss) scanRune(bitSize uint) int64 {
+       rune := int64(s.mustGetRune())
+       x := (rune << (64 - bitSize)) >> (64 - bitSize)
+       if x != rune {
+               s.errorString("overflow on character value " + string(rune))
+       }
+       return rune
+}
+
 // scanInt returns the value of the integer represented by the next
 // token, checking for overflow.  Any error is stored in s.err.
 func (s *ss) scanInt(verb int, bitSize uint) int64 {
+       if verb == 'c' {
+               return s.scanRune(bitSize)
+       }
        base, digits := s.getBase(verb)
        s.skipSpace()
        s.accept(sign) // If there's a sign, it will be left in the token buffer.
@@ -456,6 +468,9 @@ func (s *ss) scanInt(verb int, bitSize uint) int64 {
 // scanUint returns the value of the unsigned integer represented
 // by the next token, checking for overflow.  Any error is stored in s.err.
 func (s *ss) scanUint(verb int, bitSize uint) uint64 {
+       if verb == 'c' {
+               return uint64(s.scanRune(bitSize))
+       }
        base, digits := s.getBase(verb)
        s.skipSpace()
        tok := s.scanNumber(digits)
index fde3616beab14b3314e75aaab919a22d4070bd68..0ed53e886042efaf8c97afdde14af25de905331e 100644 (file)
@@ -198,6 +198,8 @@ var scanfTests = []ScanfTest{
        ScanfTest{"%t", "false\n", &boolVal, false},
        ScanfTest{"%v", "-71\n", &intVal, -71},
        ScanfTest{"%d", "72\n", &intVal, 72},
+       ScanfTest{"%c", "a\n", &intVal, 'a'},
+       ScanfTest{"%c", "\u1234\n", &intVal, '\u1234'},
        ScanfTest{"%d", "73\n", &int8Val, int8(73)},
        ScanfTest{"%d", "+74\n", &int16Val, int16(74)},
        ScanfTest{"%d", "75\n", &int32Val, int32(75)},
@@ -299,12 +301,13 @@ var multiTests = []ScanfMultiTest{
        ScanfMultiTest{"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
 
        // Custom scanner.
-       ScanfMultiTest{"%2e%f", "eefffff", []interface{}{&x, &y}, []interface{}{Xs("ee"), Xs("fffff")}, ""},
+       ScanfMultiTest{"%2e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
 
        // Errors
-       ScanfMultiTest{"%t", "23 18", []interface{}{&i}, nil, "bad verb"},
-       ScanfMultiTest{"%d %d %d", "23 18", []interface{}{&i, &j}, []interface{}{23, 18}, "too few operands"},
-       ScanfMultiTest{"%d %d", "23 18 27", []interface{}{&i, &j, &k}, []interface{}{23, 18}, "too many operands"},
+       ScanfMultiTest{"%t", "23 18", args(&i), nil, "bad verb"},
+       ScanfMultiTest{"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"},
+       ScanfMultiTest{"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"},
+       ScanfMultiTest{"%c", "\u0100", args(&int8Val), nil, "overflow"},
 }
 
 func testScan(t *testing.T, scan func(r io.Reader, a ...interface{}) (int, os.Error)) {