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 } | 279 } |
280 | 280 |
281 // Reflection values like reflect.FuncValue implement this method. We use it for
%p. | |
282 type uintptrGetter interface { | |
283 Get() uintptr | |
284 } | |
285 | |
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('?') |
294 } | 289 } |
295 | 290 |
(...skipping 218 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 |