Commit 0d400a7d authored by Russ Cox's avatar Russ Cox

fmt: use new reflect interface (CL 31107)

R=r
DELTA=208  (37 added, 63 deleted, 108 changed)
OCL=31111
CL=31281
parent 64f4e0b1
...@@ -57,6 +57,13 @@ ...@@ -57,6 +57,13 @@
operand. Another variant Println inserts blanks between operand. Another variant Println inserts blanks between
operands and appends a newline. operands and appends a newline.
Regardless of the verb, if an operand is an interface value,
the internal concrete value is used, not the interface itself.
Thus:
var i interface{} = 23;
fmt.Printf("%v\n", i);
will print 23.
If an operand implements interface Format, that interface If an operand implements interface Format, that interface
can be used for fine control of formatting. can be used for fine control of formatting.
...@@ -191,14 +198,14 @@ func (p *pp) Write(b []byte) (ret int, err os.Error) { ...@@ -191,14 +198,14 @@ func (p *pp) Write(b []byte) (ret int, err os.Error) {
return len(b), nil; return len(b), nil;
} }
func (p *pp) doprintf(format string, v reflect.StructValue); func (p *pp) doprintf(format string, v *reflect.StructValue);
func (p *pp) doprint(v reflect.StructValue, addspace, addnewline bool); func (p *pp) doprint(v *reflect.StructValue, addspace, addnewline bool);
// These routines end in 'f' and take a format string. // These routines end in 'f' and take a format string.
// Fprintf formats according to a format specifier and writes to w. // Fprintf formats according to a format specifier and writes to w.
func Fprintf(w io.Writer, format string, a ...) (n int, error os.Error) { func Fprintf(w io.Writer, format string, a ...) (n int, error os.Error) {
v := reflect.NewValue(a).(reflect.StructValue); v := reflect.NewValue(a).(*reflect.StructValue);
p := newPrinter(); p := newPrinter();
p.doprintf(format, v); p.doprintf(format, v);
n, error = w.Write(p.buf[0:p.n]); n, error = w.Write(p.buf[0:p.n]);
...@@ -213,7 +220,7 @@ func Printf(format string, v ...) (n int, errno os.Error) { ...@@ -213,7 +220,7 @@ func Printf(format string, v ...) (n int, errno os.Error) {
// Sprintf formats according to a format specifier and returns the resulting string. // Sprintf formats according to a format specifier and returns the resulting string.
func Sprintf(format string, a ...) string { func Sprintf(format string, a ...) string {
v := reflect.NewValue(a).(reflect.StructValue); v := reflect.NewValue(a).(*reflect.StructValue);
p := newPrinter(); p := newPrinter();
p.doprintf(format, v); p.doprintf(format, v);
s := string(p.buf)[0 : p.n]; s := string(p.buf)[0 : p.n];
...@@ -225,7 +232,7 @@ func Sprintf(format string, a ...) string { ...@@ -225,7 +232,7 @@ func Sprintf(format string, a ...) string {
// Fprint formats using the default formats for its operands and writes to w. // Fprint formats using the default formats for its operands and writes to w.
// Spaces are added between operands when neither is a string. // Spaces are added between operands when neither is a string.
func Fprint(w io.Writer, a ...) (n int, error os.Error) { func Fprint(w io.Writer, a ...) (n int, error os.Error) {
v := reflect.NewValue(a).(reflect.StructValue); v := reflect.NewValue(a).(*reflect.StructValue);
p := newPrinter(); p := newPrinter();
p.doprint(v, false, false); p.doprint(v, false, false);
n, error = w.Write(p.buf[0:p.n]); n, error = w.Write(p.buf[0:p.n]);
...@@ -242,7 +249,7 @@ func Print(v ...) (n int, errno os.Error) { ...@@ -242,7 +249,7 @@ func Print(v ...) (n int, errno os.Error) {
// Sprint formats using the default formats for its operands and returns the resulting string. // Sprint formats using the default formats for its operands and returns the resulting string.
// Spaces are added between operands when neither is a string. // Spaces are added between operands when neither is a string.
func Sprint(a ...) string { func Sprint(a ...) string {
v := reflect.NewValue(a).(reflect.StructValue); v := reflect.NewValue(a).(*reflect.StructValue);
p := newPrinter(); p := newPrinter();
p.doprint(v, false, false); p.doprint(v, false, false);
s := string(p.buf)[0 : p.n]; s := string(p.buf)[0 : p.n];
...@@ -256,7 +263,7 @@ func Sprint(a ...) string { ...@@ -256,7 +263,7 @@ func Sprint(a ...) string {
// Fprintln formats using the default formats for its operands and writes to w. // Fprintln formats using the default formats for its operands and writes to w.
// Spaces are always added between operands and a newline is appended. // Spaces are always added between operands and a newline is appended.
func Fprintln(w io.Writer, a ...) (n int, error os.Error) { func Fprintln(w io.Writer, a ...) (n int, error os.Error) {
v := reflect.NewValue(a).(reflect.StructValue); v := reflect.NewValue(a).(*reflect.StructValue);
p := newPrinter(); p := newPrinter();
p.doprint(v, true, true); p.doprint(v, true, true);
n, error = w.Write(p.buf[0:p.n]); n, error = w.Write(p.buf[0:p.n]);
...@@ -273,7 +280,7 @@ func Println(v ...) (n int, errno os.Error) { ...@@ -273,7 +280,7 @@ func Println(v ...) (n int, errno os.Error) {
// Sprintln formats using the default formats for its operands and returns the resulting string. // Sprintln formats using the default formats for its operands and returns the resulting string.
// Spaces are always added between operands and a newline is appended. // Spaces are always added between operands and a newline is appended.
func Sprintln(a ...) string { func Sprintln(a ...) string {
v := reflect.NewValue(a).(reflect.StructValue); v := reflect.NewValue(a).(*reflect.StructValue);
p := newPrinter(); p := newPrinter();
p.doprint(v, true, true); p.doprint(v, true, true);
s := string(p.buf)[0 : p.n]; s := string(p.buf)[0 : p.n];
...@@ -284,113 +291,93 @@ func Sprintln(a ...) string { ...@@ -284,113 +291,93 @@ func Sprintln(a ...) string {
// Get the i'th arg of the struct value. // Get the i'th arg of the struct value.
// If the arg itself is an interface, return a value for // If the arg itself is an interface, return a value for
// the thing inside the interface, not the interface itself. // the thing inside the interface, not the interface itself.
func getField(v reflect.StructValue, i int) reflect.Value { func getField(v *reflect.StructValue, i int) reflect.Value {
val := v.Field(i); val := v.Field(i);
if val.Kind() == reflect.InterfaceKind { if i, ok := val.(*reflect.InterfaceValue); ok {
inter := val.(reflect.InterfaceValue).Get(); if inter := i.Interface(); inter != nil {
return reflect.NewValue(inter); return reflect.NewValue(inter);
} }
}
return val; return val;
} }
// Getters for the fields of the argument structure. // Getters for the fields of the argument structure.
func getBool(v reflect.Value) (val bool, ok bool) { func getBool(v reflect.Value) (val bool, ok bool) {
switch v.Kind() { if b, ok := v.(*reflect.BoolValue); ok {
case reflect.BoolKind: return b.Get(), true;
return v.(reflect.BoolValue).Get(), true;
} }
return false, false return;
} }
func getInt(v reflect.Value) (val int64, signed, ok bool) { func getInt(v reflect.Value) (val int64, signed, ok bool) {
switch v.Kind() { switch v := v.(type) {
case reflect.IntKind: case *reflect.IntValue:
return int64(v.(reflect.IntValue).Get()), true, true; return int64(v.Get()), true, true;
case reflect.Int8Kind: case *reflect.Int8Value:
return int64(v.(reflect.Int8Value).Get()), true, true; return int64(v.Get()), true, true;
case reflect.Int16Kind: case *reflect.Int16Value:
return int64(v.(reflect.Int16Value).Get()), true, true; return int64(v.Get()), true, true;
case reflect.Int32Kind: case *reflect.Int32Value:
return int64(v.(reflect.Int32Value).Get()), true, true; return int64(v.Get()), true, true;
case reflect.Int64Kind: case *reflect.Int64Value:
return int64(v.(reflect.Int64Value).Get()), true, true; return int64(v.Get()), true, true;
case reflect.UintKind: case *reflect.UintValue:
return int64(v.(reflect.UintValue).Get()), false, true; return int64(v.Get()), false, true;
case reflect.Uint8Kind: case *reflect.Uint8Value:
return int64(v.(reflect.Uint8Value).Get()), false, true; return int64(v.Get()), false, true;
case reflect.Uint16Kind: case *reflect.Uint16Value:
return int64(v.(reflect.Uint16Value).Get()), false, true; return int64(v.Get()), false, true;
case reflect.Uint32Kind: case *reflect.Uint32Value:
return int64(v.(reflect.Uint32Value).Get()), false, true; return int64(v.Get()), false, true;
case reflect.Uint64Kind: case *reflect.Uint64Value:
return int64(v.(reflect.Uint64Value).Get()), false, true; return int64(v.Get()), false, true;
case reflect.UintptrKind: case *reflect.UintptrValue:
return int64(v.(reflect.UintptrValue).Get()), false, true; return int64(v.Get()), false, true;
} }
return 0, false, false; return;
} }
func getString(v reflect.Value) (val string, ok bool) { func getString(v reflect.Value) (val string, ok bool) {
switch v.Kind() { if v, ok := v.(*reflect.StringValue); ok {
case reflect.StringKind: return v.Get(), true;
return v.(reflect.StringValue).Get(), true;
case reflect.ArrayKind:
if val, ok := v.Interface().([]byte); ok {
return string(val), true;
} }
if bytes, ok := v.Interface().([]byte); ok {
return string(bytes), true;
} }
return "", false; return;
} }
func getFloat32(v reflect.Value) (val float32, ok bool) { func getFloat32(v reflect.Value) (val float32, ok bool) {
switch v.Kind() { switch v := v.(type) {
case reflect.Float32Kind: case *reflect.Float32Value:
return float32(v.(reflect.Float32Value).Get()), true; return float32(v.Get()), true;
case reflect.FloatKind: case *reflect.FloatValue:
if v.Type().Size()*8 == 32 { if v.Type().Size()*8 == 32 {
return float32(v.(reflect.FloatValue).Get()), true; return float32(v.Get()), true;
} }
} }
return 0.0, false; return;
} }
func getFloat64(v reflect.Value) (val float64, ok bool) { func getFloat64(v reflect.Value) (val float64, ok bool) {
switch v.Kind() { switch v := v.(type) {
case reflect.FloatKind: case *reflect.FloatValue:
if v.Type().Size()*8 == 64 { if v.Type().Size()*8 == 64 {
return float64(v.(reflect.FloatValue).Get()), true; return float64(v.Get()), true;
} }
case reflect.Float64Kind: case *reflect.Float64Value:
return float64(v.(reflect.Float64Value).Get()), true; return float64(v.Get()), true;
} }
return 0.0, false; return;
} }
func getPtr(v reflect.Value) (val uintptr, ok bool) { func getPtr(v reflect.Value) (val uintptr, ok bool) {
switch v.Kind() { switch v := v.(type) {
case reflect.PtrKind: case *reflect.PtrValue:
return uintptr(v.(reflect.PtrValue).Get()), true; return uintptr(v.Get()), true;
}
return 0, false;
}
func getArrayPtr(v reflect.Value) (val reflect.ArrayValue, ok bool) {
if v.Kind() == reflect.PtrKind {
v = v.(reflect.PtrValue).Sub();
if v.Kind() == reflect.ArrayKind {
return v.(reflect.ArrayValue), true;
} }
} return;
return nil, false;
}
func getArray(v reflect.Value) (val reflect.ArrayValue, ok bool) {
switch v.Kind() {
case reflect.ArrayKind:
return v.(reflect.ArrayValue), true;
}
return nil, false;
} }
// Convert ASCII to integer. n is 0 (and got is false) if no number present. // Convert ASCII to integer. n is 0 (and got is false) if no number present.
...@@ -418,101 +405,91 @@ func (p *pp) printField(field reflect.Value) (was_string bool) { ...@@ -418,101 +405,91 @@ func (p *pp) printField(field reflect.Value) (was_string bool) {
} }
} }
s := ""; s := "";
switch field.Kind() { switch f := field.(type) {
case reflect.BoolKind: case *reflect.BoolValue:
s = p.fmt.Fmt_boolean(field.(reflect.BoolValue).Get()).Str(); s = p.fmt.Fmt_boolean(f.Get()).Str();
case reflect.IntKind, reflect.Int8Kind, reflect.Int16Kind, reflect.Int32Kind, reflect.Int64Kind: case *reflect.Float32Value:
v, signed, ok := getInt(field); s = p.fmt.Fmt_g32(f.Get()).Str();
s = p.fmt.Fmt_d64(v).Str(); case *reflect.Float64Value:
case reflect.UintKind, reflect.Uint8Kind, reflect.Uint16Kind, reflect.Uint32Kind, reflect.Uint64Kind: s = p.fmt.Fmt_g64(f.Get()).Str();
v, signed, ok := getInt(field); case *reflect.FloatValue:
s = p.fmt.Fmt_ud64(uint64(v)).Str();
case reflect.UintptrKind:
v, signed, ok := getInt(field);
p.fmt.sharp = !p.fmt.sharp; // turn 0x on by default
s = p.fmt.Fmt_ux64(uint64(v)).Str();
case reflect.Float32Kind:
v, ok := getFloat32(field);
s = p.fmt.Fmt_g32(v).Str();
case reflect.Float64Kind:
v, ok := getFloat64(field);
s = p.fmt.Fmt_g64(v).Str();
case reflect.FloatKind:
if field.Type().Size()*8 == 32 { if field.Type().Size()*8 == 32 {
v, ok := getFloat32(field); s = p.fmt.Fmt_g32(float32(f.Get())).Str();
s = p.fmt.Fmt_g32(v).Str();
} else { } else {
v, ok := getFloat64(field); s = p.fmt.Fmt_g64(float64(f.Get())).Str();
s = p.fmt.Fmt_g64(v).Str();
} }
case reflect.StringKind: case *reflect.StringValue:
v, ok := getString(field); s = p.fmt.Fmt_s(f.Get()).Str();
s = p.fmt.Fmt_s(v).Str();
was_string = true; was_string = true;
case reflect.PtrKind: case *reflect.PtrValue:
if v, ok := getPtr(field); v == 0 { v := f.Get();
s = "<nil>" if v == 0 {
} else { s = "<nil>";
// pointer to array? (TODO(r): holdover; delete?) break;
if a, ok := getArrayPtr(field); ok {
p.addstr("&[");
for i := 0; i < a.Len(); i++ {
if i > 0 {
p.addstr(" ");
} }
p.printField(a.Elem(i)); // pointer to array?
if a, ok := f.Elem().(reflect.ArrayOrSliceValue); ok {
p.addstr("&");
p.printField(a);
break;
} }
p.addstr("]");
} else {
p.fmt.sharp = !p.fmt.sharp; // turn 0x on by default p.fmt.sharp = !p.fmt.sharp; // turn 0x on by default
s = p.fmt.Fmt_uX64(uint64(v)).Str(); s = p.fmt.Fmt_uX64(uint64(v)).Str();
} case reflect.ArrayOrSliceValue:
}
case reflect.ArrayKind:
if a, ok := getArray(field); ok {
p.addstr("["); p.addstr("[");
for i := 0; i < a.Len(); i++ { for i := 0; i < f.Len(); i++ {
if i > 0 { if i > 0 {
p.addstr(" "); p.addstr(" ");
} }
p.printField(a.Elem(i)); p.printField(f.Elem(i));
} }
p.addstr("]"); p.addstr("]");
} case *reflect.StructValue:
case reflect.StructKind:
p.add('{'); p.add('{');
v := field.(reflect.StructValue); v := f;
t := v.Type().(reflect.StructType); t := v.Type().(*reflect.StructType);
donames := p.fmt.plus; donames := p.fmt.plus;
p.fmt.clearflags(); // clear flags for p.printField p.fmt.clearflags(); // clear flags for p.printField
for i := 0; i < v.Len(); i++ { for i := 0; i < v.NumField(); i++ {
if i > 0 { if i > 0 {
p.add(' ') p.add(' ')
} }
if donames { if donames {
if name, typ, tag, off := t.Field(i); name != "" { if f := t.Field(i); f.Name != "" {
p.addstr(name); p.addstr(f.Name);
p.add('='); p.add('=');
} }
} }
p.printField(getField(v, i)); p.printField(getField(v, i));
} }
p.add('}'); p.add('}');
case reflect.InterfaceKind: case *reflect.InterfaceValue:
value := field.(reflect.InterfaceValue).Value(); value := f.Elem();
if value == nil { if value == nil {
s = "<nil>" s = "<nil>"
} else { } else {
return p.printField(value); return p.printField(value);
} }
case *reflect.UintptrValue:
p.fmt.sharp = !p.fmt.sharp; // turn 0x on by default
s = p.fmt.Fmt_ux64(uint64(f.Get())).Str();
default: default:
v, signed, ok := getInt(field);
if ok {
if signed {
s = p.fmt.Fmt_d64(v).Str();
} else {
s = p.fmt.Fmt_ud64(uint64(v)).Str();
}
break;
}
s = "?" + field.Type().String() + "?"; s = "?" + field.Type().String() + "?";
} }
p.addstr(s); p.addstr(s);
return was_string; return was_string;
} }
func (p *pp) doprintf(format string, v reflect.StructValue) { func (p *pp) doprintf(format string, v *reflect.StructValue) {
p.ensure(len(format)); // a good starting size p.ensure(len(format)); // a good starting size
end := len(format) - 1; end := len(format) - 1;
fieldnum := 0; // we process one field per non-trivial format fieldnum := 0; // we process one field per non-trivial format
...@@ -555,7 +532,7 @@ func (p *pp) doprintf(format string, v reflect.StructValue) { ...@@ -555,7 +532,7 @@ func (p *pp) doprintf(format string, v reflect.StructValue) {
p.add('%'); // TODO: should we bother with width & prec? p.add('%'); // TODO: should we bother with width & prec?
continue; continue;
} }
if fieldnum >= v.Len() { // out of operands if fieldnum >= v.NumField() { // out of operands
p.add('%'); p.add('%');
p.add(c); p.add(c);
p.addstr("(missing)"); p.addstr("(missing)");
...@@ -719,11 +696,11 @@ func (p *pp) doprintf(format string, v reflect.StructValue) { ...@@ -719,11 +696,11 @@ func (p *pp) doprintf(format string, v reflect.StructValue) {
} }
p.addstr(s); p.addstr(s);
} }
if fieldnum < v.Len() { if fieldnum < v.NumField() {
p.addstr("?(extra "); p.addstr("?(extra ");
for ; fieldnum < v.Len(); fieldnum++ { for ; fieldnum < v.NumField(); fieldnum++ {
p.addstr(getField(v, fieldnum).Type().String()); p.addstr(getField(v, fieldnum).Type().String());
if fieldnum + 1 < v.Len() { if fieldnum + 1 < v.NumField() {
p.addstr(", "); p.addstr(", ");
} }
} }
...@@ -731,21 +708,18 @@ func (p *pp) doprintf(format string, v reflect.StructValue) { ...@@ -731,21 +708,18 @@ func (p *pp) doprintf(format string, v reflect.StructValue) {
} }
} }
func (p *pp) doprint(v reflect.StructValue, addspace, addnewline bool) { func (p *pp) doprint(v *reflect.StructValue, addspace, addnewline bool) {
prev_string := false; prev_string := false;
for fieldnum := 0; fieldnum < v.Len(); fieldnum++ { for fieldnum := 0; fieldnum < v.NumField(); fieldnum++ {
// always add spaces if we're doing println // always add spaces if we're doing println
field := getField(v, fieldnum); field := getField(v, fieldnum);
if fieldnum > 0 { if fieldnum > 0 {
if addspace { _, is_string := field.(*reflect.StringValue);
p.add(' ') if addspace || !is_string && !prev_string {
} else if field.Kind() != reflect.StringKind && !prev_string{ p.add(' ');
// if not doing println, add spaces if neither side is a string
p.add(' ')
} }
} }
was_string := p.printField(field); prev_string = p.printField(field);
prev_string = was_string;
} }
if addnewline { if addnewline {
p.add('\n') p.add('\n')
......
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