summaryrefslogtreecommitdiff
path: root/libgo/go/fmt
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-16 06:54:42 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-16 06:54:42 +0000
commitf4ca453c9530ff24478cae090c9979b97fdd7411 (patch)
tree0e8fda573576bb4181dba29d0e88380a8c38fafd /libgo/go/fmt
parent84a4a7d4b2fecf754bc0b7fce55b05912a054ef4 (diff)
downloadgcc-f4ca453c9530ff24478cae090c9979b97fdd7411.tar.gz
libgo: Update to Go 1.1.1.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200974 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/fmt')
-rw-r--r--libgo/go/fmt/doc.go13
-rw-r--r--libgo/go/fmt/fmt_test.go39
-rw-r--r--libgo/go/fmt/print.go47
3 files changed, 66 insertions, 33 deletions
diff --git a/libgo/go/fmt/doc.go b/libgo/go/fmt/doc.go
index 2c925a42283..b8dd995c77b 100644
--- a/libgo/go/fmt/doc.go
+++ b/libgo/go/fmt/doc.go
@@ -74,7 +74,8 @@
- pad with spaces on the right rather than the left (left-justify the field)
# alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
0X for hex (%#X); suppress 0x for %p (%#p);
- print a raw (backquoted) string if possible for %q (%#q);
+ for %q, print a raw (backquoted) string if strconv.CanBackquote
+ returns true;
write e.g. U+0078 'x' if the character is printable for %U (%#U).
' ' (space) leave a space for elided sign in numbers (% d);
put spaces between bytes printing strings or slices in hex (% x, % X)
@@ -137,6 +138,16 @@
by a single character (the verb) and end with a parenthesized
description.
+ If an Error or String method triggers a panic when called by a
+ print routine, the fmt package reformats the error message
+ from the panic, decorating it with an indication that it came
+ through the fmt package. For example, if a String method
+ calls panic("bad"), the resulting formatted message will look
+ like
+ %s(PANIC=bad)
+
+ The %s just shows the print verb in use when the failure
+ occurred.
Scanning
diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go
index dd5e5542523..df9e5a0af24 100644
--- a/libgo/go/fmt/fmt_test.go
+++ b/libgo/go/fmt/fmt_test.go
@@ -9,7 +9,7 @@ import (
. "fmt"
"io"
"math"
- "runtime" // for the malloc count test only
+ "runtime"
"strings"
"testing"
"time"
@@ -105,6 +105,9 @@ func (p *P) String() string {
return "String(p)"
}
+var barray = [5]renamedUint8{1, 2, 3, 4, 5}
+var bslice = barray[:]
+
var b byte
var fmttests = []struct {
@@ -176,6 +179,8 @@ var fmttests = []struct {
{"%.3q", "日本語日本語", `"日本語"`},
{"%.3q", []byte("日本語日本語"), `"日本語"`},
{"%10.1q", "日本語日本語", ` "日"`},
+ {"%10v", nil, " <nil>"},
+ {"%-10v", nil, "<nil> "},
// integers
{"%d", 12345, "12345"},
@@ -332,14 +337,18 @@ var fmttests = []struct {
// arrays
{"%v", array, "[1 2 3 4 5]"},
{"%v", iarray, "[1 hello 2.5 <nil>]"},
+ {"%v", barray, "[1 2 3 4 5]"},
{"%v", &array, "&[1 2 3 4 5]"},
{"%v", &iarray, "&[1 hello 2.5 <nil>]"},
+ {"%v", &barray, "&[1 2 3 4 5]"},
// slices
{"%v", slice, "[1 2 3 4 5]"},
{"%v", islice, "[1 hello 2.5 <nil>]"},
+ {"%v", bslice, "[1 2 3 4 5]"},
{"%v", &slice, "&[1 2 3 4 5]"},
{"%v", &islice, "&[1 hello 2.5 <nil>]"},
+ {"%v", &bslice, "&[1 2 3 4 5]"},
// complexes with %v
{"%v", 1 + 2i, "(1+2i)"},
@@ -382,6 +391,8 @@ var fmttests = []struct {
{"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
{"%#v", map[int]byte{}, `map[int]uint8{}`},
{"%#v", "foo", `"foo"`},
+ {"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
+ {"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
// slices with other formats
{"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
@@ -407,6 +418,9 @@ var fmttests = []struct {
{"%x", renamedString("thing"), "7468696e67"},
{"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
{"%q", renamedBytes([]byte("hello")), `"hello"`},
+ {"%x", []renamedUint8{'a', 'b', 'c'}, "616263"},
+ {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
+ {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
{"%v", renamedFloat32(22), "22"},
{"%v", renamedFloat64(33), "33"},
{"%v", renamedComplex64(3 + 4i), "(3+4i)"},
@@ -426,6 +440,8 @@ var fmttests = []struct {
{"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
{"%T", intVal, "int"},
{"%6T", &intVal, " *int"},
+ {"%10T", nil, " <nil>"},
+ {"%-10T", nil, "<nil> "},
// %p
{"p0=%p", new(int), "p0=0xPTR"},
@@ -481,6 +497,9 @@ var fmttests = []struct {
// causing +2+0i and +3+0i instead of 2+0i and 3+0i.
{"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
{"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
+
+ // Incomplete format specification caused crash.
+ {"%.", 3, "%!.(int=3)"},
}
func TestSprintf(t *testing.T) {
@@ -588,19 +607,13 @@ var mallocTest = []struct {
var _ bytes.Buffer
func TestCountMallocs(t *testing.T) {
- defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+ if runtime.GOMAXPROCS(0) > 1 {
+ t.Skip("skipping; GOMAXPROCS>1")
+ }
for _, mt := range mallocTest {
- const N = 100
- memstats := new(runtime.MemStats)
- runtime.ReadMemStats(memstats)
- mallocs := 0 - memstats.Mallocs
- for i := 0; i < N; i++ {
- mt.fn()
- }
- runtime.ReadMemStats(memstats)
- mallocs += memstats.Mallocs
- if mallocs/N > uint64(mt.count) {
- t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N)
+ mallocs := testing.AllocsPerRun(100, mt.fn)
+ if got, max := mallocs, float64(mt.count); got > max {
+ t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
}
}
}
diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go
index 4078f4a910b..5f37fd12085 100644
--- a/libgo/go/fmt/print.go
+++ b/libgo/go/fmt/print.go
@@ -47,7 +47,7 @@ type State interface {
}
// Formatter is the interface implemented by values with a custom formatter.
-// The implementation of Format may call Sprintf or Fprintf(f) etc.
+// The implementation of Format may call Sprint(f) or Fprint(f) etc.
// to generate its output.
type Formatter interface {
Format(f State, c rune)
@@ -56,7 +56,8 @@ type Formatter interface {
// Stringer is implemented by any value that has a String method,
// which defines the ``native'' format for that value.
// The String method is used to print values passed as an operand
-// to a %s or %v format or to an unformatted printer such as Print.
+// to any format that accepts a string or to an unformatted printer
+// such as Print.
type Stringer interface {
String() string
}
@@ -545,10 +546,15 @@ func (p *pp) fmtString(v string, verb rune, goSyntax bool) {
}
}
-func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) {
+func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, typ reflect.Type, depth int) {
if verb == 'v' || verb == 'd' {
if goSyntax {
- p.buf.Write(bytesBytes)
+ if typ == nil {
+ p.buf.Write(bytesBytes)
+ } else {
+ p.buf.WriteString(typ.String())
+ p.buf.WriteByte('{')
+ }
} else {
p.buf.WriteByte('[')
}
@@ -724,7 +730,7 @@ func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth
if field == nil {
if verb == 'T' || verb == 'v' {
- p.buf.Write(nilAngleBytes)
+ p.fmt.pad(nilAngleBytes)
} else {
p.badVerb(verb)
}
@@ -793,7 +799,7 @@ func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth
p.fmtString(f, verb, goSyntax)
wasString = verb == 's' || verb == 'v'
case []byte:
- p.fmtBytes(f, verb, goSyntax, depth)
+ p.fmtBytes(f, verb, goSyntax, nil, depth)
wasString = verb == 's'
default:
// Restore flags in case handleMethods finds a Formatter.
@@ -939,19 +945,22 @@ BigSwitch:
}
case reflect.Array, reflect.Slice:
// Byte slices are special.
- if f.Type().Elem().Kind() == reflect.Uint8 {
- // We know it's a slice of bytes, but we also know it does not have static type
- // []byte, or it would have been caught above. Therefore we cannot convert
- // it directly in the (slightly) obvious way: f.Interface().([]byte); it doesn't have
- // that type, and we can't write an expression of the right type and do a
- // conversion because we don't have a static way to write the right type.
- // So we build a slice by hand. This is a rare case but it would be nice
- // if reflection could help a little more.
- bytes := make([]byte, f.Len())
- for i := range bytes {
- bytes[i] = byte(f.Index(i).Uint())
+ if typ := f.Type(); typ.Elem().Kind() == reflect.Uint8 {
+ var bytes []byte
+ if f.Kind() == reflect.Slice {
+ bytes = f.Bytes()
+ } else if f.CanAddr() {
+ bytes = f.Slice(0, f.Len()).Bytes()
+ } else {
+ // We have an array, but we cannot Slice() a non-addressable array,
+ // so we build a slice by hand. This is a rare case but it would be nice
+ // if reflection could help a little more.
+ bytes = make([]byte, f.Len())
+ for i := range bytes {
+ bytes[i] = byte(f.Index(i).Uint())
+ }
}
- p.fmtBytes(bytes, verb, goSyntax, depth)
+ p.fmtBytes(bytes, verb, goSyntax, typ, depth)
wasString = verb == 's'
break
}
@@ -1063,7 +1072,7 @@ func (p *pp) doPrintf(format string, a []interface{}) {
p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
}
// do we have precision?
- if i < end && format[i] == '.' {
+ if i+1 < end && format[i] == '.' {
if format[i+1] == '*' {
p.fmt.prec, p.fmt.precPresent, i, fieldnum = intFromArg(a, end, i+1, fieldnum)
if !p.fmt.precPresent {