-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathstack.go
61 lines (57 loc) · 1.4 KB
/
stack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package errors
import (
"fmt"
"io"
"runtime"
)
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
type StackTrace struct {
runtime.Frames
}
// Format formats the stack of Frames according to the fmt.Formatter interface.
//
// %s lists source files for each Frame in the stack
// %v lists the source file and line number for each Frame in the stack
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+v Prints filename, function, and line number for each Frame in the stack.
func (st StackTrace) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case s.Flag('+'):
for {
frame, more := st.Frames.Next()
if frame.PC > 0 {
fmt.Fprintf(s, "\n%s", frame.Function)
fmt.Fprintf(s, "\n\t%s:%d", frame.File, frame.Line)
}
if !more {
break
}
}
default:
st.formatSlice(s, verb)
}
case 's':
st.formatSlice(s, verb)
default:
_, _ = fmt.Fprintf(s, "unsupported format: %%!%c, use %%s: ", verb)
st.formatSlice(s, verb)
}
}
// formatSlice will format this StackTrace into the given buffer as a slice of
// Frame, only valid when called with '%s' or '%v'.
func (st StackTrace) formatSlice(s fmt.State, verb rune) {
io.WriteString(s, "[")
for {
frame, more := st.Frames.Next()
fmt.Fprintf(s, "%s", frame.Function)
if !more {
break
}
io.WriteString(s, " ")
}
io.WriteString(s, "]")
}