github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/runtime/print.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 import "unsafe" 8 9 // The compiler knows that a print of a value of this type 10 // should use printhex instead of printuint (decimal). 11 type hex uint64 12 13 func bytes(s string) (ret []byte) { 14 rp := (*slice)(unsafe.Pointer(&ret)) 15 sp := stringStructOf(&s) 16 rp.array = sp.str 17 rp.len = sp.len 18 rp.cap = sp.len 19 return 20 } 21 22 var debuglock mutex 23 24 // The compiler emits calls to printlock and printunlock around 25 // the multiple calls that implement a single Go print or println 26 // statement. Some of the print helpers (printsp, for example) 27 // call print recursively. There is also the problem of a crash 28 // happening during the print routines and needing to acquire 29 // the print lock to print information about the crash. 30 // For both these reasons, let a thread acquire the printlock 'recursively'. 31 32 func printlock() { 33 mp := getg().m 34 mp.locks++ // do not reschedule between printlock++ and lock(&debuglock). 35 mp.printlock++ 36 if mp.printlock == 1 { 37 lock(&debuglock) 38 } 39 mp.locks-- // now we know debuglock is held and holding up mp.locks for us. 40 } 41 42 func printunlock() { 43 mp := getg().m 44 mp.printlock-- 45 if mp.printlock == 0 { 46 unlock(&debuglock) 47 } 48 } 49 50 // write to goroutine-local buffer if diverting output, 51 // or else standard error. 52 func gwrite(b []byte) { 53 if len(b) == 0 { 54 return 55 } 56 gp := getg() 57 if gp == nil || gp.writebuf == nil { 58 writeErr(b) 59 return 60 } 61 62 n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b) 63 gp.writebuf = gp.writebuf[:len(gp.writebuf)+n] 64 } 65 66 func printsp() { 67 print(" ") 68 } 69 70 func printnl() { 71 print("\n") 72 } 73 74 func printbool(v bool) { 75 if v { 76 print("true") 77 } else { 78 print("false") 79 } 80 } 81 82 func printfloat(v float64) { 83 switch { 84 case v != v: 85 print("NaN") 86 return 87 case v+v == v && v > 0: 88 print("+Inf") 89 return 90 case v+v == v && v < 0: 91 print("-Inf") 92 return 93 } 94 95 const n = 7 // digits printed 96 var buf [n + 7]byte 97 buf[0] = '+' 98 e := 0 // exp 99 if v == 0 { 100 if 1/v < 0 { 101 buf[0] = '-' 102 } 103 } else { 104 if v < 0 { 105 v = -v 106 buf[0] = '-' 107 } 108 109 // normalize 110 for v >= 10 { 111 e++ 112 v /= 10 113 } 114 for v < 1 { 115 e-- 116 v *= 10 117 } 118 119 // round 120 h := 5.0 121 for i := 0; i < n; i++ { 122 h /= 10 123 } 124 v += h 125 if v >= 10 { 126 e++ 127 v /= 10 128 } 129 } 130 131 // format +d.dddd+edd 132 for i := 0; i < n; i++ { 133 s := int(v) 134 buf[i+2] = byte(s + '0') 135 v -= float64(s) 136 v *= 10 137 } 138 buf[1] = buf[2] 139 buf[2] = '.' 140 141 buf[n+2] = 'e' 142 buf[n+3] = '+' 143 if e < 0 { 144 e = -e 145 buf[n+3] = '-' 146 } 147 148 buf[n+4] = byte(e/100) + '0' 149 buf[n+5] = byte(e/10)%10 + '0' 150 buf[n+6] = byte(e%10) + '0' 151 gwrite(buf[:]) 152 } 153 154 func printcomplex(c complex128) { 155 print("(", real(c), imag(c), "i)") 156 } 157 158 func printuint(v uint64) { 159 var buf [100]byte 160 i := len(buf) 161 for i--; i > 0; i-- { 162 buf[i] = byte(v%10 + '0') 163 if v < 10 { 164 break 165 } 166 v /= 10 167 } 168 gwrite(buf[i:]) 169 } 170 171 func printint(v int64) { 172 if v < 0 { 173 print("-") 174 v = -v 175 } 176 printuint(uint64(v)) 177 } 178 179 func printhex(v uint64) { 180 const dig = "0123456789abcdef" 181 var buf [100]byte 182 i := len(buf) 183 for i--; i > 0; i-- { 184 buf[i] = dig[v%16] 185 if v < 16 { 186 break 187 } 188 v /= 16 189 } 190 i-- 191 buf[i] = 'x' 192 i-- 193 buf[i] = '0' 194 gwrite(buf[i:]) 195 } 196 197 func printpointer(p unsafe.Pointer) { 198 printhex(uint64(uintptr(p))) 199 } 200 201 func printstring(s string) { 202 gwrite(bytes(s)) 203 } 204 205 func printslice(s []byte) { 206 sp := (*slice)(unsafe.Pointer(&s)) 207 print("[", len(s), "/", cap(s), "]") 208 printpointer(sp.array) 209 } 210 211 func printeface(e eface) { 212 print("(", e._type, ",", e.data, ")") 213 } 214 215 func printiface(i iface) { 216 print("(", i.tab, ",", i.data, ")") 217 }