goparsify/debugon.go
2017-08-07 20:07:29 +10:00

84 lines
1.5 KiB
Go

// +build debug
package goparsify
import (
"fmt"
"runtime"
"sort"
"strings"
"time"
)
var parsers []*DebugParser
type DebugParser struct {
Description string
Caller string
Next Parser
Time time.Duration
Calls int
}
func (dp *DebugParser) Parse(ps *State) *Node {
start := time.Now()
ret := dp.Next(ps)
dp.Time = dp.Time + time.Since(start)
dp.Calls++
return ret
}
func getPackageName(f *runtime.Func) string {
parts := strings.Split(f.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 NewParser(description string, p Parser) Parser {
fpcs := make([]uintptr, 1)
caller := ""
for i := 1; i < 10; i++ {
n := runtime.Callers(i, fpcs)
if n != 0 {
frame := runtime.FuncForPC(fpcs[0] - 1)
pkg := getPackageName(frame)
if pkg != "github.com/vektah/goparsify" {
file, line := frame.FileLine(fpcs[0] - 1)
caller = fmt.Sprintf("%s:%d", file, line)
break
}
}
}
dp := &DebugParser{
Description: description,
Next: p,
Caller: caller,
}
parsers = append(parsers, dp)
return dp.Parse
}
func DumpDebugStats() {
sort.Slice(parsers, func(i, j int) bool {
return parsers[i].Time >= parsers[j].Time
})
fmt.Println("Parser stats:")
for _, parser := range parsers {
fmt.Printf("%20s\t%10s\t%10d\tcalls\t%s\n", parser.Description, parser.Time.String(), parser.Calls, parser.Caller)
}
}