forked from toolshed/abra
chore: go mod vendor / tidy
This commit is contained in:
73
vendor/github.com/mmcloughlin/avo/internal/stack/stack.go
generated
vendored
Normal file
73
vendor/github.com/mmcloughlin/avo/internal/stack/stack.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// Package stack provides helpers for querying the callstack.
|
||||
package stack
|
||||
|
||||
import (
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Frames returns at most max callstack Frames, starting with its caller and
|
||||
// skipping skip Frames.
|
||||
func Frames(skip, max int) []runtime.Frame {
|
||||
pc := make([]uintptr, max)
|
||||
n := runtime.Callers(skip+2, pc)
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
pc = pc[:n]
|
||||
frames := runtime.CallersFrames(pc)
|
||||
var fs []runtime.Frame
|
||||
for {
|
||||
f, more := frames.Next()
|
||||
fs = append(fs, f)
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
return fs
|
||||
}
|
||||
|
||||
// Match returns the first stack frame for which the predicate function returns
|
||||
// true. Returns nil if no match is found. Starts matching after skip frames,
|
||||
// starting with its caller.
|
||||
func Match(skip int, predicate func(runtime.Frame) bool) *runtime.Frame {
|
||||
i, n := skip+1, 16
|
||||
for {
|
||||
fs := Frames(i, n)
|
||||
for j, f := range fs {
|
||||
if predicate(f) {
|
||||
return &fs[j]
|
||||
}
|
||||
}
|
||||
if len(fs) < n {
|
||||
break
|
||||
}
|
||||
i += n
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Main returns the main() function Frame.
|
||||
func Main() *runtime.Frame {
|
||||
return Match(1, func(f runtime.Frame) bool {
|
||||
return f.Function == "main.main"
|
||||
})
|
||||
}
|
||||
|
||||
// ExternalCaller returns the first frame outside the callers package.
|
||||
func ExternalCaller() *runtime.Frame {
|
||||
var first *runtime.Frame
|
||||
return Match(1, func(f runtime.Frame) bool {
|
||||
if first == nil {
|
||||
first = &f
|
||||
}
|
||||
return pkg(first.Function) != pkg(f.Function)
|
||||
})
|
||||
}
|
||||
|
||||
func pkg(ident string) string {
|
||||
dir, name := path.Split(ident)
|
||||
parts := strings.Split(name, ".")
|
||||
return dir + parts[0]
|
||||
}
|
Reference in New Issue
Block a user