From af542eff9e1e51561a9efa37685ee07b1d01b53e Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Thu, 10 Aug 2017 21:04:14 +1000 Subject: Add parse logging --- debug/frames.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 debug/frames.go (limited to 'debug/frames.go') diff --git a/debug/frames.go b/debug/frames.go new file mode 100644 index 0000000..88a48f0 --- /dev/null +++ b/debug/frames.go @@ -0,0 +1,66 @@ +package debug + +import ( + "bufio" + "fmt" + "os" + "path/filepath" + "regexp" + "runtime" + "strings" +) + +var varRegex = regexp.MustCompile(`(?:var)?\s*(\w*)\s*:?=`) + +func getPackageName(f runtime.Frame) string { + parts := strings.Split(f.Func.Name(), ".") + pl := len(parts) + + if parts[pl-2][0] == '(' { + return strings.Join(parts[0:pl-2], ".") + } else { + return strings.Join(parts[0:pl-1], ".") + } +} + +func getVarName(filename string, lineNo int) string { + f, err := os.Open(filename) + if err != nil { + return "" + } + + scanner := bufio.NewScanner(f) + for i := 0; i < lineNo; i++ { + scanner.Scan() + } + + line := scanner.Text() + if matches := varRegex.FindStringSubmatch(line); matches != nil { + return matches[1] + } + return "" +} + +// GetDefinition returns the name of the variable and location this parser was defined by walking up the stack +func GetDefinition() (varName string, location string) { + pc := make([]uintptr, 64) + n := runtime.Callers(3, pc) + frames := runtime.CallersFrames(pc[:n]) + + var frame runtime.Frame + more := true + for more { + frame, more = frames.Next() + pkg := getPackageName(frame) + if pkg == "github.com/vektah/goparsify" || pkg == "github.com/vektah/goparsify/debug" { + continue + } + + varName := getVarName(frame.File, frame.Line) + if varName != "" { + return varName, fmt.Sprintf("%s:%d", filepath.Base(frame.File), frame.Line) + } + } + + return "", "" +} -- cgit v1.2.3