Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / pkg / errors / stack.go
1 package errors
2
3 import (
4         "fmt"
5         "io"
6         "path"
7         "runtime"
8         "strings"
9 )
10
11 // Frame represents a program counter inside a stack frame.
12 type Frame uintptr
13
14 // pc returns the program counter for this frame;
15 // multiple frames may have the same PC value.
16 func (f Frame) pc() uintptr { return uintptr(f) - 1 }
17
18 // file returns the full path to the file that contains the
19 // function for this Frame's pc.
20 func (f Frame) file() string {
21         fn := runtime.FuncForPC(f.pc())
22         if fn == nil {
23                 return "unknown"
24         }
25         file, _ := fn.FileLine(f.pc())
26         return file
27 }
28
29 // line returns the line number of source code of the
30 // function for this Frame's pc.
31 func (f Frame) line() int {
32         fn := runtime.FuncForPC(f.pc())
33         if fn == nil {
34                 return 0
35         }
36         _, line := fn.FileLine(f.pc())
37         return line
38 }
39
40 // Format formats the frame according to the fmt.Formatter interface.
41 //
42 //    %s    source file
43 //    %d    source line
44 //    %n    function name
45 //    %v    equivalent to %s:%d
46 //
47 // Format accepts flags that alter the printing of some verbs, as follows:
48 //
49 //    %+s   function name and path of source file relative to the compile time
50 //          GOPATH separated by \n\t (<funcname>\n\t<path>)
51 //    %+v   equivalent to %+s:%d
52 func (f Frame) Format(s fmt.State, verb rune) {
53         switch verb {
54         case 's':
55                 switch {
56                 case s.Flag('+'):
57                         pc := f.pc()
58                         fn := runtime.FuncForPC(pc)
59                         if fn == nil {
60                                 io.WriteString(s, "unknown")
61                         } else {
62                                 file, _ := fn.FileLine(pc)
63                                 fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
64                         }
65                 default:
66                         io.WriteString(s, path.Base(f.file()))
67                 }
68         case 'd':
69                 fmt.Fprintf(s, "%d", f.line())
70         case 'n':
71                 name := runtime.FuncForPC(f.pc()).Name()
72                 io.WriteString(s, funcname(name))
73         case 'v':
74                 f.Format(s, 's')
75                 io.WriteString(s, ":")
76                 f.Format(s, 'd')
77         }
78 }
79
80 // StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
81 type StackTrace []Frame
82
83 // Format formats the stack of Frames according to the fmt.Formatter interface.
84 //
85 //    %s        lists source files for each Frame in the stack
86 //    %v        lists the source file and line number for each Frame in the stack
87 //
88 // Format accepts flags that alter the printing of some verbs, as follows:
89 //
90 //    %+v   Prints filename, function, and line number for each Frame in the stack.
91 func (st StackTrace) Format(s fmt.State, verb rune) {
92         switch verb {
93         case 'v':
94                 switch {
95                 case s.Flag('+'):
96                         for _, f := range st {
97                                 fmt.Fprintf(s, "\n%+v", f)
98                         }
99                 case s.Flag('#'):
100                         fmt.Fprintf(s, "%#v", []Frame(st))
101                 default:
102                         fmt.Fprintf(s, "%v", []Frame(st))
103                 }
104         case 's':
105                 fmt.Fprintf(s, "%s", []Frame(st))
106         }
107 }
108
109 // stack represents a stack of program counters.
110 type stack []uintptr
111
112 func (s *stack) Format(st fmt.State, verb rune) {
113         switch verb {
114         case 'v':
115                 switch {
116                 case st.Flag('+'):
117                         for _, pc := range *s {
118                                 f := Frame(pc)
119                                 fmt.Fprintf(st, "\n%+v", f)
120                         }
121                 }
122         }
123 }
124
125 func (s *stack) StackTrace() StackTrace {
126         f := make([]Frame, len(*s))
127         for i := 0; i < len(f); i++ {
128                 f[i] = Frame((*s)[i])
129         }
130         return f
131 }
132
133 func callers() *stack {
134         const depth = 32
135         var pcs [depth]uintptr
136         n := runtime.Callers(3, pcs[:])
137         var st stack = pcs[0:n]
138         return &st
139 }
140
141 // funcname removes the path prefix component of a function's name reported by func.Name().
142 func funcname(name string) string {
143         i := strings.LastIndex(name, "/")
144         name = name[i+1:]
145         i = strings.Index(name, ".")
146         return name[i+1:]
147 }