nvidia-container-toolkit/vendor/github.com/tsaikd/KDGoLib/runtimecaller/runtimeCaller.go
Evan Lezar 6e1436cefb Update go vendoring
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2021-09-07 13:13:03 +02:00

93 lines
2.0 KiB
Go

package runtimecaller
import (
"path"
"runtime"
"strings"
)
// GetByFilters return CallInfo until all filters are valid
func GetByFilters(skip int, filters ...Filter) (callinfo CallInfo, ok bool) {
filters = append(FilterCommons, filters...)
for {
skip++
if callinfo, ok = retrieveCallInfo(skip); !ok {
return
}
valid, stop := filterAll(callinfo, filters...)
if valid {
return callinfo, true
}
if stop {
return callinfo, false
}
}
}
// ListByFilters return all CallInfo stack for all filters are valid
func ListByFilters(skip int, filters ...Filter) (callinfos []CallInfo) {
filters = append(FilterCommons, filters...)
for {
var callinfo CallInfo
var ok bool
skip++
if callinfo, ok = retrieveCallInfo(skip); !ok {
return
}
valid, stop := filterAll(callinfo, filters...)
if valid {
callinfos = append(callinfos, callinfo)
}
if stop {
return
}
}
}
// http://stackoverflow.com/questions/25262754/how-to-get-name-of-current-package-in-go
func retrieveCallInfo(skip int) (result CallInfo, ok bool) {
callinfo := CallInfoImpl{}
if callinfo.pc, callinfo.filePath, callinfo.line, ok = runtime.Caller(skip + 1); !ok {
return
}
callinfo.fileDir, callinfo.fileName = path.Split(callinfo.filePath)
callinfo.pcFunc = runtime.FuncForPC(callinfo.pc)
parts := strings.Split(callinfo.pcFunc.Name(), ".")
pl := len(parts)
if pl < 1 {
return result, false
}
callinfo.funcName = parts[pl-1]
if pl >= 2 && parts[pl-2] != "" && parts[pl-2][0] == '(' {
callinfo.funcName = parts[pl-2] + "." + callinfo.funcName
callinfo.packageName = strings.Join(parts[0:pl-2], ".")
} else {
callinfo.packageName = strings.Join(parts[0:pl-1], ".")
}
return callinfo, true
}
func filterAll(callinfo CallInfo, filters ...Filter) (allvalid bool, onestop bool) {
allvalid = true
for _, filter := range filters {
valid, stop := filter(callinfo)
allvalid = allvalid && valid
if stop {
return allvalid, true
}
if !allvalid {
return
}
}
return
}