mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 11:32:25 -05:00 
			
		
		
		
	
		
			
	
	
		
			57 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			57 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | // Copyright 2018 The Go Authors. All rights reserved. | ||
|  | // Use of this source code is governed by a BSD-style | ||
|  | // license that can be found in the LICENSE file. | ||
|  | 
 | ||
|  | package xerrors | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"runtime" | ||
|  | ) | ||
|  | 
 | ||
|  | // A Frame contains part of a call stack. | ||
|  | type Frame struct { | ||
|  | 	// Make room for three PCs: the one we were asked for, what it called, | ||
|  | 	// and possibly a PC for skipPleaseUseCallersFrames. See: | ||
|  | 	// https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169 | ||
|  | 	frames [3]uintptr | ||
|  | } | ||
|  | 
 | ||
|  | // Caller returns a Frame that describes a frame on the caller's stack. | ||
|  | // The argument skip is the number of frames to skip over. | ||
|  | // Caller(0) returns the frame for the caller of Caller. | ||
|  | func Caller(skip int) Frame { | ||
|  | 	var s Frame | ||
|  | 	runtime.Callers(skip+1, s.frames[:]) | ||
|  | 	return s | ||
|  | } | ||
|  | 
 | ||
|  | // location reports the file, line, and function of a frame. | ||
|  | // | ||
|  | // The returned function may be "" even if file and line are not. | ||
|  | func (f Frame) location() (function, file string, line int) { | ||
|  | 	frames := runtime.CallersFrames(f.frames[:]) | ||
|  | 	if _, ok := frames.Next(); !ok { | ||
|  | 		return "", "", 0 | ||
|  | 	} | ||
|  | 	fr, ok := frames.Next() | ||
|  | 	if !ok { | ||
|  | 		return "", "", 0 | ||
|  | 	} | ||
|  | 	return fr.Function, fr.File, fr.Line | ||
|  | } | ||
|  | 
 | ||
|  | // Format prints the stack as error detail. | ||
|  | // It should be called from an error's Format implementation | ||
|  | // after printing any other error detail. | ||
|  | func (f Frame) Format(p Printer) { | ||
|  | 	if p.Detail() { | ||
|  | 		function, file, line := f.location() | ||
|  | 		if function != "" { | ||
|  | 			p.Printf("%s\n    ", function) | ||
|  | 		} | ||
|  | 		if file != "" { | ||
|  | 			p.Printf("%s:%d\n", file, line) | ||
|  | 		} | ||
|  | 	} | ||
|  | } |