diff options
author | Rob Pike <r@golang.org> | 2010-06-03 17:03:22 -0700 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2010-06-03 17:03:22 -0700 |
commit | 0086eaafe84f703df233949a18f8e6c701f3e697 (patch) | |
tree | 926978a00e0dcfa72dae297f243c0ccf25e08e0f /src/pkg/fmt | |
parent | 0727ff6d82c3c31710070f890c45db15ca72332e (diff) | |
download | golang-0086eaafe84f703df233949a18f8e6c701f3e697.tar.gz |
fmt.Scan: %c
R=rsc
CC=golang-dev
http://codereview.appspot.com/1518042
Diffstat (limited to 'src/pkg/fmt')
-rw-r--r-- | src/pkg/fmt/scan.go | 17 | ||||
-rw-r--r-- | src/pkg/fmt/scan_test.go | 11 |
2 files changed, 23 insertions, 5 deletions
diff --git a/src/pkg/fmt/scan.go b/src/pkg/fmt/scan.go index 66c557750..92990b421 100644 --- a/src/pkg/fmt/scan.go +++ b/src/pkg/fmt/scan.go @@ -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) diff --git a/src/pkg/fmt/scan_test.go b/src/pkg/fmt/scan_test.go index fde3616be..0ed53e886 100644 --- a/src/pkg/fmt/scan_test.go +++ b/src/pkg/fmt/scan_test.go @@ -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)) { |