diff options
Diffstat (limited to 'libgo/go/fmt/scan.go')
-rw-r--r-- | libgo/go/fmt/scan.go | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go index 41a12d9957d..ebbb17155e4 100644 --- a/libgo/go/fmt/scan.go +++ b/libgo/go/fmt/scan.go @@ -388,9 +388,9 @@ func (s *ss) typeError(field interface{}, expected string) { var complexError = os.ErrorString("syntax error scanning complex number") var boolError = os.ErrorString("syntax error scanning boolean") -// accepts checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the -// buffer and returns true. Otherwise it return false. -func (s *ss) accept(ok string) bool { +// consume reads the next rune in the input and reports whether it is in the ok string. +// If accept is true, it puts the character into the input token. +func (s *ss) consume(ok string, accept bool) bool { if s.wid >= s.maxWid { return false } @@ -400,17 +400,25 @@ func (s *ss) accept(ok string) bool { } for i := 0; i < len(ok); i++ { if int(ok[i]) == rune { - s.buf.WriteRune(rune) - s.wid++ + if accept { + s.buf.WriteRune(rune) + s.wid++ + } return true } } - if rune != EOF { + if rune != EOF && accept { s.UngetRune() } return false } +// accept checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the +// buffer and returns true. Otherwise it return false. +func (s *ss) accept(ok string) bool { + return s.consume(ok, true) +} + // okVerb verifies that the verb is present in the list, setting s.err appropriately if not. func (s *ss) okVerb(verb int, okVerbs, typ string) bool { for _, v := range okVerbs { @@ -460,7 +468,7 @@ const ( // getBase returns the numeric base represented by the verb and its digit string. func (s *ss) getBase(verb int) (base int, digits string) { - s.okVerb(verb, "bdoxXv", "integer") // sets s.err + s.okVerb(verb, "bdoUxXv", "integer") // sets s.err base = 10 digits = decimalDigits switch verb { @@ -470,7 +478,7 @@ func (s *ss) getBase(verb int) (base int, digits string) { case 'o': base = 8 digits = octalDigits - case 'x', 'X': + case 'x', 'X', 'U': base = 16 digits = hexadecimalDigits } @@ -506,7 +514,13 @@ func (s *ss) scanInt(verb int, bitSize int) int64 { } base, digits := s.getBase(verb) s.skipSpace(false) - s.accept(sign) // If there's a sign, it will be left in the token buffer. + if verb == 'U' { + if !s.consume("U", false) || !s.consume("+", false) { + s.errorString("bad unicode format ") + } + } else { + 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) if err != nil { @@ -528,6 +542,11 @@ func (s *ss) scanUint(verb int, bitSize int) uint64 { } base, digits := s.getBase(verb) s.skipSpace(false) + if verb == 'U' { + if !s.consume("U", false) || !s.consume("+", false) { + s.errorString("bad unicode format ") + } + } tok := s.scanNumber(digits) i, err := strconv.Btoui64(tok, base) if err != nil { @@ -546,8 +565,16 @@ func (s *ss) scanUint(verb int, bitSize int) uint64 { // we have at least some digits, but Atof will do that. func (s *ss) floatToken() string { s.buf.Reset() + // NaN? + if s.accept("nN") && s.accept("aA") && s.accept("nN") { + return s.buf.String() + } // leading sign? s.accept(sign) + // Inf? + if s.accept("iI") && s.accept("nN") && s.accept("fF") { + return s.buf.String() + } // digits? for s.accept(decimalDigits) { } @@ -613,7 +640,7 @@ func (s *ss) scanComplex(verb int, n int) complex128 { sreal, simag := s.complexTokens() real := s.convertFloat(sreal, n/2) imag := s.convertFloat(simag, n/2) - return cmplx(real, imag) + return complex(real, imag) } // convertString returns the string represented by the next input characters. @@ -745,8 +772,6 @@ func (s *ss) scanOne(verb int, field interface{}) { switch v := field.(type) { case *bool: *v = s.scanBool(verb) - case *complex: - *v = complex(s.scanComplex(verb, int(complexBits))) case *complex64: *v = complex64(s.scanComplex(verb, 64)) case *complex128: @@ -775,11 +800,6 @@ func (s *ss) scanOne(verb int, field interface{}) { *v = uintptr(s.scanUint(verb, uintptrBits)) // Floats are tricky because you want to scan in the precision of the result, not // scan in high precision and convert, in order to preserve the correct error condition. - case *float: - if s.okVerb(verb, floatVerbs, "float") { - s.skipSpace(false) - *v = float(s.convertFloat(s.floatToken(), int(floatBits))) - } case *float32: if s.okVerb(verb, floatVerbs, "float32") { s.skipSpace(false) |