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 func printfloat64(v float64) {
126 var buf [20]byte
127 gwrite(strconv.AppendFloat(buf[:0], v, 'g', -1, 64))
128 }
129
130 func printfloat32(v float32) {
131 var buf [20]byte
132 gwrite(strconv.AppendFloat(buf[:0], float64(v), 'g', -1, 32))
133 }
134
135 func printcomplex128(c complex128) {
136 var buf [44]byte
137 gwrite(strconv.AppendComplex(buf[:0], c, 'g', -1, 128))
138 }
139
140 func printcomplex64(c complex64) {
141 var buf [44]byte
142 gwrite(strconv.AppendComplex(buf[:0], complex128(c), 'g', -1, 64))
143 }
144
145 func printuint(v uint64) {
146
147
148
149
150 var buf [20]byte
151 i := strconv.RuntimeFormatBase10(buf[:], v)
152 gwrite(buf[i:])
153 }
154
155 func printint(v int64) {
156
157
158
159
160 neg := v < 0
161 u := uint64(v)
162 if neg {
163 u = -u
164 }
165 var buf [20]byte
166 i := strconv.RuntimeFormatBase10(buf[:], u)
167 if neg {
168 i--
169 buf[i] = '-'
170 }
171 gwrite(buf[i:])
172 }
173
174 var minhexdigits = 0
175
176 func printhexopts(include0x bool, mindigits int, v uint64) {
177 const dig = "0123456789abcdef"
178 var buf [100]byte
179 i := len(buf)
180 for i--; i > 0; i-- {
181 buf[i] = dig[v%16]
182 if v < 16 && len(buf)-i >= mindigits {
183 break
184 }
185 v /= 16
186 }
187 if include0x {
188 i--
189 buf[i] = 'x'
190 i--
191 buf[i] = '0'
192 }
193 gwrite(buf[i:])
194 }
195
196 func printhex(v uint64) {
197 printhexopts(true, minhexdigits, v)
198 }
199
200 func printquoted(s string) {
201 printlock()
202 gwrite([]byte(`"`))
203 for _, r := range s {
204 switch r {
205 case '\n':
206 gwrite([]byte(`\n`))
207 continue
208 case '\r':
209 gwrite([]byte(`\r`))
210 continue
211 case '\t':
212 gwrite([]byte(`\t`))
213 print()
214 continue
215 case '\\', '"':
216 gwrite([]byte{byte('\\'), byte(r)})
217 continue
218 }
219
220 if r >= ' ' && r <= '~' {
221 gwrite([]byte{byte(r)})
222 } else if r < 127 {
223 gwrite(bytes(`\x`))
224 printhexopts(false, 2, uint64(r))
225 } else if r < 0x1_0000 {
226 gwrite(bytes(`\u`))
227 printhexopts(false, 4, uint64(r))
228 } else {
229 gwrite(bytes(`\U`))
230 printhexopts(false, 8, uint64(r))
231 }
232 }
233 gwrite([]byte{byte('"')})
234 printunlock()
235 }
236
237 func printpointer(p unsafe.Pointer) {
238 printhex(uint64(uintptr(p)))
239 }
240 func printuintptr(p uintptr) {
241 printhex(uint64(p))
242 }
243
244 func printstring(s string) {
245 gwrite(bytes(s))
246 }
247
248 func printslice(s []byte) {
249 sp := (*slice)(unsafe.Pointer(&s))
250 print("[", len(s), "/", cap(s), "]")
251 printpointer(sp.array)
252 }
253
254 func printeface(e eface) {
255 print("(", e._type, ",", e.data, ")")
256 }
257
258 func printiface(i iface) {
259 print("(", i.tab, ",", i.data, ")")
260 }
261
View as plain text