aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/fmt/format.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-07-22 18:15:38 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-07-22 18:15:38 +0000
commit22b955cca564a9a3a5b8c9d9dd1e295b7943c128 (patch)
treeabdbd898676e1f853fca2d7e031d105d7ebcf676 /libgo/go/fmt/format.go
parent9d04a3af4c6491536badf6bde9707c907e4d196b (diff)
downloadgcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.zip
gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.tar.gz
gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.tar.bz2
libgo: update to go1.7rc3
Reviewed-on: https://go-review.googlesource.com/25150 From-SVN: r238662
Diffstat (limited to 'libgo/go/fmt/format.go')
-rw-r--r--libgo/go/fmt/format.go593
1 files changed, 278 insertions, 315 deletions
diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go
index 517b18f..0236475 100644
--- a/libgo/go/fmt/format.go
+++ b/libgo/go/fmt/format.go
@@ -5,18 +5,13 @@
package fmt
import (
- "math"
"strconv"
"unicode/utf8"
)
const (
- // %b of an int64, plus a sign.
- // Hex can add 0x and we handle it specially.
- nByte = 65
-
- ldigits = "0123456789abcdef"
- udigits = "0123456789ABCDEF"
+ ldigits = "0123456789abcdefx"
+ udigits = "0123456789ABCDEFX"
)
const (
@@ -24,16 +19,6 @@ const (
unsigned = false
)
-var padZeroBytes = make([]byte, nByte)
-var padSpaceBytes = make([]byte, nByte)
-
-func init() {
- for i := 0; i < nByte; i++ {
- padZeroBytes[i] = '0'
- padSpaceBytes[i] = ' '
- }
-}
-
// flags placed in a separate struct for easy clearing.
type fmtFlags struct {
widPresent bool
@@ -42,8 +27,6 @@ type fmtFlags struct {
plus bool
sharp bool
space bool
- unicode bool
- uniQuote bool // Use 'x'= prefix for %U if printable.
zero bool
// For the formats %+v %#v, we set the plusV/sharpV flags
@@ -56,12 +39,16 @@ type fmtFlags struct {
// A fmt is the raw formatter used by Printf etc.
// It prints into a buffer that must be set up separately.
type fmt struct {
- intbuf [nByte]byte
- buf *buffer
- // width, precision
- wid int
- prec int
+ buf *buffer
+
fmtFlags
+
+ wid int // width
+ prec int // precision
+
+ // intbuf is large enought to store %b of an int64 with a sign and
+ // avoids padding at the end of the struct on 32 bit architectures.
+ intbuf [68]byte
}
func (f *fmt) clearflags() {
@@ -73,176 +60,213 @@ func (f *fmt) init(buf *buffer) {
f.clearflags()
}
-// computePadding computes left and right padding widths (only one will be non-zero).
-func (f *fmt) computePadding(width int) (padding []byte, leftWidth, rightWidth int) {
- left := !f.minus
- w := f.wid
- if w < 0 {
- left = false
- w = -w
- }
- w -= width
- if w > 0 {
- if left && f.zero {
- return padZeroBytes, w, 0
- }
- if left {
- return padSpaceBytes, w, 0
- } else {
- // can't be zero padding on the right
- return padSpaceBytes, 0, w
- }
- }
- return
-}
-
// writePadding generates n bytes of padding.
-func (f *fmt) writePadding(n int, padding []byte) {
- for n > 0 {
- m := n
- if m > nByte {
- m = nByte
- }
- f.buf.Write(padding[0:m])
- n -= m
+func (f *fmt) writePadding(n int) {
+ if n <= 0 { // No padding bytes needed.
+ return
}
+ buf := *f.buf
+ oldLen := len(buf)
+ newLen := oldLen + n
+ // Make enough room for padding.
+ if newLen > cap(buf) {
+ buf = make(buffer, cap(buf)*2+n)
+ copy(buf, *f.buf)
+ }
+ // Decide which byte the padding should be filled with.
+ padByte := byte(' ')
+ if f.zero {
+ padByte = byte('0')
+ }
+ // Fill padding with padByte.
+ padding := buf[oldLen:newLen]
+ for i := range padding {
+ padding[i] = padByte
+ }
+ *f.buf = buf[:newLen]
}
-// pad appends b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus).
+// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
func (f *fmt) pad(b []byte) {
if !f.widPresent || f.wid == 0 {
f.buf.Write(b)
return
}
- padding, left, right := f.computePadding(utf8.RuneCount(b))
- if left > 0 {
- f.writePadding(left, padding)
- }
- f.buf.Write(b)
- if right > 0 {
- f.writePadding(right, padding)
+ width := f.wid - utf8.RuneCount(b)
+ if !f.minus {
+ // left padding
+ f.writePadding(width)
+ f.buf.Write(b)
+ } else {
+ // right padding
+ f.buf.Write(b)
+ f.writePadding(width)
}
}
-// padString appends s to buf, padded on left (w > 0) or right (w < 0 or f.minus).
+// padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
func (f *fmt) padString(s string) {
if !f.widPresent || f.wid == 0 {
f.buf.WriteString(s)
return
}
- padding, left, right := f.computePadding(utf8.RuneCountInString(s))
- if left > 0 {
- f.writePadding(left, padding)
- }
- f.buf.WriteString(s)
- if right > 0 {
- f.writePadding(right, padding)
+ width := f.wid - utf8.RuneCountInString(s)
+ if !f.minus {
+ // left padding
+ f.writePadding(width)
+ f.buf.WriteString(s)
+ } else {
+ // right padding
+ f.buf.WriteString(s)
+ f.writePadding(width)
}
}
-var (
- trueBytes = []byte("true")
- falseBytes = []byte("false")
-)
-
// fmt_boolean formats a boolean.
func (f *fmt) fmt_boolean(v bool) {
if v {
- f.pad(trueBytes)
+ f.padString("true")
} else {
- f.pad(falseBytes)
+ f.padString("false")
}
}
-// integer; interprets prec but not wid. Once formatted, result is sent to pad()
-// and then flags are cleared.
-func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
- // precision of 0 and value of 0 means "print nothing"
- if f.precPresent && f.prec == 0 && a == 0 {
- return
+// fmt_unicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'".
+func (f *fmt) fmt_unicode(u uint64) {
+ buf := f.intbuf[0:]
+
+ // With default precision set the maximum needed buf length is 18
+ // for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits
+ // into the already allocated intbuf with a capacity of 68 bytes.
+ prec := 4
+ if f.precPresent && f.prec > 4 {
+ prec = f.prec
+ // Compute space needed for "U+" , number, " '", character, "'".
+ width := 2 + prec + 2 + utf8.UTFMax + 1
+ if width > len(buf) {
+ buf = make([]byte, width)
+ }
}
- negative := signedness == signed && a < 0
+ // Format into buf, ending at buf[i]. Formatting numbers is easier right-to-left.
+ i := len(buf)
+
+ // For %#U we want to add a space and a quoted character at the end of the buffer.
+ if f.sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
+ i--
+ buf[i] = '\''
+ i -= utf8.RuneLen(rune(u))
+ utf8.EncodeRune(buf[i:], rune(u))
+ i--
+ buf[i] = '\''
+ i--
+ buf[i] = ' '
+ }
+ // Format the Unicode code point u as a hexadecimal number.
+ for u >= 16 {
+ i--
+ buf[i] = udigits[u&0xF]
+ prec--
+ u >>= 4
+ }
+ i--
+ buf[i] = udigits[u]
+ prec--
+ // Add zeros in front of the number until requested precision is reached.
+ for prec > 0 {
+ i--
+ buf[i] = '0'
+ prec--
+ }
+ // Add a leading "U+".
+ i--
+ buf[i] = '+'
+ i--
+ buf[i] = 'U'
+
+ oldZero := f.zero
+ f.zero = false
+ f.pad(buf[i:])
+ f.zero = oldZero
+}
+
+// fmt_integer formats signed and unsigned integers.
+func (f *fmt) fmt_integer(u uint64, base int, isSigned bool, digits string) {
+ negative := isSigned && int64(u) < 0
if negative {
- a = -a
+ u = -u
}
- var buf []byte = f.intbuf[0:]
- if f.widPresent || f.precPresent || f.plus || f.space {
- width := f.wid + f.prec // Only one will be set, both are positive; this provides the maximum.
- if base == 16 && f.sharp {
- // Also adds "0x".
- width += 2
- }
- if f.unicode {
- // Also adds "U+".
- width += 2
- if f.uniQuote {
- // Also adds " 'x'".
- width += 1 + 1 + utf8.UTFMax + 1
- }
- }
- if negative || f.plus || f.space {
- width++
- }
- if width > nByte {
+ buf := f.intbuf[0:]
+ // The already allocated f.intbuf with a capacity of 68 bytes
+ // is large enough for integer formatting when no precision or width is set.
+ if f.widPresent || f.precPresent {
+ // Account 3 extra bytes for possible addition of a sign and "0x".
+ width := 3 + f.wid + f.prec // wid and prec are always positive.
+ if width > len(buf) {
// We're going to need a bigger boat.
buf = make([]byte, width)
}
}
- // two ways to ask for extra leading zero digits: %.3d or %03d.
- // apparently the first cancels the second.
+ // Two ways to ask for extra leading zero digits: %.3d or %03d.
+ // If both are specified the f.zero flag is ignored and
+ // padding with spaces is used instead.
prec := 0
if f.precPresent {
prec = f.prec
- f.zero = false
- } else if f.zero && f.widPresent && !f.minus && f.wid > 0 {
+ // Precision of 0 and value of 0 means "print nothing" but padding.
+ if prec == 0 && u == 0 {
+ oldZero := f.zero
+ f.zero = false
+ f.writePadding(f.wid)
+ f.zero = oldZero
+ return
+ }
+ } else if f.zero && f.widPresent {
prec = f.wid
if negative || f.plus || f.space {
prec-- // leave room for sign
}
}
- // format a into buf, ending at buf[i]. (printing is easier right-to-left.)
- // a is made into unsigned ua. we could make things
- // marginally faster by splitting the 32-bit case out into a separate
- // block but it's not worth the duplication, so ua has 64 bits.
+ // Because printing is easier right-to-left: format u into buf, ending at buf[i].
+ // We could make things marginally faster by splitting the 32-bit case out
+ // into a separate block but it's not worth the duplication, so u has 64 bits.
i := len(buf)
- ua := uint64(a)
- // use constants for the division and modulo for more efficient code.
- // switch cases ordered by popularity.
+ // Use constants for the division and modulo for more efficient code.
+ // Switch cases ordered by popularity.
switch base {
case 10:
- for ua >= 10 {
+ for u >= 10 {
i--
- next := ua / 10
- buf[i] = byte('0' + ua - next*10)
- ua = next
+ next := u / 10
+ buf[i] = byte('0' + u - next*10)
+ u = next
}
case 16:
- for ua >= 16 {
+ for u >= 16 {
i--
- buf[i] = digits[ua&0xF]
- ua >>= 4
+ buf[i] = digits[u&0xF]
+ u >>= 4
}
case 8:
- for ua >= 8 {
+ for u >= 8 {
i--
- buf[i] = byte('0' + ua&7)
- ua >>= 3
+ buf[i] = byte('0' + u&7)
+ u >>= 3
}
case 2:
- for ua >= 2 {
+ for u >= 2 {
i--
- buf[i] = byte('0' + ua&1)
- ua >>= 1
+ buf[i] = byte('0' + u&1)
+ u >>= 1
}
default:
panic("fmt: unknown base; can't happen")
}
i--
- buf[i] = digits[ua]
+ buf[i] = digits[u]
for i > 0 && prec > len(buf)-i {
i--
buf[i] = '0'
@@ -257,18 +281,13 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
buf[i] = '0'
}
case 16:
+ // Add a leading 0x or 0X.
i--
- buf[i] = 'x' + digits[10] - 'a'
+ buf[i] = digits[16]
i--
buf[i] = '0'
}
}
- if f.unicode {
- i--
- buf[i] = '+'
- i--
- buf[i] = 'U'
- }
if negative {
i--
@@ -281,36 +300,23 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
buf[i] = ' '
}
- // If we want a quoted char for %#U, move the data up to make room.
- if f.unicode && f.uniQuote && a >= 0 && a <= utf8.MaxRune && strconv.IsPrint(rune(a)) {
- runeWidth := utf8.RuneLen(rune(a))
- width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote
- copy(buf[i-width:], buf[i:]) // guaranteed to have enough room.
- i -= width
- // Now put " 'x'" at the end.
- j := len(buf) - width
- buf[j] = ' '
- j++
- buf[j] = '\''
- j++
- utf8.EncodeRune(buf[j:], rune(a))
- j += runeWidth
- buf[j] = '\''
- }
-
+ // Left padding with zeros has already been handled like precision earlier
+ // or the f.zero flag is ignored due to an explicitly set precision.
+ oldZero := f.zero
+ f.zero = false
f.pad(buf[i:])
+ f.zero = oldZero
}
// truncate truncates the string to the specified precision, if present.
func (f *fmt) truncate(s string) string {
- if f.precPresent && f.prec < utf8.RuneCountInString(s) {
+ if f.precPresent {
n := f.prec
for i := range s {
- if n == 0 {
- s = s[:i]
- break
- }
n--
+ if n < 0 {
+ return s[:i]
+ }
}
}
return s
@@ -324,212 +330,169 @@ func (f *fmt) fmt_s(s string) {
// fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes.
func (f *fmt) fmt_sbx(s string, b []byte, digits string) {
- n := len(b)
+ length := len(b)
if b == nil {
- n = len(s)
+ // No byte slice present. Assume string s should be encoded.
+ length = len(s)
+ }
+ // Set length to not process more bytes than the precision demands.
+ if f.precPresent && f.prec < length {
+ length = f.prec
+ }
+ // Compute width of the encoding taking into account the f.sharp and f.space flag.
+ width := 2 * length
+ if width > 0 {
+ if f.space {
+ // Each element encoded by two hexadecimals will get a leading 0x or 0X.
+ if f.sharp {
+ width *= 2
+ }
+ // Elements will be separated by a space.
+ width += length - 1
+ } else if f.sharp {
+ // Only a leading 0x or 0X will be added for the whole string.
+ width += 2
+ }
+ } else { // The byte slice or string that should be encoded is empty.
+ if f.widPresent {
+ f.writePadding(f.wid)
+ }
+ return
+ }
+ // Handle padding to the left.
+ if f.widPresent && f.wid > width && !f.minus {
+ f.writePadding(f.wid - width)
}
- x := digits[10] - 'a' + 'x'
- // TODO: Avoid buffer by pre-padding.
- var buf []byte
- for i := 0; i < n; i++ {
- if i > 0 && f.space {
+ // Write the encoding directly into the output buffer.
+ buf := *f.buf
+ if f.sharp {
+ // Add leading 0x or 0X.
+ buf = append(buf, '0', digits[16])
+ }
+ var c byte
+ for i := 0; i < length; i++ {
+ if f.space && i > 0 {
+ // Separate elements with a space.
buf = append(buf, ' ')
+ if f.sharp {
+ // Add leading 0x or 0X for each element.
+ buf = append(buf, '0', digits[16])
+ }
}
- if f.sharp && (f.space || i == 0) {
- buf = append(buf, '0', x)
- }
- var c byte
- if b == nil {
- c = s[i]
+ if b != nil {
+ c = b[i] // Take a byte from the input byte slice.
} else {
- c = b[i]
+ c = s[i] // Take a byte from the input string.
}
+ // Encode each byte as two hexadecimal digits.
buf = append(buf, digits[c>>4], digits[c&0xF])
}
- f.pad(buf)
+ *f.buf = buf
+ // Handle padding to the right.
+ if f.widPresent && f.wid > width && f.minus {
+ f.writePadding(f.wid - width)
+ }
}
// fmt_sx formats a string as a hexadecimal encoding of its bytes.
func (f *fmt) fmt_sx(s, digits string) {
- if f.precPresent && f.prec < len(s) {
- s = s[:f.prec]
- }
f.fmt_sbx(s, nil, digits)
}
// fmt_bx formats a byte slice as a hexadecimal encoding of its bytes.
func (f *fmt) fmt_bx(b []byte, digits string) {
- if f.precPresent && f.prec < len(b) {
- b = b[:f.prec]
- }
f.fmt_sbx("", b, digits)
}
// fmt_q formats a string as a double-quoted, escaped Go string constant.
+// If f.sharp is set a raw (backquoted) string may be returned instead
+// if the string does not contain any control characters other than tab.
func (f *fmt) fmt_q(s string) {
s = f.truncate(s)
- var quoted string
if f.sharp && strconv.CanBackquote(s) {
- quoted = "`" + s + "`"
+ f.padString("`" + s + "`")
+ return
+ }
+ buf := f.intbuf[:0]
+ if f.plus {
+ f.pad(strconv.AppendQuoteToASCII(buf, s))
} else {
- if f.plus {
- quoted = strconv.QuoteToASCII(s)
- } else {
- quoted = strconv.Quote(s)
- }
+ f.pad(strconv.AppendQuote(buf, s))
}
- f.padString(quoted)
}
-// fmt_qc formats the integer as a single-quoted, escaped Go character constant.
+// fmt_c formats an integer as a Unicode character.
// If the character is not valid Unicode, it will print '\ufffd'.
-func (f *fmt) fmt_qc(c int64) {
- var quoted []byte
+func (f *fmt) fmt_c(c uint64) {
+ r := rune(c)
+ if c > utf8.MaxRune {
+ r = utf8.RuneError
+ }
+ buf := f.intbuf[:0]
+ w := utf8.EncodeRune(buf[:utf8.UTFMax], r)
+ f.pad(buf[:w])
+}
+
+// fmt_qc formats an integer as a single-quoted, escaped Go character constant.
+// If the character is not valid Unicode, it will print '\ufffd'.
+func (f *fmt) fmt_qc(c uint64) {
+ r := rune(c)
+ if c > utf8.MaxRune {
+ r = utf8.RuneError
+ }
+ buf := f.intbuf[:0]
if f.plus {
- quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c))
+ f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
} else {
- quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c))
+ f.pad(strconv.AppendQuoteRune(buf, r))
}
- f.pad(quoted)
}
-// floating-point
-
-func doPrec(f *fmt, def int) int {
+// fmt_float formats a float64. It assumes that verb is a valid format specifier
+// for strconv.AppendFloat and therefore fits into a byte.
+func (f *fmt) fmt_float(v float64, size int, verb rune, prec int) {
+ // Explicit precision in format specifier overrules default precision.
if f.precPresent {
- return f.prec
+ prec = f.prec
}
- return def
-}
-
-// formatFloat formats a float64; it is an efficient equivalent to f.pad(strconv.FormatFloat()...).
-func (f *fmt) formatFloat(v float64, verb byte, prec, n int) {
// Format number, reserving space for leading + sign if needed.
- num := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n)
+ num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size)
if num[1] == '-' || num[1] == '+' {
num = num[1:]
} else {
num[0] = '+'
}
- // Special handling for infinity, which doesn't look like a number so shouldn't be padded with zeros.
- if math.IsInf(v, 0) {
- if f.zero {
- defer func() { f.zero = true }()
- f.zero = false
- }
+ // f.space means to add a leading space instead of a "+" sign unless
+ // the sign is explicitly asked for by f.plus.
+ if f.space && num[0] == '+' && !f.plus {
+ num[0] = ' '
}
- // num is now a signed version of the number.
- // If we're zero padding, want the sign before the leading zeros.
- // Achieve this by writing the sign out and then padding the unsigned number.
- if f.zero && f.widPresent && f.wid > len(num) {
- if f.space && v >= 0 {
- f.buf.WriteByte(' ') // This is what C does: even with zero, f.space means space.
- f.wid--
- } else if f.plus || v < 0 {
- f.buf.WriteByte(num[0])
- f.wid--
+ // Special handling for infinities and NaN,
+ // which don't look like a number so shouldn't be padded with zeros.
+ if num[1] == 'I' || num[1] == 'N' {
+ oldZero := f.zero
+ f.zero = false
+ // Remove sign before NaN if not asked for.
+ if num[1] == 'N' && !f.space && !f.plus {
+ num = num[1:]
}
- f.pad(num[1:])
- return
- }
- // f.space says to replace a leading + with a space.
- if f.space && num[0] == '+' {
- num[0] = ' '
f.pad(num)
+ f.zero = oldZero
return
}
- // Now we know the sign is attached directly to the number, if present at all.
- // We want a sign if asked for, if it's negative, or if it's infinity (+Inf vs. -Inf).
- if f.plus || num[0] == '-' || math.IsInf(v, 0) {
+ // We want a sign if asked for and if the sign is not positive.
+ if f.plus || num[0] != '+' {
+ // If we're zero padding to the left we want the sign before the leading zeros.
+ // Achieve this by writing the sign out and then padding the unsigned number.
+ if f.zero && f.widPresent && f.wid > len(num) {
+ f.buf.WriteByte(num[0])
+ f.writePadding(f.wid - len(num))
+ f.buf.Write(num[1:])
+ return
+ }
f.pad(num)
return
}
// No sign to show and the number is positive; just print the unsigned number.
f.pad(num[1:])
}
-
-// fmt_e64 formats a float64 in the form -1.23e+12.
-func (f *fmt) fmt_e64(v float64) { f.formatFloat(v, 'e', doPrec(f, 6), 64) }
-
-// fmt_E64 formats a float64 in the form -1.23E+12.
-func (f *fmt) fmt_E64(v float64) { f.formatFloat(v, 'E', doPrec(f, 6), 64) }
-
-// fmt_f64 formats a float64 in the form -1.23.
-func (f *fmt) fmt_f64(v float64) { f.formatFloat(v, 'f', doPrec(f, 6), 64) }
-
-// fmt_g64 formats a float64 in the 'f' or 'e' form according to size.
-func (f *fmt) fmt_g64(v float64) { f.formatFloat(v, 'g', doPrec(f, -1), 64) }
-
-// fmt_G64 formats a float64 in the 'f' or 'E' form according to size.
-func (f *fmt) fmt_G64(v float64) { f.formatFloat(v, 'G', doPrec(f, -1), 64) }
-
-// fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2).
-func (f *fmt) fmt_fb64(v float64) { f.formatFloat(v, 'b', 0, 64) }
-
-// float32
-// cannot defer to float64 versions
-// because it will get rounding wrong in corner cases.
-
-// fmt_e32 formats a float32 in the form -1.23e+12.
-func (f *fmt) fmt_e32(v float32) { f.formatFloat(float64(v), 'e', doPrec(f, 6), 32) }
-
-// fmt_E32 formats a float32 in the form -1.23E+12.
-func (f *fmt) fmt_E32(v float32) { f.formatFloat(float64(v), 'E', doPrec(f, 6), 32) }
-
-// fmt_f32 formats a float32 in the form -1.23.
-func (f *fmt) fmt_f32(v float32) { f.formatFloat(float64(v), 'f', doPrec(f, 6), 32) }
-
-// fmt_g32 formats a float32 in the 'f' or 'e' form according to size.
-func (f *fmt) fmt_g32(v float32) { f.formatFloat(float64(v), 'g', doPrec(f, -1), 32) }
-
-// fmt_G32 formats a float32 in the 'f' or 'E' form according to size.
-func (f *fmt) fmt_G32(v float32) { f.formatFloat(float64(v), 'G', doPrec(f, -1), 32) }
-
-// fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2).
-func (f *fmt) fmt_fb32(v float32) { f.formatFloat(float64(v), 'b', 0, 32) }
-
-// fmt_c64 formats a complex64 according to the verb.
-func (f *fmt) fmt_c64(v complex64, verb rune) {
- f.fmt_complex(float64(real(v)), float64(imag(v)), 32, verb)
-}
-
-// fmt_c128 formats a complex128 according to the verb.
-func (f *fmt) fmt_c128(v complex128, verb rune) {
- f.fmt_complex(real(v), imag(v), 64, verb)
-}
-
-// fmt_complex formats a complex number as (r+ji).
-func (f *fmt) fmt_complex(r, j float64, size int, verb rune) {
- f.buf.WriteByte('(')
- oldPlus := f.plus
- oldSpace := f.space
- oldWid := f.wid
- for i := 0; ; i++ {
- switch verb {
- case 'b':
- f.formatFloat(r, 'b', 0, size)
- case 'e':
- f.formatFloat(r, 'e', doPrec(f, 6), size)
- case 'E':
- f.formatFloat(r, 'E', doPrec(f, 6), size)
- case 'f', 'F':
- f.formatFloat(r, 'f', doPrec(f, 6), size)
- case 'g':
- f.formatFloat(r, 'g', doPrec(f, -1), size)
- case 'G':
- f.formatFloat(r, 'G', doPrec(f, -1), size)
- }
- if i != 0 {
- break
- }
- // Imaginary part always has a sign.
- f.plus = true
- f.space = false
- f.wid = oldWid
- r = j
- }
- f.space = oldSpace
- f.plus = oldPlus
- f.wid = oldWid
- f.buf.Write(irparenBytes)
-}