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 _, 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 }
231
232 if r >= ' ' && r <= '~' {
233 gwrite([]byte{byte(r)})
234 } else if r < 127 {
235 gwrite(bytes(`\x`))
236 printhexopts(false, 2, uint64(r))
237 } else if r < 0x1_0000 {
238 gwrite(bytes(`\u`))
239 printhexopts(false, 4, uint64(r))
240 } else {
241 gwrite(bytes(`\U`))
242 printhexopts(false, 8, uint64(r))
243 }
244 }
245 gwrite([]byte{byte('"')})
246 printunlock()
247 }
248
249 func printpointer(p unsafe.Pointer) {
250 printhex(uint64(uintptr(p)))
251 }
252 func printuintptr(p uintptr) {
253 printhex(uint64(p))
254 }
255
256 func printstring(s string) {
257 gwrite(bytes(s))
258 }
259
260 func printslice(s []byte) {
261 sp := (*slice)(unsafe.Pointer(&s))
262 print("[", len(s), "/", cap(s), "]")
263 printpointer(sp.array)
264 }
265
266 func printeface(e eface) {
267 print("(", e._type, ",", e.data, ")")
268 }
269
270 func printiface(i iface) {
271 print("(", i.tab, ",", i.data, ")")
272 }
273
View as plain text