summaryrefslogtreecommitdiff
path: root/debug/frames.go
diff options
context:
space:
mode:
authorAdam Scarr <adam@vektah.net>2017-08-10 21:04:14 +1000
committerAdam Scarr <adam@vektah.net>2017-08-10 21:08:18 +1000
commitaf542eff9e1e51561a9efa37685ee07b1d01b53e (patch)
treec700bdca58b4f9bbeb89ba1b102b2a779c88f7f3 /debug/frames.go
parentb64fcfaa6115eb4a5f65c12d37f95d842136ae35 (diff)
Add parse logging
Diffstat (limited to 'debug/frames.go')
-rw-r--r--debug/frames.go66
1 files changed, 66 insertions, 0 deletions
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 "", ""
+}