aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/fmt
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-01-13 05:11:45 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-01-13 05:11:45 +0000
commitdf4aa89a5e7acb315655f193e7f549e8d32367e2 (patch)
treeeb5eccc07097c5fcf940967f33ab84a7d47c96fe /libgo/go/fmt
parentf83fa0bf8f411697ec908cfa86ee6faf4cd9c476 (diff)
downloadgcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.zip
gcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.tar.gz
gcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.tar.bz2
libgo: Update to weekly.2011-12-22.
From-SVN: r183150
Diffstat (limited to 'libgo/go/fmt')
-rw-r--r--libgo/go/fmt/fmt_test.go98
-rw-r--r--libgo/go/fmt/format.go93
-rw-r--r--libgo/go/fmt/print.go8
3 files changed, 84 insertions, 115 deletions
diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go
index d7fe296..d34a4f8 100644
--- a/libgo/go/fmt/fmt_test.go
+++ b/libgo/go/fmt/fmt_test.go
@@ -506,78 +506,42 @@ func BenchmarkSprintfFloat(b *testing.B) {
}
}
+var mallocBuf bytes.Buffer
+
+var mallocTest = []struct {
+ count int
+ desc string
+ fn func()
+}{
+ {0, `Sprintf("")`, func() { Sprintf("") }},
+ {1, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
+ {1, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
+ {2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
+ {1, `Sprintf("%x %x")`, func() { Sprintf("%x", 7, 112) }},
+ {1, `Sprintf("%g")`, func() { Sprintf("%g", 3.14159) }},
+ {0, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x %x %x", 7, 8, 9) }},
+ {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
+}
+
+var _ bytes.Buffer
+
func TestCountMallocs(t *testing.T) {
if testing.Short() {
return
}
- const N = 100
- runtime.UpdateMemStats()
- mallocs := 0 - runtime.MemStats.Mallocs
- for i := 0; i < N; i++ {
- Sprintf("")
- }
- runtime.UpdateMemStats()
- mallocs += runtime.MemStats.Mallocs
- Printf("mallocs per Sprintf(\"\"): %d\n", mallocs/N)
- runtime.UpdateMemStats()
- mallocs = 0 - runtime.MemStats.Mallocs
- for i := 0; i < N; i++ {
- Sprintf("xxx")
- }
- runtime.UpdateMemStats()
- mallocs += runtime.MemStats.Mallocs
- Printf("mallocs per Sprintf(\"xxx\"): %d\n", mallocs/N)
- runtime.UpdateMemStats()
- mallocs = 0 - runtime.MemStats.Mallocs
- for i := 0; i < N; i++ {
- Sprintf("%x", i)
- }
- runtime.UpdateMemStats()
- mallocs += runtime.MemStats.Mallocs
- Printf("mallocs per Sprintf(\"%%x\"): %d\n", mallocs/N)
- runtime.UpdateMemStats()
- mallocs = 0 - runtime.MemStats.Mallocs
- for i := 0; i < N; i++ {
- Sprintf("%s", "hello")
- }
- runtime.UpdateMemStats()
- mallocs += runtime.MemStats.Mallocs
- Printf("mallocs per Sprintf(\"%%s\"): %d\n", mallocs/N)
- runtime.UpdateMemStats()
- mallocs = 0 - runtime.MemStats.Mallocs
- for i := 0; i < N; i++ {
- Sprintf("%x %x", i, i)
- }
- runtime.UpdateMemStats()
- mallocs += runtime.MemStats.Mallocs
- Printf("mallocs per Sprintf(\"%%x %%x\"): %d\n", mallocs/N)
- runtime.UpdateMemStats()
- mallocs = 0 - runtime.MemStats.Mallocs
- for i := 0; i < N; i++ {
- Sprintf("%g", 3.14159)
- }
- runtime.UpdateMemStats()
- mallocs += runtime.MemStats.Mallocs
- Printf("mallocs per Sprintf(\"%%g\"): %d\n", mallocs/N)
- buf := new(bytes.Buffer)
- runtime.UpdateMemStats()
- mallocs = 0 - runtime.MemStats.Mallocs
- for i := 0; i < N; i++ {
- buf.Reset()
- Fprintf(buf, "%x %x %x", i, i, i)
- }
- runtime.UpdateMemStats()
- mallocs += runtime.MemStats.Mallocs
- Printf("mallocs per Fprintf(buf, \"%%x %%x %%x\"): %d\n", mallocs/N)
- runtime.UpdateMemStats()
- mallocs = 0 - runtime.MemStats.Mallocs
- for i := 0; i < N; i++ {
- buf.Reset()
- Fprintf(buf, "%s", "hello")
+ for _, mt := range mallocTest {
+ const N = 100
+ runtime.UpdateMemStats()
+ mallocs := 0 - runtime.MemStats.Mallocs
+ for i := 0; i < N; i++ {
+ mt.fn()
+ }
+ runtime.UpdateMemStats()
+ mallocs += runtime.MemStats.Mallocs
+ if mallocs/N != uint64(mt.count) {
+ t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N)
+ }
}
- runtime.UpdateMemStats()
- mallocs += runtime.MemStats.Mallocs
- Printf("mallocs per Fprintf(buf, \"%%s\"): %d\n", mallocs/N)
}
type flagPrinter struct{}
diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go
index 5f62c06..78d9e99 100644
--- a/libgo/go/fmt/format.go
+++ b/libgo/go/fmt/format.go
@@ -154,12 +154,17 @@ func putint(buf []byte, base, val uint64, digits string) int {
return i - 1
}
+var (
+ trueBytes = []byte("true")
+ falseBytes = []byte("false")
+)
+
// fmt_boolean formats a boolean.
func (f *fmt) fmt_boolean(v bool) {
if v {
- f.padString("true")
+ f.pad(trueBytes)
} else {
- f.padString("false")
+ f.pad(falseBytes)
}
}
@@ -283,31 +288,18 @@ func (f *fmt) fmt_s(s string) {
}
// fmt_sx formats a string as a hexadecimal encoding of its bytes.
-func (f *fmt) fmt_sx(s string) {
- t := ""
+func (f *fmt) fmt_sx(s, digits string) {
+ // TODO: Avoid buffer by pre-padding.
+ var b bytes.Buffer
for i := 0; i < len(s); i++ {
if i > 0 && f.space {
- t += " "
+ b.WriteByte(' ')
}
v := s[i]
- t += string(ldigits[v>>4])
- t += string(ldigits[v&0xF])
+ b.WriteByte(digits[v>>4])
+ b.WriteByte(digits[v&0xF])
}
- f.padString(t)
-}
-
-// fmt_sX formats a string as an uppercase hexadecimal encoding of its bytes.
-func (f *fmt) fmt_sX(s string) {
- t := ""
- for i := 0; i < len(s); i++ {
- if i > 0 && f.space {
- t += " "
- }
- v := s[i]
- t += string(udigits[v>>4])
- t += string(udigits[v&0xF])
- }
- f.padString(t)
+ f.pad(b.Bytes())
}
// fmt_q formats a string as a double-quoted, escaped Go string constant.
@@ -329,13 +321,13 @@ func (f *fmt) fmt_q(s string) {
// fmt_qc formats the 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 int64) {
- var quoted string
+ var quoted []byte
if f.plus {
- quoted = strconv.QuoteRuneToASCII(rune(c))
+ quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c))
} else {
- quoted = strconv.QuoteRune(rune(c))
+ quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c))
}
- f.padString(quoted)
+ f.pad(quoted)
}
// floating-point
@@ -347,57 +339,70 @@ func doPrec(f *fmt, def int) int {
return def
}
-// Add a plus sign or space to the floating-point string representation if missing and required.
-func (f *fmt) plusSpace(s string) {
- if s[0] != '-' {
+// 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) {
+ // We leave one byte at the beginning of f.intbuf for a sign if needed,
+ // and make it a space, which we might be able to use.
+ f.intbuf[0] = ' '
+ slice := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n)
+ // Add a plus sign or space to the floating-point string representation if missing and required.
+ // The formatted number starts at slice[1].
+ switch slice[1] {
+ case '-', '+':
+ // We're set; drop the leading space.
+ slice = slice[1:]
+ default:
+ // There's no sign, but we might need one.
if f.plus {
- s = "+" + s
+ slice[0] = '+'
} else if f.space {
- s = " " + s
+ // space is already there
+ } else {
+ slice = slice[1:]
}
}
- f.padString(s)
+ f.pad(slice)
}
// fmt_e64 formats a float64 in the form -1.23e+12.
-func (f *fmt) fmt_e64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'e', doPrec(f, 6), 64)) }
+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.plusSpace(strconv.FormatFloat(v, 'E', doPrec(f, 6), 64)) }
+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.plusSpace(strconv.FormatFloat(v, 'f', doPrec(f, 6), 64)) }
+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.plusSpace(strconv.FormatFloat(v, 'g', doPrec(f, -1), 64)) }
+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.plusSpace(strconv.FormatFloat(v, 'G', doPrec(f, -1), 64)) }
+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.plusSpace(strconv.FormatFloat(v, 'b', 0, 64)) }
+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.plusSpace(strconv.FormatFloat(float64(v), 'e', doPrec(f, 6), 32)) }
+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.plusSpace(strconv.FormatFloat(float64(v), 'E', doPrec(f, 6), 32)) }
+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.plusSpace(strconv.FormatFloat(float64(v), 'f', doPrec(f, 6), 32)) }
+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.plusSpace(strconv.FormatFloat(float64(v), 'g', doPrec(f, -1), 32)) }
+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.plusSpace(strconv.FormatFloat(float64(v), 'G', doPrec(f, -1), 32)) }
+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.padString(strconv.FormatFloat(float64(v), 'b', 0, 32)) }
+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) {
diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go
index 9f157da..3b7d346 100644
--- a/libgo/go/fmt/print.go
+++ b/libgo/go/fmt/print.go
@@ -503,9 +503,9 @@ func (p *pp) fmtString(v string, verb rune, goSyntax bool) {
case 's':
p.fmt.fmt_s(v)
case 'x':
- p.fmt.fmt_sx(v)
+ p.fmt.fmt_sx(v, ldigits)
case 'X':
- p.fmt.fmt_sX(v)
+ p.fmt.fmt_sx(v, udigits)
case 'q':
p.fmt.fmt_q(v)
default:
@@ -542,9 +542,9 @@ func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) {
case 's':
p.fmt.fmt_s(s)
case 'x':
- p.fmt.fmt_sx(s)
+ p.fmt.fmt_sx(s, ldigits)
case 'X':
- p.fmt.fmt_sX(s)
+ p.fmt.fmt_sx(s, udigits)
case 'q':
p.fmt.fmt_q(s)
default: