github.com/haraldrudell/parl@v0.4.176/pruntime/pruntimelib/parse-file-line.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package pruntimelib 7 8 import ( 9 "bytes" 10 "fmt" 11 "strconv" 12 ) 13 14 const ( 15 fileLineTabRune = '\t' 16 ) 17 18 // ParseFileLine parses a line of a tab character then absolue file path, 19 // followed by a colon and line number, then a space character and 20 // a byte offset. 21 // 22 // "\t/gp-debug-stack/debug-stack.go:29 +0x44" 23 // "\t/opt/sw/parl/g0/waiterr.go:49" 24 func ParseFileLine(fileLine []byte) (file string, line int) { 25 var hasTab bool 26 var lastColon = -1 27 var spaceAfterColon = -1 28 if len(fileLine) > 0 { 29 hasTab = fileLine[0] == fileLineTabRune 30 lastColon = bytes.LastIndexByte(fileLine, ':') 31 if spaceAfterColon = bytes.LastIndexByte(fileLine, '\x20'); spaceAfterColon == -1 { 32 spaceAfterColon = len(fileLine) 33 } 34 } 35 if !hasTab || lastColon == -1 || spaceAfterColon < lastColon { 36 panic(fmt.Errorf("bad debug.Stack: file line: %q", string(fileLine))) 37 } 38 39 var err error 40 if line, err = strconv.Atoi(string(fileLine[lastColon+1 : spaceAfterColon])); err != nil { 41 panic(fmt.Errorf("bad debug.Stack file line number: %w %q", err, string(fileLine))) 42 } else if line < 1 { 43 panic(fmt.Errorf("bad debug.Stack file line number <1: %q", string(fileLine))) 44 } 45 46 // absolute filename 47 file = string(fileLine[1:lastColon]) 48 49 return 50 }