| OLD | NEW |
| 1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
| 3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package fmt | 5 package fmt |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "bytes" | 8 "bytes" |
| 9 "io" | 9 "io" |
| 10 "os" | 10 "os" |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 p.doPrint(a, true, true) | 249 p.doPrint(a, true, true) |
| 250 s := p.buf.String() | 250 s := p.buf.String() |
| 251 p.free() | 251 p.free() |
| 252 return s | 252 return s |
| 253 } | 253 } |
| 254 | 254 |
| 255 | 255 |
| 256 // Get the i'th arg of the struct value. | 256 // Get the i'th arg of the struct value. |
| 257 // If the arg itself is an interface, return a value for | 257 // If the arg itself is an interface, return a value for |
| 258 // the thing inside the interface, not the interface itself. | 258 // the thing inside the interface, not the interface itself. |
| 259 func getField(v *reflect.StructValue, i int) reflect.Value { | 259 func getField(v reflect.Value, i int) reflect.Value { |
| 260 val := v.Field(i) | 260 val := v.Field(i) |
| 261 » if i, ok := val.(*reflect.InterfaceValue); ok { | 261 » if i := val; i.Kind() == reflect.Interface { |
| 262 if inter := i.Interface(); inter != nil { | 262 if inter := i.Interface(); inter != nil { |
| 263 return reflect.NewValue(inter) | 263 return reflect.NewValue(inter) |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 return val | 266 return val |
| 267 } | 267 } |
| 268 | 268 |
| 269 // Convert ASCII to integer. n is 0 (and got is false) if no number present. | 269 // Convert ASCII to integer. n is 0 (and got is false) if no number present. |
| 270 func parsenum(s string, start, end int) (num int, isnum bool, newi int) { | 270 func parsenum(s string, start, end int) (num int, isnum bool, newi int) { |
| 271 if start >= end { | 271 if start >= end { |
| 272 return 0, false, end | 272 return 0, false, end |
| 273 } | 273 } |
| 274 for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++
{ | 274 for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++
{ |
| 275 num = num*10 + int(s[newi]-'0') | 275 num = num*10 + int(s[newi]-'0') |
| 276 isnum = true | 276 isnum = true |
| 277 } | 277 } |
| 278 return | 278 return |
| 279 } | |
| 280 | |
| 281 // Reflection values like reflect.FuncValue implement this method. We use it for
%p. | |
| 282 type uintptrGetter interface { | |
| 283 Get() uintptr | |
| 284 } | 279 } |
| 285 | 280 |
| 286 func (p *pp) unknownType(v interface{}) { | 281 func (p *pp) unknownType(v interface{}) { |
| 287 if v == nil { | 282 if v == nil { |
| 288 p.buf.Write(nilAngleBytes) | 283 p.buf.Write(nilAngleBytes) |
| 289 return | 284 return |
| 290 } | 285 } |
| 291 p.buf.WriteByte('?') | 286 p.buf.WriteByte('?') |
| 292 p.buf.WriteString(reflect.Typeof(v).String()) | 287 p.buf.WriteString(reflect.Typeof(v).String()) |
| 293 p.buf.WriteByte('?') | 288 p.buf.WriteByte('?') |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 p.fmt.fmt_sX(s) | 509 p.fmt.fmt_sX(s) |
| 515 case 'q': | 510 case 'q': |
| 516 p.fmt.fmt_q(s) | 511 p.fmt.fmt_q(s) |
| 517 default: | 512 default: |
| 518 p.badVerb(verb, value) | 513 p.badVerb(verb, value) |
| 519 } | 514 } |
| 520 } | 515 } |
| 521 | 516 |
| 522 func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSynt
ax bool) { | 517 func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSynt
ax bool) { |
| 523 var u uintptr | 518 var u uintptr |
| 524 » switch value.(type) { | 519 » switch value.Kind() { |
| 525 » case *reflect.ChanValue, *reflect.FuncValue, *reflect.MapValue, *reflect
.PtrValue, *reflect.SliceValue, *reflect.UnsafePointerValue: | 520 » case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice
, reflect.UnsafePointer: |
| 526 » » u = value.(uintptrGetter).Get() | 521 » » u = value.Pointer() |
| 527 default: | 522 default: |
| 528 p.badVerb(verb, field) | 523 p.badVerb(verb, field) |
| 529 return | 524 return |
| 530 } | 525 } |
| 531 if goSyntax { | 526 if goSyntax { |
| 532 p.add('(') | 527 p.add('(') |
| 533 p.buf.WriteString(reflect.Typeof(field).String()) | 528 p.buf.WriteString(reflect.Typeof(field).String()) |
| 534 p.add(')') | 529 p.add(')') |
| 535 p.add('(') | 530 p.add('(') |
| 536 if u == 0 { | 531 if u == 0 { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 return verb == 's' || verb == 'v' | 647 return verb == 's' || verb == 'v' |
| 653 case []byte: | 648 case []byte: |
| 654 p.fmtBytes(f, verb, goSyntax, depth, field) | 649 p.fmtBytes(f, verb, goSyntax, depth, field) |
| 655 return verb == 's' | 650 return verb == 's' |
| 656 } | 651 } |
| 657 | 652 |
| 658 // Need to use reflection | 653 // Need to use reflection |
| 659 value := reflect.NewValue(field) | 654 value := reflect.NewValue(field) |
| 660 | 655 |
| 661 BigSwitch: | 656 BigSwitch: |
| 662 » switch f := value.(type) { | 657 » switch f := value; f.Kind() { |
| 663 » case *reflect.BoolValue: | 658 » case reflect.Bool: |
| 664 » » p.fmtBool(f.Get(), verb, field) | 659 » » p.fmtBool(f.Bool(), verb, field) |
| 665 » case *reflect.IntValue: | 660 » case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In
t64: |
| 666 » » p.fmtInt64(f.Get(), verb, field) | 661 » » p.fmtInt64(f.Int(), verb, field) |
| 667 » case *reflect.UintValue: | 662 » case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflec
t.Uint64, reflect.Uintptr: |
| 668 » » p.fmtUint64(uint64(f.Get()), verb, goSyntax, field) | 663 » » p.fmtUint64(uint64(f.Uint()), verb, goSyntax, field) |
| 669 » case *reflect.FloatValue: | 664 » case reflect.Float32, reflect.Float64: |
| 670 if f.Type().Size() == 4 { | 665 if f.Type().Size() == 4 { |
| 671 » » » p.fmtFloat32(float32(f.Get()), verb, field) | 666 » » » p.fmtFloat32(float32(f.Float()), verb, field) |
| 672 } else { | 667 } else { |
| 673 » » » p.fmtFloat64(float64(f.Get()), verb, field) | 668 » » » p.fmtFloat64(float64(f.Float()), verb, field) |
| 674 } | 669 } |
| 675 » case *reflect.ComplexValue: | 670 » case reflect.Complex64, reflect.Complex128: |
| 676 if f.Type().Size() == 8 { | 671 if f.Type().Size() == 8 { |
| 677 » » » p.fmtComplex64(complex64(f.Get()), verb, field) | 672 » » » p.fmtComplex64(complex64(f.Complex()), verb, field) |
| 678 } else { | 673 } else { |
| 679 » » » p.fmtComplex128(complex128(f.Get()), verb, field) | 674 » » » p.fmtComplex128(complex128(f.Complex()), verb, field) |
| 680 } | 675 } |
| 681 » case *reflect.StringValue: | 676 » case reflect.String: |
| 682 » » p.fmtString(f.Get(), verb, goSyntax, field) | 677 » » p.fmtString(f.String(), verb, goSyntax, field) |
| 683 » case *reflect.MapValue: | 678 » case reflect.Map: |
| 684 if goSyntax { | 679 if goSyntax { |
| 685 p.buf.WriteString(f.Type().String()) | 680 p.buf.WriteString(f.Type().String()) |
| 686 p.buf.WriteByte('{') | 681 p.buf.WriteByte('{') |
| 687 } else { | 682 } else { |
| 688 p.buf.Write(mapBytes) | 683 p.buf.Write(mapBytes) |
| 689 } | 684 } |
| 690 » » keys := f.Keys() | 685 » » keys := f.MapKeys() |
| 691 for i, key := range keys { | 686 for i, key := range keys { |
| 692 if i > 0 { | 687 if i > 0 { |
| 693 if goSyntax { | 688 if goSyntax { |
| 694 p.buf.Write(commaSpaceBytes) | 689 p.buf.Write(commaSpaceBytes) |
| 695 } else { | 690 } else { |
| 696 p.buf.WriteByte(' ') | 691 p.buf.WriteByte(' ') |
| 697 } | 692 } |
| 698 } | 693 } |
| 699 p.printField(key.Interface(), verb, plus, goSyntax, dept
h+1) | 694 p.printField(key.Interface(), verb, plus, goSyntax, dept
h+1) |
| 700 p.buf.WriteByte(':') | 695 p.buf.WriteByte(':') |
| 701 » » » p.printField(f.Elem(key).Interface(), verb, plus, goSynt
ax, depth+1) | 696 » » » p.printField(f.MapIndex(key).Interface(), verb, plus, go
Syntax, depth+1) |
| 702 } | 697 } |
| 703 if goSyntax { | 698 if goSyntax { |
| 704 p.buf.WriteByte('}') | 699 p.buf.WriteByte('}') |
| 705 } else { | 700 } else { |
| 706 p.buf.WriteByte(']') | 701 p.buf.WriteByte(']') |
| 707 } | 702 } |
| 708 » case *reflect.StructValue: | 703 » case reflect.Struct: |
| 709 if goSyntax { | 704 if goSyntax { |
| 710 p.buf.WriteString(reflect.Typeof(field).String()) | 705 p.buf.WriteString(reflect.Typeof(field).String()) |
| 711 } | 706 } |
| 712 p.add('{') | 707 p.add('{') |
| 713 v := f | 708 v := f |
| 714 » » t := v.Type().(*reflect.StructType) | 709 » » t := v.Type() |
| 715 for i := 0; i < v.NumField(); i++ { | 710 for i := 0; i < v.NumField(); i++ { |
| 716 if i > 0 { | 711 if i > 0 { |
| 717 if goSyntax { | 712 if goSyntax { |
| 718 p.buf.Write(commaSpaceBytes) | 713 p.buf.Write(commaSpaceBytes) |
| 719 } else { | 714 } else { |
| 720 p.buf.WriteByte(' ') | 715 p.buf.WriteByte(' ') |
| 721 } | 716 } |
| 722 } | 717 } |
| 723 if plus || goSyntax { | 718 if plus || goSyntax { |
| 724 if f := t.Field(i); f.Name != "" { | 719 if f := t.Field(i); f.Name != "" { |
| 725 p.buf.WriteString(f.Name) | 720 p.buf.WriteString(f.Name) |
| 726 p.buf.WriteByte(':') | 721 p.buf.WriteByte(':') |
| 727 } | 722 } |
| 728 } | 723 } |
| 729 p.printField(getField(v, i).Interface(), verb, plus, goS
yntax, depth+1) | 724 p.printField(getField(v, i).Interface(), verb, plus, goS
yntax, depth+1) |
| 730 } | 725 } |
| 731 p.buf.WriteByte('}') | 726 p.buf.WriteByte('}') |
| 732 » case *reflect.InterfaceValue: | 727 » case reflect.Interface: |
| 733 value := f.Elem() | 728 value := f.Elem() |
| 734 » » if value == nil { | 729 » » if !value.IsValid() { |
| 735 if goSyntax { | 730 if goSyntax { |
| 736 p.buf.WriteString(reflect.Typeof(field).String()
) | 731 p.buf.WriteString(reflect.Typeof(field).String()
) |
| 737 p.buf.Write(nilParenBytes) | 732 p.buf.Write(nilParenBytes) |
| 738 } else { | 733 } else { |
| 739 p.buf.Write(nilAngleBytes) | 734 p.buf.Write(nilAngleBytes) |
| 740 } | 735 } |
| 741 } else { | 736 } else { |
| 742 return p.printField(value.Interface(), verb, plus, goSyn
tax, depth+1) | 737 return p.printField(value.Interface(), verb, plus, goSyn
tax, depth+1) |
| 743 } | 738 } |
| 744 » case reflect.ArrayOrSliceValue: | 739 » case reflect.Array, reflect.Slice: |
| 745 // Byte slices are special. | 740 // Byte slices are special. |
| 746 » » if f.Type().(reflect.ArrayOrSliceType).Elem().Kind() == reflect.
Uint8 { | 741 » » if f.Type().Elem().Kind() == reflect.Uint8 { |
| 747 // We know it's a slice of bytes, but we also know it do
es not have static type | 742 // We know it's a slice of bytes, but we also know it do
es not have static type |
| 748 // []byte, or it would have been caught above. Therefor
e we cannot convert | 743 // []byte, or it would have been caught above. Therefor
e we cannot convert |
| 749 // it directly in the (slightly) obvious way: f.Interfac
e().([]byte); it doesn't have | 744 // it directly in the (slightly) obvious way: f.Interfac
e().([]byte); it doesn't have |
| 750 // that type, and we can't write an expression of the ri
ght type and do a | 745 // that type, and we can't write an expression of the ri
ght type and do a |
| 751 // conversion because we don't have a static way to writ
e the right type. | 746 // conversion because we don't have a static way to writ
e the right type. |
| 752 // So we build a slice by hand. This is a rare case but
it would be nice | 747 // So we build a slice by hand. This is a rare case but
it would be nice |
| 753 // if reflection could help a little more. | 748 // if reflection could help a little more. |
| 754 bytes := make([]byte, f.Len()) | 749 bytes := make([]byte, f.Len()) |
| 755 for i := range bytes { | 750 for i := range bytes { |
| 756 » » » » bytes[i] = byte(f.Elem(i).(*reflect.UintValue).G
et()) | 751 » » » » bytes[i] = byte(f.Index(i).Uint()) |
| 757 } | 752 } |
| 758 p.fmtBytes(bytes, verb, goSyntax, depth, field) | 753 p.fmtBytes(bytes, verb, goSyntax, depth, field) |
| 759 return verb == 's' | 754 return verb == 's' |
| 760 } | 755 } |
| 761 if goSyntax { | 756 if goSyntax { |
| 762 p.buf.WriteString(reflect.Typeof(field).String()) | 757 p.buf.WriteString(reflect.Typeof(field).String()) |
| 763 p.buf.WriteByte('{') | 758 p.buf.WriteByte('{') |
| 764 } else { | 759 } else { |
| 765 p.buf.WriteByte('[') | 760 p.buf.WriteByte('[') |
| 766 } | 761 } |
| 767 for i := 0; i < f.Len(); i++ { | 762 for i := 0; i < f.Len(); i++ { |
| 768 if i > 0 { | 763 if i > 0 { |
| 769 if goSyntax { | 764 if goSyntax { |
| 770 p.buf.Write(commaSpaceBytes) | 765 p.buf.Write(commaSpaceBytes) |
| 771 } else { | 766 } else { |
| 772 p.buf.WriteByte(' ') | 767 p.buf.WriteByte(' ') |
| 773 } | 768 } |
| 774 } | 769 } |
| 775 » » » p.printField(f.Elem(i).Interface(), verb, plus, goSyntax
, depth+1) | 770 » » » p.printField(f.Index(i).Interface(), verb, plus, goSynta
x, depth+1) |
| 776 } | 771 } |
| 777 if goSyntax { | 772 if goSyntax { |
| 778 p.buf.WriteByte('}') | 773 p.buf.WriteByte('}') |
| 779 } else { | 774 } else { |
| 780 p.buf.WriteByte(']') | 775 p.buf.WriteByte(']') |
| 781 } | 776 } |
| 782 » case *reflect.PtrValue: | 777 » case reflect.Ptr: |
| 783 » » v := f.Get() | 778 » » v := f.Pointer() |
| 784 // pointer to array or slice or struct? ok at top level | 779 // pointer to array or slice or struct? ok at top level |
| 785 // but not embedded (avoid loops) | 780 // but not embedded (avoid loops) |
| 786 if v != 0 && depth == 0 { | 781 if v != 0 && depth == 0 { |
| 787 » » » switch a := f.Elem().(type) { | 782 » » » switch a := f.Elem(); a.Kind() { |
| 788 » » » case reflect.ArrayOrSliceValue: | 783 » » » case reflect.Array, reflect.Slice: |
| 789 p.buf.WriteByte('&') | 784 p.buf.WriteByte('&') |
| 790 p.printField(a.Interface(), verb, plus, goSyntax
, depth+1) | 785 p.printField(a.Interface(), verb, plus, goSyntax
, depth+1) |
| 791 break BigSwitch | 786 break BigSwitch |
| 792 » » » case *reflect.StructValue: | 787 » » » case reflect.Struct: |
| 793 p.buf.WriteByte('&') | 788 p.buf.WriteByte('&') |
| 794 p.printField(a.Interface(), verb, plus, goSyntax
, depth+1) | 789 p.printField(a.Interface(), verb, plus, goSyntax
, depth+1) |
| 795 break BigSwitch | 790 break BigSwitch |
| 796 } | 791 } |
| 797 } | 792 } |
| 798 if goSyntax { | 793 if goSyntax { |
| 799 p.buf.WriteByte('(') | 794 p.buf.WriteByte('(') |
| 800 p.buf.WriteString(reflect.Typeof(field).String()) | 795 p.buf.WriteString(reflect.Typeof(field).String()) |
| 801 p.buf.WriteByte(')') | 796 p.buf.WriteByte(')') |
| 802 p.buf.WriteByte('(') | 797 p.buf.WriteByte('(') |
| 803 if v == 0 { | 798 if v == 0 { |
| 804 p.buf.Write(nilBytes) | 799 p.buf.Write(nilBytes) |
| 805 } else { | 800 } else { |
| 806 p.fmt0x64(uint64(v), true) | 801 p.fmt0x64(uint64(v), true) |
| 807 } | 802 } |
| 808 p.buf.WriteByte(')') | 803 p.buf.WriteByte(')') |
| 809 break | 804 break |
| 810 } | 805 } |
| 811 if v == 0 { | 806 if v == 0 { |
| 812 p.buf.Write(nilAngleBytes) | 807 p.buf.Write(nilAngleBytes) |
| 813 break | 808 break |
| 814 } | 809 } |
| 815 p.fmt0x64(uint64(v), true) | 810 p.fmt0x64(uint64(v), true) |
| 816 » case *reflect.ChanValue, *reflect.FuncValue, *reflect.UnsafePointerValue
: | 811 » case reflect.Chan, reflect.Func, reflect.UnsafePointer: |
| 817 p.fmtPointer(field, value, verb, goSyntax) | 812 p.fmtPointer(field, value, verb, goSyntax) |
| 818 default: | 813 default: |
| 819 p.unknownType(f) | 814 p.unknownType(f) |
| 820 } | 815 } |
| 821 return false | 816 return false |
| 822 } | 817 } |
| 823 | 818 |
| 824 // intFromArg gets the fieldnumth element of a. On return, isInt reports whether
the argument has type int. | 819 // intFromArg gets the fieldnumth element of a. On return, isInt reports whether
the argument has type int. |
| 825 func intFromArg(a []interface{}, end, i, fieldnum int) (num int, isInt bool, new
i, newfieldnum int) { | 820 func intFromArg(a []interface{}, end, i, fieldnum int) (num int, isInt bool, new
i, newfieldnum int) { |
| 826 newi, newfieldnum = end, fieldnum | 821 newi, newfieldnum = end, fieldnum |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 if addspace || !isString && !prevString { | 936 if addspace || !isString && !prevString { |
| 942 p.buf.WriteByte(' ') | 937 p.buf.WriteByte(' ') |
| 943 } | 938 } |
| 944 } | 939 } |
| 945 prevString = p.printField(field, 'v', false, false, 0) | 940 prevString = p.printField(field, 'v', false, false, 0) |
| 946 } | 941 } |
| 947 if addnewline { | 942 if addnewline { |
| 948 p.buf.WriteByte('\n') | 943 p.buf.WriteByte('\n') |
| 949 } | 944 } |
| 950 } | 945 } |
| OLD | NEW |