Commit bf67afc8 authored by Russ Cox's avatar Russ Cox

print field names on struct members.

also don't concatenate strings next
to each other in the struct,
like p.doprint does.

expose additional print flags to formatters

R=r
DELTA=128  (111 added, 11 deleted, 6 changed)
OCL=20991
CL=21018
parent c7ab3327
......@@ -6,6 +6,7 @@ package fmt
import (
"fmt";
"io";
"syscall";
"testing";
)
......@@ -163,3 +164,77 @@ export func TestSprintf(t *testing.T) {
}
}
type FlagPrinter struct { }
func (*FlagPrinter) Format(f fmt.Formatter, c int) {
s := "%";
for i := 0; i < 128; i++ {
if f.Flag(i) {
s += string(i);
}
}
if w, ok := f.Width(); ok {
s += fmt.sprintf("%d", w);
}
if p, ok := f.Precision(); ok {
s += fmt.sprintf(".%d", p);
}
s += string(c);
io.WriteString(f, "["+s+"]");
}
type FlagTest struct {
in string;
out string;
}
var flagtests = []FlagTest {
FlagTest{ "%a", "[%a]" },
FlagTest{ "%-a", "[%-a]" },
FlagTest{ "%+a", "[%+a]" },
FlagTest{ "%#a", "[%#a]" },
FlagTest{ "% a", "[% a]" },
FlagTest{ "%0a", "[%0a]" },
FlagTest{ "%1.2a", "[%1.2a]" },
FlagTest{ "%-1.2a", "[%-1.2a]" },
FlagTest{ "%+1.2a", "[%+1.2a]" },
FlagTest{ "%-+1.2a", "[%+-1.2a]" },
FlagTest{ "%-+1.2abc", "[%+-1.2a]bc" },
FlagTest{ "%-1.2abc", "[%-1.2a]bc" },
}
export func TestFlagParser(t *testing.T) {
var flagprinter FlagPrinter;
for i := 0; i < len(flagtests); i++ {
tt := flagtests[i];
s := fmt.sprintf(tt.in, &flagprinter);
if s != tt.out {
t.Errorf("sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out);
}
}
}
export func TestStructPrinter(t *testing.T) {
var s struct {
a string;
b string;
c int;
};
s.a = "abc";
s.b = "def";
s.c = 123;
type Test struct {
fmt string;
out string;
}
var tests = []Test {
Test{ "%v", "{abc def 123}" },
Test{ "%+v", "{a=abc b=def c=123}" },
};
for i := 0; i < len(tests); i++ {
tt := tests[i];
out := fmt.sprintf(tt.fmt, s);
if out != tt.out {
t.Errorf("sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out);
}
}
}
......@@ -50,7 +50,9 @@ export type Fmt struct {
}
func (f *Fmt) clearflags() {
f.wid = 0;
f.wid_present = false;
f.prec = 0;
f.prec_present = false;
f.minus = false;
f.plus = false;
......
......@@ -23,6 +23,9 @@ export type Formatter interface {
Write(b *[]byte) (ret int, err *os.Error);
Width() (wid int, ok bool);
Precision() (prec int, ok bool);
// flags
Flag(int) bool;
}
type Format interface {
......@@ -40,10 +43,6 @@ type P struct {
n int;
buf *[]byte;
fmt *Fmt;
wid int;
wid_ok bool;
prec int;
prec_ok bool;
}
func Printer() *P {
......@@ -53,11 +52,27 @@ func Printer() *P {
}
func (p *P) Width() (wid int, ok bool) {
return p.wid, p.wid_ok
return p.fmt.wid, p.fmt.wid_present
}
func (p *P) Precision() (prec int, ok bool) {
return p.prec, p.prec_ok
return p.fmt.prec, p.fmt.prec_present
}
func (p *P) Flag(b int) bool {
switch b {
case '-':
return p.fmt.minus;
case '+':
return p.fmt.plus;
case '#':
return p.fmt.sharp;
case ' ':
return p.fmt.space;
case '0':
return p.fmt.zero;
}
return false
}
func (p *P) ensure(n int) {
......@@ -369,7 +384,21 @@ func (p *P) printField(field reflect.Value) (was_string bool) {
}
case reflect.StructKind:
p.add('{');
p.doprint(field, true, false);
v := field.(reflect.StructValue);
t := v.Type().(reflect.StructType);
donames := p.fmt.plus; // first p.printField clears flag
for i := 0; i < v.Len(); i++ {
if i > 0 {
p.add(' ')
}
if donames {
if name, typ, tag, off := t.Field(i); name != "" {
p.addstr(name);
p.add('=');
}
}
p.printField(getField(v, i));
}
p.add('}');
case reflect.InterfaceKind:
inter := field.(reflect.InterfaceValue).Get();
......@@ -398,7 +427,8 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
continue;
}
i++;
// flags
// flags and widths
p.fmt.clearflags();
F: for ; i < end; i++ {
switch format[i] {
case '#':
......@@ -416,11 +446,10 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
}
}
// do we have 20 (width)?
p.wid, p.wid_ok, i = parsenum(format, i, end);
p.prec_ok = false;
p.fmt.wid, p.fmt.wid_present, i = parsenum(format, i, end);
// do we have .20 (precision)?
if i < end && format[i] == '.' {
p.prec, p.prec_ok, i = parsenum(format, i+1, end);
p.fmt.prec, p.fmt.prec_present, i = parsenum(format, i+1, end);
}
c, w = sys.stringtorune(format, i);
i += w;
......@@ -445,12 +474,6 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
}
}
s := "";
if p.wid_ok {
p.fmt.w(p.wid);
}
if p.prec_ok {
p.fmt.p(p.prec);
}
switch c {
// bool
case 't':
......
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