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  }