Skip to content

Commit f06639a

Browse files
committed
add external PR:pkg#198
1 parent e4dcbeb commit f06639a

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ _testmain.go
2222
*.exe
2323
*.test
2424
*.prof
25+
.idea

stack.go

+25-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package errors
22

33
import (
4+
"bytes"
45
"fmt"
56
"io"
67
"path"
@@ -49,6 +50,8 @@ func (f Frame) name() string {
4950
return fn.Name()
5051
}
5152

53+
func (f Frame) Format(s fmt.State, verb rune) { f.format(s, s, verb) }
54+
5255
// Format formats the frame according to the fmt.Formatter interface.
5356
//
5457
// %s source file
@@ -61,25 +64,25 @@ func (f Frame) name() string {
6164
// %+s function name and path of source file relative to the compile time
6265
// GOPATH separated by \n\t (<funcname>\n\t<path>)
6366
// %+v equivalent to %+s:%d
64-
func (f Frame) Format(s fmt.State, verb rune) {
67+
func (f Frame) format(w io.Writer, s fmt.State, verb rune) {
6568
switch verb {
6669
case 's':
6770
switch {
6871
case s.Flag('+'):
69-
io.WriteString(s, f.name())
70-
io.WriteString(s, "\n\t")
71-
io.WriteString(s, f.file())
72+
io.WriteString(w, f.name())
73+
io.WriteString(w, "\n\t")
74+
io.WriteString(w, f.file())
7275
default:
73-
io.WriteString(s, path.Base(f.file()))
76+
io.WriteString(w, path.Base(f.file()))
7477
}
7578
case 'd':
76-
io.WriteString(s, strconv.Itoa(f.line()))
79+
io.WriteString(w, strconv.Itoa(f.line()))
7780
case 'n':
78-
io.WriteString(s, funcname(f.name()))
81+
io.WriteString(w, funcname(f.name()))
7982
case 'v':
80-
f.Format(s, 's')
81-
io.WriteString(s, ":")
82-
f.Format(s, 'd')
83+
f.format(w, s, 's')
84+
io.WriteString(w, ":")
85+
f.format(w, s, 'd')
8386
}
8487
}
8588

@@ -141,11 +144,22 @@ func (st StackTrace) formatSlice(s fmt.State, verb rune) {
141144
// stack represents a stack of program counters.
142145
type stack []uintptr
143146

147+
// stackMinLen is a best-guess at the minimum length of a stack trace. It
148+
// doesn't need to be exact, just give a good enough head start for the buffer
149+
// to avoid the expensive early growth.
150+
const stackMinLen = 96
151+
144152
func (s *stack) Format(st fmt.State, verb rune) {
145153
if verb == 'v' && st.Flag('+') {
154+
var b = &bytes.Buffer{}
155+
b.Grow(len(*s) * stackMinLen)
156+
146157
for i := range *s {
147-
fmt.Fprintf(st, "\n%+v", Frame((*s)[i]))
158+
b.WriteByte('\n')
159+
Frame((*s)[i]).format(b, st, verb)
148160
}
161+
162+
io.Copy(st, b)
149163
}
150164
}
151165

0 commit comments

Comments
 (0)