Commit 3928a4e1 authored by Rob Pike's avatar Rob Pike

printing maps

R=rsc
DELTA=57  (39 added, 3 deleted, 15 changed)
OCL=31424
CL=31430
parent 12ebbe74
...@@ -15,9 +15,9 @@ import ( ...@@ -15,9 +15,9 @@ import (
func TestFmtInterface(t *testing.T) { func TestFmtInterface(t *testing.T) {
var i1 interface{}; var i1 interface{};
i1 = "abc"; i1 = "abc";
s := fmt.Sprintf("%s", i1); s := Sprintf("%s", i1);
if s != "abc" { if s != "abc" {
t.Errorf(`fmt.Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc"); t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc");
} }
} }
...@@ -157,23 +157,22 @@ var fmttests = []fmtTest{ ...@@ -157,23 +157,22 @@ var fmttests = []fmtTest{
} }
func TestSprintf(t *testing.T) { func TestSprintf(t *testing.T) {
for i := 0; i < len(fmttests); i++ { for i, tt := range fmttests {
tt := fmttests[i]; s := Sprintf(tt.fmt, tt.val);
s := fmt.Sprintf(tt.fmt, tt.val);
if s != tt.out { if s != tt.out {
if ss, ok := tt.val.(string); ok { if ss, ok := tt.val.(string); ok {
// Don't requote the already-quoted strings. // Don't requote the already-quoted strings.
// It's too confusing to read the errors. // It's too confusing to read the errors.
t.Errorf("fmt.Sprintf(%q, %q) = %s want %s", tt.fmt, tt.val, s, tt.out); t.Errorf("Sprintf(%q, %q) = %s want %s", tt.fmt, tt.val, s, tt.out);
} else { } else {
t.Errorf("fmt.Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out); t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out);
} }
} }
} }
} }
type flagPrinter struct { } type flagPrinter struct { }
func (*flagPrinter) Format(f fmt.State, c int) { func (*flagPrinter) Format(f State, c int) {
s := "%"; s := "%";
for i := 0; i < 128; i++ { for i := 0; i < 128; i++ {
if f.Flag(i) { if f.Flag(i) {
...@@ -181,10 +180,10 @@ func (*flagPrinter) Format(f fmt.State, c int) { ...@@ -181,10 +180,10 @@ func (*flagPrinter) Format(f fmt.State, c int) {
} }
} }
if w, ok := f.Width(); ok { if w, ok := f.Width(); ok {
s += fmt.Sprintf("%d", w); s += Sprintf("%d", w);
} }
if p, ok := f.Precision(); ok { if p, ok := f.Precision(); ok {
s += fmt.Sprintf(".%d", p); s += Sprintf(".%d", p);
} }
s += string(c); s += string(c);
io.WriteString(f, "["+s+"]"); io.WriteString(f, "["+s+"]");
...@@ -212,9 +211,8 @@ var flagtests = []flagTest { ...@@ -212,9 +211,8 @@ var flagtests = []flagTest {
func TestFlagParser(t *testing.T) { func TestFlagParser(t *testing.T) {
var flagprinter flagPrinter; var flagprinter flagPrinter;
for i := 0; i < len(flagtests); i++ { for i, tt := range flagtests {
tt := flagtests[i]; s := Sprintf(tt.in, &flagprinter);
s := fmt.Sprintf(tt.in, &flagprinter);
if s != tt.out { if s != tt.out {
t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out); t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out);
} }
...@@ -236,13 +234,39 @@ func TestStructPrinter(t *testing.T) { ...@@ -236,13 +234,39 @@ func TestStructPrinter(t *testing.T) {
} }
var tests = []Test { var tests = []Test {
Test{ "%v", "{abc def 123}" }, Test{ "%v", "{abc def 123}" },
Test{ "%+v", "{a=abc b=def c=123}" }, Test{ "%+v", "{a:abc b:def c:123}" },
}; };
for i := 0; i < len(tests); i++ { for i, tt := range tests {
tt := tests[i]; out := Sprintf(tt.fmt, s);
out := fmt.Sprintf(tt.fmt, s);
if out != tt.out { if out != tt.out {
t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out); t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out);
} }
} }
} }
// Check map printing using substrings so we don't depend on the print order.
func presentInMap(s string, a []string, t *testing.T) {
for i := 0; i < len(a); i++ {
loc := strings.Index(s, a[i]);
if loc < 0 {
t.Errorf("map print: expected to find %q in %q", a[i], s);
}
// make sure the match ends here
loc += len(a[i]);
if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
t.Errorf("map print: %q not properly terminated in %q", a[i], s);
}
}
}
func TestMapPrinter(t *testing.T) {
m0 := make(map[int] string);
s := Sprint(m0);
if s != "map[]" {
t.Errorf("empty map printed as %q not %q", s, "map[]");
}
m1 := map[int]string{1:"one", 2:"two", 3:"three"};
a := []string{"1:one", "2:two", "3:three"};
presentInMap(Sprintf("%v", m1), a, t);
presentInMap(Sprint(m1), a, t);
}
...@@ -444,6 +444,18 @@ func (p *pp) printField(field reflect.Value) (was_string bool) { ...@@ -444,6 +444,18 @@ func (p *pp) printField(field reflect.Value) (was_string bool) {
p.printField(f.Elem(i)); p.printField(f.Elem(i));
} }
p.addstr("]"); p.addstr("]");
case *reflect.MapValue:
p.addstr("map[");
keys := f.Keys();
for i, key := range keys {
if i > 0 {
p.addstr(" ");
}
p.printField(key);
p.addstr(":");
p.printField(f.Get(key));
}
p.addstr("]");
case *reflect.StructValue: case *reflect.StructValue:
p.add('{'); p.add('{');
v := f; v := f;
...@@ -457,7 +469,7 @@ func (p *pp) printField(field reflect.Value) (was_string bool) { ...@@ -457,7 +469,7 @@ func (p *pp) printField(field reflect.Value) (was_string bool) {
if donames { if donames {
if f := t.Field(i); f.Name != "" { if f := t.Field(i); f.Name != "" {
p.addstr(f.Name); p.addstr(f.Name);
p.add('='); p.add(':');
} }
} }
p.printField(getField(v, i)); p.printField(getField(v, i));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment