Skip to content
This repository was archived by the owner on Dec 1, 2021. It is now read-only.

Commit 567ccaa

Browse files
committed
Split stack.Location into a private helper
1 parent 80cce0e commit 567ccaa

File tree

1 file changed

+50
-46
lines changed

1 file changed

+50
-46
lines changed

errors.go

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -59,52 +59,7 @@ import (
5959
type stack []uintptr
6060

6161
func (s stack) Location() (string, int) {
62-
pc := s[0] - 1
63-
fn := runtime.FuncForPC(pc)
64-
if fn == nil {
65-
return "unknown", 0
66-
}
67-
68-
file, line := fn.FileLine(pc)
69-
70-
// Here we want to get the source file path relative to the compile time
71-
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
72-
// GOPATH at runtime, but we can infer the number of path segments in the
73-
// GOPATH. We note that fn.Name() returns the function name qualified by
74-
// the import path, which does not include the GOPATH. Thus we can trim
75-
// segments from the beginning of the file path until the number of path
76-
// separators remaining is one more than the number of path separators in
77-
// the function name. For example, given:
78-
//
79-
// GOPATH /home/user
80-
// file /home/user/src/pkg/sub/file.go
81-
// fn.Name() pkg/sub.Type.Method
82-
//
83-
// We want to produce:
84-
//
85-
// pkg/sub/file.go
86-
//
87-
// From this we can easily see that fn.Name() has one less path separator
88-
// than our desired output. We count separators from the end of the file
89-
// path until it finds two more than in the function name and then move
90-
// one character forward to preserve the initial path segment without a
91-
// leading separator.
92-
const sep = "/"
93-
goal := strings.Count(fn.Name(), sep) + 2
94-
i := len(file)
95-
for n := 0; n < goal; n++ {
96-
i = strings.LastIndex(file[:i], sep)
97-
if i == -1 {
98-
// not enough separators found, set i so that the slice expression
99-
// below leaves file unmodified
100-
i = -len(sep)
101-
break
102-
}
103-
}
104-
// get back to 0 or trim the leading separator
105-
file = file[i+len(sep):]
106-
107-
return file, line
62+
return location(s[0] - 1)
10863
}
10964

11065
// New returns an error that formats as the given text.
@@ -241,3 +196,52 @@ func callers() stack {
241196
n := runtime.Callers(3, pcs[:])
242197
return pcs[0:n]
243198
}
199+
200+
// location returns the source file and line matching pc.
201+
func location(pc uintptr) (string, int) {
202+
fn := runtime.FuncForPC(pc)
203+
if fn == nil {
204+
return "unknown", 0
205+
}
206+
207+
file, line := fn.FileLine(pc)
208+
209+
// Here we want to get the source file path relative to the compile time
210+
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
211+
// GOPATH at runtime, but we can infer the number of path segments in the
212+
// GOPATH. We note that fn.Name() returns the function name qualified by
213+
// the import path, which does not include the GOPATH. Thus we can trim
214+
// segments from the beginning of the file path until the number of path
215+
// separators remaining is one more than the number of path separators in
216+
// the function name. For example, given:
217+
//
218+
// GOPATH /home/user
219+
// file /home/user/src/pkg/sub/file.go
220+
// fn.Name() pkg/sub.Type.Method
221+
//
222+
// We want to produce:
223+
//
224+
// pkg/sub/file.go
225+
//
226+
// From this we can easily see that fn.Name() has one less path separator
227+
// than our desired output. We count separators from the end of the file
228+
// path until it finds two more than in the function name and then move
229+
// one character forward to preserve the initial path segment without a
230+
// leading separator.
231+
const sep = "/"
232+
goal := strings.Count(fn.Name(), sep) + 2
233+
i := len(file)
234+
for n := 0; n < goal; n++ {
235+
i = strings.LastIndex(file[:i], sep)
236+
if i == -1 {
237+
// not enough separators found, set i so that the slice expression
238+
// below leaves file unmodified
239+
i = -len(sep)
240+
break
241+
}
242+
}
243+
// get back to 0 or trim the leading separator
244+
file = file[i+len(sep):]
245+
246+
return file, line
247+
}

0 commit comments

Comments
 (0)