package fingerprint import ( "regexp" "strconv" "strings" ) // Zig panic/stack trace patterns: // /path/to/file.zig:42:13: 0x1234 in function_name (module) // ???:?:?: 0x1234 in ??? (???) var zigFrameRe = regexp.MustCompile( `^\s*(.+?):(\d+):\d+:\s+(0x[0-9a-fA-F]+)\s+in\s+(\S+)\s+\(([^)]*)\)`, ) // Zig panic header: "panic: ..." or "thread N panic: ..." var zigPanicRe = regexp.MustCompile(`(?:thread \d+ )?panic: `) // ParseZig parses Zig panic stack traces. func ParseZig(raw string) []Frame { if !zigPanicRe.MatchString(raw) && !strings.Contains(raw, " in ") { return nil } var frames []Frame for _, line := range strings.Split(raw, "\n") { m := zigFrameRe.FindStringSubmatch(line) if m == nil { continue } file := m[1] lineNo, _ := strconv.Atoi(m[2]) addr := m[3] fn := m[4] module := m[5] // Skip unknown frames. if fn == "???" { continue } frames = append(frames, Frame{ Address: addr, Function: fn, File: file, Line: lineNo, Module: module, Index: len(frames), }) } if len(frames) < 1 { return nil } return frames }