mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
add a %v format to print an arbitrary value in its "println" form.
also add code to print (pointers to) arrays, through %v. R=rsc DELTA=108 (70 added, 33 deleted, 5 changed) OCL=19184 CL=19192
This commit is contained in:
parent
e4f4ab0b8d
commit
e2621b8037
1 changed files with 75 additions and 38 deletions
|
|
@ -255,6 +255,16 @@ func getPtr(v reflect.Value) (val uint64, ok bool) {
|
||||||
return 0, false;
|
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 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.
|
||||||
|
|
||||||
func parsenum(s string, start, end int) (n int, got bool, newi int) {
|
func parsenum(s string, start, end int) (n int, got bool, newi int) {
|
||||||
|
|
@ -277,6 +287,56 @@ func parsenum(s string, start, end int) (n int, got bool, newi int) {
|
||||||
return num, isnum, start;
|
return num, isnum, start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *P) printField(field reflect.Value) (was_string bool) {
|
||||||
|
if stringer, ok := field.Interface().(String); ok {
|
||||||
|
p.addstr(stringer.String());
|
||||||
|
return false; // this value is not a string
|
||||||
|
}
|
||||||
|
s := "";
|
||||||
|
switch field.Kind() {
|
||||||
|
case reflect.BoolKind:
|
||||||
|
s = p.fmt.boolean(field.(reflect.BoolValue).Get()).str();
|
||||||
|
case reflect.IntKind, reflect.Int8Kind, reflect.Int16Kind, reflect.Int32Kind, reflect.Int64Kind:
|
||||||
|
v, signed, ok := getInt(field);
|
||||||
|
s = p.fmt.d64(v).str();
|
||||||
|
case reflect.UintKind, reflect.Uint8Kind, reflect.Uint16Kind, reflect.Uint32Kind, reflect.Uint64Kind:
|
||||||
|
v, signed, ok := getInt(field);
|
||||||
|
s = p.fmt.ud64(uint64(v)).str();
|
||||||
|
case reflect.FloatKind, reflect.Float32Kind, reflect.Float64Kind, reflect.Float80Kind:
|
||||||
|
v, ok := getFloat(field);
|
||||||
|
s = p.fmt.g64(v).str();
|
||||||
|
case reflect.StringKind:
|
||||||
|
v, ok := getString(field);
|
||||||
|
s = p.fmt.s(v).str();
|
||||||
|
was_string = true;
|
||||||
|
case reflect.PtrKind:
|
||||||
|
// pointer to array?
|
||||||
|
if v, ok := getArrayPtr(field); ok {
|
||||||
|
p.addstr("&[");
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
if i > 0 {
|
||||||
|
p.addstr(" ");
|
||||||
|
}
|
||||||
|
p.printField(v.Elem(i));
|
||||||
|
}
|
||||||
|
p.addstr("]");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
v, ok := getPtr(field);
|
||||||
|
p.add('0');
|
||||||
|
p.add('x');
|
||||||
|
s = p.fmt.uX64(v).str();
|
||||||
|
case reflect.StructKind:
|
||||||
|
p.add('{');
|
||||||
|
p.doprint(field, true, false);
|
||||||
|
p.add('}');
|
||||||
|
default:
|
||||||
|
s = "?" + field.Type().String() + "?";
|
||||||
|
}
|
||||||
|
p.addstr(s);
|
||||||
|
return was_string;
|
||||||
|
}
|
||||||
|
|
||||||
func (p *P) doprintf(format string, v reflect.StructValue) {
|
func (p *P) 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;
|
||||||
|
|
@ -310,9 +370,11 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
|
||||||
}
|
}
|
||||||
field := v.Field(fieldnum);
|
field := v.Field(fieldnum);
|
||||||
fieldnum++;
|
fieldnum++;
|
||||||
if formatter, ok := field.Interface().(Format); ok {
|
if c != 'T' { // don't want thing to describe itself if we're asking for its type
|
||||||
formatter.Format(p, c);
|
if formatter, ok := field.Interface().(Format); ok {
|
||||||
continue;
|
formatter.Format(p, c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s := "";
|
s := "";
|
||||||
if p.wid_ok {
|
if p.wid_ok {
|
||||||
|
|
@ -414,6 +476,14 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
|
||||||
goto badtype
|
goto badtype
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// arbitrary value; do your best
|
||||||
|
case 'v':
|
||||||
|
p.printField(field);
|
||||||
|
|
||||||
|
// the value's type
|
||||||
|
case 'T':
|
||||||
|
s = field.Type().String();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
badtype:
|
badtype:
|
||||||
s = "%" + string(c) + "(" + field.Type().String() + ")%";
|
s = "%" + string(c) + "(" + field.Type().String() + ")%";
|
||||||
|
|
@ -437,7 +507,6 @@ func (p *P) doprint(v reflect.StructValue, addspace, addnewline bool) {
|
||||||
for fieldnum := 0; fieldnum < v.Len(); fieldnum++ {
|
for fieldnum := 0; fieldnum < v.Len(); fieldnum++ {
|
||||||
// always add spaces if we're doing println
|
// always add spaces if we're doing println
|
||||||
field := v.Field(fieldnum);
|
field := v.Field(fieldnum);
|
||||||
s := "";
|
|
||||||
if fieldnum > 0 {
|
if fieldnum > 0 {
|
||||||
if addspace {
|
if addspace {
|
||||||
p.add(' ')
|
p.add(' ')
|
||||||
|
|
@ -446,40 +515,8 @@ func (p *P) doprint(v reflect.StructValue, addspace, addnewline bool) {
|
||||||
p.add(' ')
|
p.add(' ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if stringer, ok := field.Interface().(String); ok {
|
was_string := p.printField(field);
|
||||||
p.addstr(stringer.String());
|
prev_string = was_string;
|
||||||
prev_string = false; // this value is not a string
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch field.Kind() {
|
|
||||||
case reflect.BoolKind:
|
|
||||||
s = p.fmt.boolean(field.(reflect.BoolValue).Get()).str();
|
|
||||||
case reflect.IntKind, reflect.Int8Kind, reflect.Int16Kind, reflect.Int32Kind, reflect.Int64Kind:
|
|
||||||
v, signed, ok := getInt(field);
|
|
||||||
s = p.fmt.d64(v).str();
|
|
||||||
case reflect.UintKind, reflect.Uint8Kind, reflect.Uint16Kind, reflect.Uint32Kind, reflect.Uint64Kind:
|
|
||||||
v, signed, ok := getInt(field);
|
|
||||||
s = p.fmt.ud64(uint64(v)).str();
|
|
||||||
case reflect.FloatKind, reflect.Float32Kind, reflect.Float64Kind, reflect.Float80Kind:
|
|
||||||
v, ok := getFloat(field);
|
|
||||||
s = p.fmt.g64(v).str();
|
|
||||||
case reflect.StringKind:
|
|
||||||
v, ok := getString(field);
|
|
||||||
s = p.fmt.s(v).str();
|
|
||||||
case reflect.PtrKind:
|
|
||||||
v, ok := getPtr(field);
|
|
||||||
p.add('0');
|
|
||||||
p.add('x');
|
|
||||||
s = p.fmt.uX64(v).str();
|
|
||||||
case reflect.StructKind:
|
|
||||||
p.add('{');
|
|
||||||
p.doprint(field, true, false);
|
|
||||||
p.add('}');
|
|
||||||
default:
|
|
||||||
s = "?" + field.Type().String() + "?";
|
|
||||||
}
|
|
||||||
p.addstr(s);
|
|
||||||
prev_string = field.Kind() == reflect.StringKind;
|
|
||||||
}
|
}
|
||||||
if addnewline {
|
if addnewline {
|
||||||
p.add('\n')
|
p.add('\n')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue