(filename string, line, context int)
| 208 | var fileCache = make(map[string][][]byte) |
| 209 | |
| 210 | func fileContext(filename string, line, context int) ([][]byte, int) { |
| 211 | fileCacheLock.Lock() |
| 212 | defer fileCacheLock.Unlock() |
| 213 | lines, ok := fileCache[filename] |
| 214 | if !ok { |
| 215 | data, err := os.ReadFile(filename) |
| 216 | if err != nil { |
| 217 | // cache errors as nil slice: code below handles it correctly |
| 218 | // otherwise when missing the source or running as a different user, we try |
| 219 | // reading the file on each error which is unnecessary |
| 220 | fileCache[filename] = nil |
| 221 | return nil, 0 |
| 222 | } |
| 223 | lines = bytes.Split(data, []byte{'\n'}) |
| 224 | fileCache[filename] = lines |
| 225 | } |
| 226 | |
| 227 | if lines == nil { |
| 228 | // cached error from ReadFile: return no lines |
| 229 | return nil, 0 |
| 230 | } |
| 231 | |
| 232 | line-- // stack trace lines are 1-indexed |
| 233 | start := line - context |
| 234 | var idx int |
| 235 | if start < 0 { |
| 236 | start = 0 |
| 237 | idx = line |
| 238 | } else { |
| 239 | idx = context |
| 240 | } |
| 241 | end := line + context + 1 |
| 242 | if line >= len(lines) { |
| 243 | return nil, 0 |
| 244 | } |
| 245 | if end > len(lines) { |
| 246 | end = len(lines) |
| 247 | } |
| 248 | return lines[start:end], idx |
| 249 | } |
no outgoing calls
no test coverage detected
searching dependent graphs…