@@ -11,8 +11,10 @@ package stack
11
11
12
12
import (
13
13
"fmt"
14
+ "io"
14
15
"path/filepath"
15
16
"runtime"
17
+ "strconv"
16
18
"strings"
17
19
"sync"
18
20
)
@@ -66,7 +68,7 @@ func (c Call) Format(s fmt.State, verb rune) {
66
68
67
69
switch verb {
68
70
case 's' , 'v' :
69
- file , line := c .fn .FileLine (uintptr ( c .pc ) )
71
+ file , line := c .fn .FileLine (c .pc )
70
72
switch {
71
73
case s .Flag ('#' ):
72
74
// done
@@ -90,32 +92,40 @@ func (c Call) Format(s fmt.State, verb rune) {
90
92
// pkg/sub/file.go
91
93
//
92
94
// From this we can easily see that fn.Name() has one less path
93
- // separator than our desired output.
95
+ // separator than our desired output. We count separators from the
96
+ // end of the file path until it finds two more than in the
97
+ // function name and then move one character forward to preserve
98
+ // the initial path segment without a leading separator.
94
99
const sep = "/"
95
- impCnt := strings .Count (c .fn .Name (), sep ) + 1
96
- pathCnt := strings .Count (file , sep )
97
- for pathCnt > impCnt {
98
- i := strings .Index (file , sep )
100
+ goal := strings .Count (c .fn .Name (), sep ) + 2
101
+ pathCnt := 0
102
+ i := len (file )
103
+ for pathCnt < goal {
104
+ i = strings .LastIndex (file [:i ], sep )
99
105
if i == - 1 {
106
+ i = - len (sep )
100
107
break
101
108
}
102
- file = file [i + len (sep ):]
103
- pathCnt --
109
+ pathCnt ++
104
110
}
111
+ // get back to 0 or trim the leading seperator
112
+ file = file [i + len (sep ):]
105
113
default :
106
114
const sep = "/"
107
115
if i := strings .LastIndex (file , sep ); i != - 1 {
108
116
file = file [i + len (sep ):]
109
117
}
110
118
}
111
- fmt . Fprint (s , file )
119
+ io . WriteString (s , file )
112
120
if verb == 'v' {
113
- fmt .Fprint (s , ":" , line )
121
+ buf := [7 ]byte {':' }
122
+ s .Write (strconv .AppendInt (buf [:1 ], int64 (line ), 10 ))
114
123
}
115
124
116
125
case 'd' :
117
- _ , line := c .fn .FileLine (uintptr (c .pc ))
118
- fmt .Fprint (s , line )
126
+ _ , line := c .fn .FileLine (c .pc )
127
+ buf := [6 ]byte {}
128
+ s .Write (strconv .AppendInt (buf [:0 ], int64 (line ), 10 ))
119
129
120
130
case 'n' :
121
131
name := c .fn .Name ()
@@ -129,7 +139,7 @@ func (c Call) Format(s fmt.State, verb rune) {
129
139
name = name [i + len (pkgSep ):]
130
140
}
131
141
}
132
- fmt . Fprint (s , name )
142
+ io . WriteString (s , name )
133
143
}
134
144
}
135
145
@@ -146,7 +156,7 @@ func (c Call) file() string {
146
156
if c .fn == nil {
147
157
return "???"
148
158
}
149
- file , _ := c .fn .FileLine (uintptr ( c .pc ) )
159
+ file , _ := c .fn .FileLine (c .pc )
150
160
return file
151
161
}
152
162
0 commit comments