aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/fmt/scan.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/fmt/scan.go')
-rw-r--r--libgo/go/fmt/scan.go70
1 files changed, 47 insertions, 23 deletions
diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go
index ae79e39..74ada20 100644
--- a/libgo/go/fmt/scan.go
+++ b/libgo/go/fmt/scan.go
@@ -457,7 +457,7 @@ func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
s.UnreadRune()
break
}
- s.buf.WriteRune(r)
+ s.buf.writeRune(r)
}
return s.buf
}
@@ -483,7 +483,7 @@ func (s *ss) consume(ok string, accept bool) bool {
}
if indexRune(ok, r) >= 0 {
if accept {
- s.buf.WriteRune(r)
+ s.buf.writeRune(r)
}
return true
}
@@ -562,7 +562,7 @@ const (
hexadecimalDigits = "0123456789aAbBcCdDeEfF"
sign = "+-"
period = "."
- exponent = "eEp"
+ exponent = "eEpP"
)
// getBase returns the numeric base represented by the verb and its digit string.
@@ -609,22 +609,28 @@ func (s *ss) scanRune(bitSize int) int64 {
return r
}
-// scanBasePrefix reports whether the integer begins with a 0 or 0x,
+// scanBasePrefix reports whether the integer begins with a bas prefix
// and returns the base, digit string, and whether a zero was found.
// It is called only if the verb is %v.
-func (s *ss) scanBasePrefix() (base int, digits string, found bool) {
+func (s *ss) scanBasePrefix() (base int, digits string, zeroFound bool) {
if !s.peek("0") {
- return 10, decimalDigits, false
+ return 0, decimalDigits + "_", false
}
s.accept("0")
- found = true // We've put a digit into the token buffer.
- // Special cases for '0' && '0x'
- base, digits = 8, octalDigits
- if s.peek("xX") {
- s.consume("xX", false)
- base, digits = 16, hexadecimalDigits
+ // Special cases for 0, 0b, 0o, 0x.
+ switch {
+ case s.peek("bB"):
+ s.consume("bB", true)
+ return 0, binaryDigits + "_", true
+ case s.peek("oO"):
+ s.consume("oO", true)
+ return 0, octalDigits + "_", true
+ case s.peek("xX"):
+ s.consume("xX", true)
+ return 0, hexadecimalDigits + "_", true
+ default:
+ return 0, octalDigits + "_", true
}
- return
}
// scanInt returns the value of the integer represented by the next
@@ -705,21 +711,27 @@ func (s *ss) floatToken() string {
if s.accept("iI") && s.accept("nN") && s.accept("fF") {
return string(s.buf)
}
+ digits := decimalDigits + "_"
+ exp := exponent
+ if s.accept("0") && s.accept("xX") {
+ digits = hexadecimalDigits + "_"
+ exp = "pP"
+ }
// digits?
- for s.accept(decimalDigits) {
+ for s.accept(digits) {
}
// decimal point?
if s.accept(period) {
// fraction?
- for s.accept(decimalDigits) {
+ for s.accept(digits) {
}
}
// exponent?
- if s.accept(exponent) {
+ if s.accept(exp) {
// leading sign?
s.accept(sign)
// digits?
- for s.accept(decimalDigits) {
+ for s.accept(decimalDigits + "_") {
}
}
return string(s.buf)
@@ -749,9 +761,21 @@ func (s *ss) complexTokens() (real, imag string) {
return real, imagSign + imag
}
+func hasX(s string) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] == 'x' || s[i] == 'X' {
+ return true
+ }
+ }
+ return false
+}
+
// convertFloat converts the string to a float64value.
func (s *ss) convertFloat(str string, n int) float64 {
- if p := indexRune(str, 'p'); p >= 0 {
+ // strconv.ParseFloat will handle "+0x1.fp+2",
+ // but we have to implement our non-standard
+ // decimal+binary exponent mix (1.2p4) ourselves.
+ if p := indexRune(str, 'p'); p >= 0 && !hasX(str) {
// Atof doesn't handle power-of-2 exponents,
// but they're easy to evaluate.
f, err := strconv.ParseFloat(str[:p], n)
@@ -826,20 +850,20 @@ func (s *ss) quotedString() string {
if r == quote {
break
}
- s.buf.WriteRune(r)
+ s.buf.writeRune(r)
}
return string(s.buf)
case '"':
// Double-quoted: Include the quotes and let strconv.Unquote do the backslash escapes.
- s.buf.WriteByte('"')
+ s.buf.writeByte('"')
for {
r := s.mustReadRune()
- s.buf.WriteRune(r)
+ s.buf.writeRune(r)
if r == '\\' {
// In a legal backslash escape, no matter how long, only the character
// immediately after the escape can itself be a backslash or quote.
// Thus we only need to protect the first character after the backslash.
- s.buf.WriteRune(s.mustReadRune())
+ s.buf.writeRune(s.mustReadRune())
} else if r == '"' {
break
}
@@ -898,7 +922,7 @@ func (s *ss) hexString() string {
if !ok {
break
}
- s.buf.WriteByte(b)
+ s.buf.writeByte(b)
}
if len(s.buf) == 0 {
s.errorString("no hex data for %x string")