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 mp := getg().m
71 mp.locks++
72 mp.printlock++
73 if mp.printlock == 1 {
74 lock(&debuglock)
75 }
76 mp.locks--
77 }
78
79 func printunlock() {
80 mp := getg().m
81 mp.printlock--
82 if mp.printlock == 0 {
83 unlock(&debuglock)
84 }
85 }
86
87
88
89 func gwrite(b []byte) {
90 if len(b) == 0 {
91 return
92 }
93 recordForPanic(b)
94 gp := getg()
95
96
97
98
99
100 if gp == nil || gp.writebuf == nil || gp.m.dying > 0 {
101 writeErr(b)
102 return
103 }
104
105 n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
106 gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
107 }
108
109 func printsp() {
110 printstring(" ")
111 }
112
113 func printnl() {
114 printstring("\n")
115 }
116
117 func printbool(v bool) {
118 if v {
119 printstring("true")
120 } else {
121 printstring("false")
122 }
123 }
124
125
126 const float64Bytes = 24
127
128 func printfloat64(v float64) {
129 var buf [float64Bytes]byte
130 gwrite(strconv.AppendFloat(buf[:0], v, 'g', -1, 64))
131 }
132
133
134 const float32Bytes = 15
135
136 func printfloat32(v float32) {
137 var buf [float32Bytes]byte
138 gwrite(strconv.AppendFloat(buf[:0], float64(v), 'g', -1, 32))
139 }
140
141
142 const complex128Bytes = 2*float64Bytes + 3
143
144 func printcomplex128(c complex128) {
145 var buf [complex128Bytes]byte
146 gwrite(strconv.AppendComplex(buf[:0], c, 'g', -1, 128))
147 }
148
149
150 const complex64Bytes = 2*float32Bytes + 3
151
152 func printcomplex64(c complex64) {
153 var buf [complex64Bytes]byte
154 gwrite(strconv.AppendComplex(buf[:0], complex128(c), 'g', -1, 64))
155 }
156
157 func printuint(v uint64) {
158
159
160
161
162 var buf [20]byte
163 i := strconv.RuntimeFormatBase10(buf[:], v)
164 gwrite(buf[i:])
165 }
166
167 func printint(v int64) {
168
169
170
171
172 neg := v < 0
173 u := uint64(v)
174 if neg {
175 u = -u
176 }
177 var buf [20]byte
178 i := strconv.RuntimeFormatBase10(buf[:], u)
179 if neg {
180 i--
181 buf[i] = '-'
182 }
183 gwrite(buf[i:])
184 }
185
186 var minhexdigits = 0
187
188 func printhexopts(include0x bool, mindigits int, v uint64) {
189 const dig = "0123456789abcdef"
190 var buf [100]byte
191 i := len(buf)
192 for i--; i > 0; i-- {
193 buf[i] = dig[v%16]
194 if v < 16 && len(buf)-i >= mindigits {
195 break
196 }
197 v /= 16
198 }
199 if include0x {
200 i--
201 buf[i] = 'x'
202 i--
203 buf[i] = '0'
204 }
205 gwrite(buf[i:])
206 }
207
208 func printhex(v uint64) {
209 printhexopts(true, minhexdigits, v)
210 }
211
212 func printquoted(s string) {
213 printlock()
214 gwrite([]byte(`"`))
215 for i, r := range s {
216 switch r {
217 case '\n':
218 gwrite([]byte(`\n`))
219 continue
220 case '\r':
221 gwrite([]byte(`\r`))
222 continue
223 case '\t':
224 gwrite([]byte(`\t`))
225 print()
226 continue
227 case '\\', '"':
228 gwrite([]byte{byte('\\'), byte(r)})
229 continue
230 case runeError:
231
232 if _, j := decoderune(s, uint(i)); j == uint(i+1) {
233 gwrite(bytes(`\x`))
234 printhexopts(false, 2, uint64(s[i]))
235 continue
236 }
237
238 }
239
240 if r >= ' ' && r <= '~' {
241 gwrite([]byte{byte(r)})
242 } else if r < 127 {
243 gwrite(bytes(`\x`))
244 printhexopts(false, 2, uint64(r))
245 } else if r < 0x1_0000 {
246 gwrite(bytes(`\u`))
247 printhexopts(false, 4, uint64(r))
248 } else {
249 gwrite(bytes(`\U`))
250 printhexopts(false, 8, uint64(r))
251 }
252 }
253 gwrite([]byte{byte('"')})
254 printunlock()
255 }
256
257 func printpointer(p unsafe.Pointer) {
258 printhex(uint64(uintptr(p)))
259 }
260 func printuintptr(p uintptr) {
261 printhex(uint64(p))
262 }
263
264 func printstring(s string) {
265 gwrite(bytes(s))
266 }
267
268 func printslice(s []byte) {
269 sp := (*slice)(unsafe.Pointer(&s))
270 print("[", len(s), "/", cap(s), "]")
271 printpointer(sp.array)
272 }
273
274 func printeface(e eface) {
275 print("(", e._type, ",", e.data, ")")
276 }
277
278 func printiface(i iface) {
279 print("(", i.tab, ",", i.data, ")")
280 }
281
View as plain text