Source file
src/runtime/print.go
1
2
3
4
5 package runtime
6
7 import (
8 "internal/strconv"
9 "unsafe"
10 )
11
12
13
14 type hex uint64
15
16
17
18 type quoted string
19
20 func bytes(s string) (ret []byte) {
21 rp := (*slice)(unsafe.Pointer(&ret))
22 sp := stringStructOf(&s)
23 rp.array = sp.str
24 rp.len = sp.len
25 rp.cap = sp.len
26 return
27 }
28
29 var (
30
31
32 printBacklog [512]byte
33 printBacklogIndex int
34 )
35
36
37
38
39
40
41
42
43 func recordForPanic(b []byte) {
44 printlock()
45
46 if panicking.Load() == 0 {
47
48 for i := 0; i < len(b); {
49 n := copy(printBacklog[printBacklogIndex:], b[i:])
50 i += n
51 printBacklogIndex += n
52 printBacklogIndex %= len(printBacklog)
53 }
54 }
55
56 printunlock()
57 }
58
59 var debuglock mutex
60
61
62
63
64
65
66
67
68
69 func printlock() {
70 gp := getg()
71 if gp.writebuf != nil && gp.m.dying == 0 {
72
73
74
75 return
76 }
77 mp := gp.m
78 mp.locks++
79 mp.printlock++
80 if mp.printlock == 1 {
81 lock(&debuglock)
82 }
83 mp.locks--
84 }
85
86 func printunlock() {
87 gp := getg()
88 if gp.writebuf != nil && gp.m.dying == 0 {
89 return
90 }
91 mp := gp.m
92 mp.printlock--
93 if mp.printlock == 0 {
94 unlock(&debuglock)
95 }
96 }
97
98
99
100 func gwrite(b []byte) {
101 if len(b) == 0 {
102 return
103 }
104 gp := getg()
105
106
107
108
109
110 if gp == nil || gp.writebuf == nil || gp.m.dying > 0 {
111 recordForPanic(b)
112 writeErr(b)
113 return
114 }
115
116 n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
117 gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
118 }
119
120 func printsp() {
121 printstring(" ")
122 }
123
124 func printnl() {
125 printstring("\n")
126 }
127
128 func printbool(v bool) {
129 if v {
130 printstring("true")
131 } else {
132 printstring("false")
133 }
134 }
135
136
137 const float64Bytes = 24
138
139 func printfloat64(v float64) {
140 var buf [float64Bytes]byte
141 gwrite(strconv.AppendFloat(buf[:0], v, 'g', -1, 64))
142 }
143
144
145 const float32Bytes = 15
146
147 func printfloat32(v float32) {
148 var buf [float32Bytes]byte
149 gwrite(strconv.AppendFloat(buf[:0], float64(v), 'g', -1, 32))
150 }
151
152
153 const complex128Bytes = 2*float64Bytes + 3
154
155 func printcomplex128(c complex128) {
156 var buf [complex128Bytes]byte
157 gwrite(strconv.AppendComplex(buf[:0], c, 'g', -1, 128))
158 }
159
160
161 const complex64Bytes = 2*float32Bytes + 3
162
163 func printcomplex64(c complex64) {
164 var buf [complex64Bytes]byte
165 gwrite(strconv.AppendComplex(buf[:0], complex128(c), 'g', -1, 64))
166 }
167
168 func printuint(v uint64) {
169
170
171
172
173 var buf [20]byte
174 i := strconv.RuntimeFormatBase10(buf[:], v)
175 gwrite(buf[i:])
176 }
177
178 func printint(v int64) {
179
180
181
182
183 neg := v < 0
184 u := uint64(v)
185 if neg {
186 u = -u
187 }
188 var buf [20]byte
189 i := strconv.RuntimeFormatBase10(buf[:], u)
190 if neg {
191 i--
192 buf[i] = '-'
193 }
194 gwrite(buf[i:])
195 }
196
197 var minhexdigits = 0
198
199 func printhexopts(include0x bool, mindigits int, v uint64) {
200 const dig = "0123456789abcdef"
201 var buf [100]byte
202 i := len(buf)
203 for i--; i > 0; i-- {
204 buf[i] = dig[v%16]
205 if v < 16 && len(buf)-i >= mindigits {
206 break
207 }
208 v /= 16
209 }
210 if include0x {
211 i--
212 buf[i] = 'x'
213 i--
214 buf[i] = '0'
215 }
216 gwrite(buf[i:])
217 }
218
219 func printhex(v uint64) {
220 printhexopts(true, minhexdigits, v)
221 }
222
223 func printquoted(s string) {
224 printlock()
225 gwrite([]byte(`"`))
226 for i, r := range s {
227 switch r {
228 case '\n':
229 gwrite([]byte(`\n`))
230 continue
231 case '\r':
232 gwrite([]byte(`\r`))
233 continue
234 case '\t':
235 gwrite([]byte(`\t`))
236 print()
237 continue
238 case '\\', '"':
239 gwrite([]byte{byte('\\'), byte(r)})
240 continue
241 case runeError:
242
243 if _, j := decoderune(s, uint(i)); j == uint(i+1) {
244 gwrite(bytes(`\x`))
245 printhexopts(false, 2, uint64(s[i]))
246 continue
247 }
248
249 }
250
251 if r >= ' ' && r <= '~' {
252 gwrite([]byte{byte(r)})
253 } else if r < 127 {
254 gwrite(bytes(`\x`))
255 printhexopts(false, 2, uint64(r))
256 } else if r < 0x1_0000 {
257 gwrite(bytes(`\u`))
258 printhexopts(false, 4, uint64(r))
259 } else {
260 gwrite(bytes(`\U`))
261 printhexopts(false, 8, uint64(r))
262 }
263 }
264 gwrite([]byte{byte('"')})
265 printunlock()
266 }
267
268 func printpointer(p unsafe.Pointer) {
269 printhex(uint64(uintptr(p)))
270 }
271 func printuintptr(p uintptr) {
272 printhex(uint64(p))
273 }
274
275 func printstring(s string) {
276 gwrite(bytes(s))
277 }
278
279 func printslice(s []byte) {
280 sp := (*slice)(unsafe.Pointer(&s))
281 print("[", len(s), "/", cap(s), "]")
282 printpointer(sp.array)
283 }
284
285 func printeface(e eface) {
286 print("(", e._type, ",", e.data, ")")
287 }
288
289 func printiface(i iface) {
290 print("(", i.tab, ",", i.data, ")")
291 }
292
View as plain text