11package errors
22
33import (
4- "bytes"
54 "fmt"
65 "io"
76 "path"
@@ -11,6 +10,8 @@ import (
1110)
1211
1312// Frame represents a program counter inside a stack frame.
13+ // For historical reasons if Frame is interpreted as a uintptr
14+ // its value represents the program counter + 1.
1415type Frame uintptr
1516
1617// pc returns the program counter for this frame;
@@ -61,29 +62,24 @@ func (f Frame) name() string {
6162// GOPATH separated by \n\t (<funcname>\n\t<path>)
6263// %+v equivalent to %+s:%d
6364func (f Frame ) Format (s fmt.State , verb rune ) {
64- f .format (s , s , verb )
65- }
66-
67- // format allows stack trace printing calls to be made with a bytes.Buffer.
68- func (f Frame ) format (w io.Writer , s fmt.State , verb rune ) {
6965 switch verb {
7066 case 's' :
7167 switch {
7268 case s .Flag ('+' ):
73- io .WriteString (w , f .name ())
74- io .WriteString (w , "\n \t " )
75- io .WriteString (w , f .file ())
69+ io .WriteString (s , f .name ())
70+ io .WriteString (s , "\n \t " )
71+ io .WriteString (s , f .file ())
7672 default :
77- io .WriteString (w , path .Base (f .file ()))
73+ io .WriteString (s , path .Base (f .file ()))
7874 }
7975 case 'd' :
80- io .WriteString (w , strconv .Itoa (f .line ()))
76+ io .WriteString (s , strconv .Itoa (f .line ()))
8177 case 'n' :
82- io .WriteString (w , funcname (f .name ()))
78+ io .WriteString (s , funcname (f .name ()))
8379 case 'v' :
84- f .format ( w , s , 's' )
85- io .WriteString (w , ":" )
86- f .format ( w , s , 'd' )
80+ f .Format ( s , 's' )
81+ io .WriteString (s , ":" )
82+ f .Format ( s , 'd' )
8783 }
8884}
8985
@@ -99,43 +95,35 @@ type StackTrace []Frame
9995//
10096// %+v Prints filename, function, and line number for each Frame in the stack.
10197func (st StackTrace ) Format (s fmt.State , verb rune ) {
102- var b bytes.Buffer
10398 switch verb {
10499 case 'v' :
105100 switch {
106101 case s .Flag ('+' ):
107- b .Grow (len (st ) * stackMinLen )
108102 for _ , f := range st {
109- b . WriteByte ( '\n' )
110- f .format ( & b , s , verb )
103+ io . WriteString ( s , " \n " )
104+ f .Format ( s , verb )
111105 }
112106 case s .Flag ('#' ):
113- fmt .Fprintf (& b , "%#v" , []Frame (st ))
107+ fmt .Fprintf (s , "%#v" , []Frame (st ))
114108 default :
115- st .formatSlice (& b , s , verb )
109+ st .formatSlice (s , verb )
116110 }
117111 case 's' :
118- st .formatSlice (& b , s , verb )
112+ st .formatSlice (s , verb )
119113 }
120- io .Copy (s , & b )
121114}
122115
123116// formatSlice will format this StackTrace into the given buffer as a slice of
124117// Frame, only valid when called with '%s' or '%v'.
125- func (st StackTrace ) formatSlice (b * bytes.Buffer , s fmt.State , verb rune ) {
126- b .WriteByte ('[' )
127- if len (st ) == 0 {
128- b .WriteByte (']' )
129- return
130- }
131-
132- b .Grow (len (st ) * (stackMinLen / 4 ))
133- st [0 ].format (b , s , verb )
134- for _ , fr := range st [1 :] {
135- b .WriteByte (' ' )
136- fr .format (b , s , verb )
118+ func (st StackTrace ) formatSlice (s fmt.State , verb rune ) {
119+ io .WriteString (s , "[" )
120+ for i , f := range st {
121+ if i > 0 {
122+ io .WriteString (s , " " )
123+ }
124+ f .Format (s , verb )
137125 }
138- b . WriteByte ( ']' )
126+ io . WriteString ( s , "]" )
139127}
140128
141129// stackMinLen is a best-guess at the minimum length of a stack trace. It
0 commit comments