github.com/viant/toolbox@v0.34.5/stack_helper.go (about) 1 package toolbox 2 3 import ( 4 "path" 5 "runtime" 6 "strings" 7 ) 8 9 // CallerInfo return filename, function or file line from the stack 10 func CallerInfo(callerIndex int) (string, string, int) { 11 var callerPointer = make([]uintptr, 10) // at least 1 entry needed 12 runtime.Callers(callerIndex, callerPointer) 13 callerInfo := runtime.FuncForPC(callerPointer[0]) 14 file, line := callerInfo.FileLine(callerPointer[0]) 15 callerName := callerInfo.Name() 16 dotPosition := strings.LastIndex(callerName, ".") 17 return file, callerName[dotPosition+1:], line 18 } 19 20 //CallerDirectory returns directory of caller source code directory 21 func CallerDirectory(callerIndex int) string { 22 file, _, _ := CallerInfo(callerIndex) 23 parent, _ := path.Split(file) 24 return parent 25 } 26 27 func hasMatch(target string, candidates ...string) bool { 28 for _, candidate := range candidates { 29 if strings.HasSuffix(target, candidate) { 30 return true 31 } 32 } 33 return false 34 } 35 36 //DiscoverCaller returns the first matched caller info 37 func DiscoverCaller(offset, maxDepth int, ignoreFiles ...string) (string, string, int) { 38 var callerPointer = make([]uintptr, maxDepth) // at least 1 entry needed 39 var caller *runtime.Func 40 var filename string 41 var line int 42 for i := offset; i < maxDepth; i++ { 43 runtime.Callers(i, callerPointer) 44 caller = runtime.FuncForPC(callerPointer[0]) 45 filename, line = caller.FileLine(callerPointer[0]) 46 if hasMatch(filename, ignoreFiles...) { 47 continue 48 } 49 break 50 } 51 callerName := caller.Name() 52 dotPosition := strings.LastIndex(callerName, ".") 53 return filename, callerName[dotPosition+1:], line 54 }