This file is indexed.

/usr/share/gocode/src/gopkg.in/inconshreveable/log15.v2/stack/stack.go is in golang-gopkg-inconshreveable-log15.v2-dev 2.11+git20150921.0.b105bd3-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
// Package stack implements utilities to capture, manipulate, and format call
// stacks.
package stack

import (
	"fmt"
	"path/filepath"
	"runtime"
	"strings"
)

// Call records a single function invocation from a goroutine stack. It is a
// wrapper for the program counter values returned by runtime.Caller and
// runtime.Callers and consumed by runtime.FuncForPC.
type Call uintptr

// Format implements fmt.Formatter with support for the following verbs.
//
//    %s    source file
//    %d    line number
//    %n    function name
//    %v    equivalent to %s:%d
//
// It accepts the '+' and '#' flags for most of the verbs as follows.
//
//    %+s   path of source file relative to the compile time GOPATH
//    %#s   full path of source file
//    %+n   import path qualified function name
//    %+v   equivalent to %+s:%d
//    %#v   equivalent to %#s:%d
func (pc Call) Format(s fmt.State, c rune) {
	// BUG(ChrisHines): Subtracting one from pc is a work around for
	// https://code.google.com/p/go/issues/detail?id=7690. The idea for this
	// work around comes from rsc's initial patch at
	// https://codereview.appspot.com/84100043/#ps20001, but as noted in the
	// issue discussion, it is not a complete fix since it doesn't handle some
	// cases involving signals. Just the same, it handles all of the other
	// cases I have tested.
	pcFix := uintptr(pc) - 1
	fn := runtime.FuncForPC(pcFix)
	if fn == nil {
		fmt.Fprintf(s, "%%!%c(NOFUNC)", c)
		return
	}

	switch c {
	case 's', 'v':
		file, line := fn.FileLine(pcFix)
		switch {
		case s.Flag('#'):
			// done
		case s.Flag('+'):
			// Here we want to get the source file path relative to the
			// compile time GOPATH. As of Go 1.3.x there is no direct way to
			// know the compiled GOPATH at runtime, but we can infer the
			// number of path segments in the GOPATH. We note that fn.Name()
			// returns the function name qualified by the import path, which
			// does not include the GOPATH. Thus we can trim segments from the
			// beginning of the file path until the number of path separators
			// remaining is one more than the number of path separators in the
			// function name. For example, given:
			//
			//    GOPATH     /home/user
			//    file       /home/user/src/pkg/sub/file.go
			//    fn.Name()  pkg/sub.Type.Method
			//
			// We want to produce:
			//
			//    pkg/sub/file.go
			//
			// From this we can easily see that fn.Name() has one less path
			// separator than our desired output.
			const sep = "/"
			impCnt := strings.Count(fn.Name(), sep) + 1
			pathCnt := strings.Count(file, sep)
			for pathCnt > impCnt {
				i := strings.Index(file, sep)
				if i == -1 {
					break
				}
				file = file[i+len(sep):]
				pathCnt--
			}
		default:
			const sep = "/"
			if i := strings.LastIndex(file, sep); i != -1 {
				file = file[i+len(sep):]
			}
		}
		fmt.Fprint(s, file)
		if c == 'v' {
			fmt.Fprint(s, ":", line)
		}

	case 'd':
		_, line := fn.FileLine(pcFix)
		fmt.Fprint(s, line)

	case 'n':
		name := fn.Name()
		if !s.Flag('+') {
			const pathSep = "/"
			if i := strings.LastIndex(name, pathSep); i != -1 {
				name = name[i+len(pathSep):]
			}
			const pkgSep = "."
			if i := strings.Index(name, pkgSep); i != -1 {
				name = name[i+len(pkgSep):]
			}
		}
		fmt.Fprint(s, name)
	}
}

// Callers returns a Trace for the current goroutine with element 0
// identifying the calling function.
func Callers() Trace {
	pcs := poolBuf()
	pcs = pcs[:cap(pcs)]
	n := runtime.Callers(2, pcs)
	cs := make([]Call, n)
	for i, pc := range pcs[:n] {
		cs[i] = Call(pc)
	}
	putPoolBuf(pcs)
	return cs
}

// name returns the import path qualified name of the function containing the
// call.
func (pc Call) name() string {
	pcFix := uintptr(pc) - 1 // work around for go issue #7690
	fn := runtime.FuncForPC(pcFix)
	if fn == nil {
		return "???"
	}
	return fn.Name()
}

func (pc Call) file() string {
	pcFix := uintptr(pc) - 1 // work around for go issue #7690
	fn := runtime.FuncForPC(pcFix)
	if fn == nil {
		return "???"
	}
	file, _ := fn.FileLine(pcFix)
	return file
}

// Trace records a sequence of function invocations from a goroutine stack.
type Trace []Call

// Format implements fmt.Formatter by printing the Trace as square brackes ([,
// ]) surrounding a space separated list of Calls each formatted with the
// supplied verb and options.
func (pcs Trace) Format(s fmt.State, c rune) {
	s.Write([]byte("["))
	for i, pc := range pcs {
		if i > 0 {
			s.Write([]byte(" "))
		}
		pc.Format(s, c)
	}
	s.Write([]byte("]"))
}

// TrimBelow returns a slice of the Trace with all entries below pc removed.
func (pcs Trace) TrimBelow(pc Call) Trace {
	for len(pcs) > 0 && pcs[0] != pc {
		pcs = pcs[1:]
	}
	return pcs
}

// TrimAbove returns a slice of the Trace with all entries above pc removed.
func (pcs Trace) TrimAbove(pc Call) Trace {
	for len(pcs) > 0 && pcs[len(pcs)-1] != pc {
		pcs = pcs[:len(pcs)-1]
	}
	return pcs
}

// TrimBelowName returns a slice of the Trace with all entries below the
// lowest with function name name removed.
func (pcs Trace) TrimBelowName(name string) Trace {
	for len(pcs) > 0 && pcs[0].name() != name {
		pcs = pcs[1:]
	}
	return pcs
}

// TrimAboveName returns a slice of the Trace with all entries above the
// highest with function name name removed.
func (pcs Trace) TrimAboveName(name string) Trace {
	for len(pcs) > 0 && pcs[len(pcs)-1].name() != name {
		pcs = pcs[:len(pcs)-1]
	}
	return pcs
}

var goroot string

func init() {
	goroot = filepath.ToSlash(runtime.GOROOT())
	if runtime.GOOS == "windows" {
		goroot = strings.ToLower(goroot)
	}
}

func inGoroot(path string) bool {
	if runtime.GOOS == "windows" {
		path = strings.ToLower(path)
	}
	return strings.HasPrefix(path, goroot)
}

// TrimRuntime returns a slice of the Trace with the topmost entries from the
// go runtime removed. It considers any calls originating from files under
// GOROOT as part of the runtime.
func (pcs Trace) TrimRuntime() Trace {
	for len(pcs) > 0 && inGoroot(pcs[len(pcs)-1].file()) {
		pcs = pcs[:len(pcs)-1]
	}
	return pcs
}