]> Cypherpunks repositories - gostls13.git/commitdiff
fmt.Scanf: handle trailing spaces.
authorRob Pike <r@golang.org>
Mon, 26 Jul 2010 23:38:35 +0000 (16:38 -0700)
committerRob Pike <r@golang.org>
Mon, 26 Jul 2010 23:38:35 +0000 (16:38 -0700)
Fixes #954.

R=rsc
CC=golang-dev
https://golang.org/cl/1864046

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

index ded1f771917f94f3cc172961cfcfcb6c591abb27..fad7dbf550482b8f00afe80ea37b6f8a210be8bf 100644 (file)
@@ -316,14 +316,17 @@ func (s *ss) free() {
        _ = ssFree <- s
 }
 
-// skipSpace skips spaces and maybe newlines
-func (s *ss) skipSpace() {
+// skipSpace skips spaces and maybe newlines.
+func (s *ss) skipSpace(stopAtNewline bool) {
        for {
                rune := s.getRune()
                if rune == EOF {
                        return
                }
                if rune == '\n' {
+                       if stopAtNewline {
+                               break
+                       }
                        if s.nlIsSpace {
                                continue
                        }
@@ -341,7 +344,7 @@ func (s *ss) skipSpace() {
 // skips white space.  For Scanln, it stops at newlines.  For Scan,
 // newlines are treated as spaces.
 func (s *ss) token() string {
-       s.skipSpace()
+       s.skipSpace(false)
        // read until white space or newline
        for nrunes := 0; !s.widPresent || nrunes < s.maxWid; nrunes++ {
                rune := s.getRune()
@@ -482,7 +485,7 @@ func (s *ss) scanInt(verb int, bitSize int) int64 {
                return s.scanRune(bitSize)
        }
        base, digits := s.getBase(verb)
-       s.skipSpace()
+       s.skipSpace(false)
        s.accept(sign) // If there's a sign, it will be left in the token buffer.
        tok := s.scanNumber(digits)
        i, err := strconv.Btoi64(tok, base)
@@ -504,7 +507,7 @@ func (s *ss) scanUint(verb int, bitSize int) uint64 {
                return uint64(s.scanRune(bitSize))
        }
        base, digits := s.getBase(verb)
-       s.skipSpace()
+       s.skipSpace(false)
        tok := s.scanNumber(digits)
        i, err := strconv.Btoui64(tok, base)
        if err != nil {
@@ -586,7 +589,7 @@ func (s *ss) scanComplex(verb int, n int) complex128 {
        if !s.okVerb(verb, floatVerbs, "complex") {
                return 0
        }
-       s.skipSpace()
+       s.skipSpace(false)
        sreal, simag := s.complexTokens()
        real := s.convertFloat(sreal, n/2)
        imag := s.convertFloat(simag, n/2)
@@ -599,7 +602,7 @@ func (s *ss) convertString(verb int) string {
        if !s.okVerb(verb, "svqx", "string") {
                return ""
        }
-       s.skipSpace()
+       s.skipSpace(false)
        switch verb {
        case 'q':
                return s.quotedString()
@@ -748,17 +751,17 @@ func (s *ss) scanOne(verb int, field interface{}) {
        // scan in high precision and convert, in order to preserve the correct error condition.
        case *float:
                if s.okVerb(verb, floatVerbs, "float") {
-                       s.skipSpace()
+                       s.skipSpace(false)
                        *v = float(s.convertFloat(s.floatToken(), int(floatBits)))
                }
        case *float32:
                if s.okVerb(verb, floatVerbs, "float32") {
-                       s.skipSpace()
+                       s.skipSpace(false)
                        *v = float32(s.convertFloat(s.floatToken(), 32))
                }
        case *float64:
                if s.okVerb(verb, floatVerbs, "float64") {
-                       s.skipSpace()
+                       s.skipSpace(false)
                        *v = s.convertFloat(s.floatToken(), 64)
                }
        case *string:
@@ -795,7 +798,7 @@ func (s *ss) scanOne(verb int, field interface{}) {
                                v.Elem(i).(*reflect.UintValue).Set(uint64(str[i]))
                        }
                case *reflect.FloatValue:
-                       s.skipSpace()
+                       s.skipSpace(false)
                        v.Set(s.convertFloat(s.floatToken(), v.Type().Bits()))
                case *reflect.ComplexValue:
                        v.Set(s.scanComplex(verb, v.Type().Bits()))
@@ -878,7 +881,7 @@ func (s *ss) advance(format string) (i int) {
                                // Space in format but not in input: error
                                s.errorString("expected space in input to match format")
                        }
-                       s.skipSpace()
+                       s.skipSpace(true)
                        continue
                }
                inputc := s.mustGetRune()
index 1e0319836c48fc1ffe11e9b5435bbc42ba8f1d11..05112438d5f00065ecf2f6f82981b87de8e8d61b 100644 (file)
@@ -259,6 +259,10 @@ var scanfTests = []ScanfTest{
        // Custom scanner.
        ScanfTest{"%s", "  sss ", &xVal, Xs("sss")},
        ScanfTest{"%2s", "sssss", &xVal, Xs("ss")},
+
+       // Fixed bugs
+       ScanfTest{"%d\n", "27\n", &intVal, 27},  // ok
+       ScanfTest{"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
 }
 
 var overflowTests = []ScanTest{