2016-08-05 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / libgo / go / runtime / print.go
blob32626c1e9dff14e3ced2b37906340eb004aadc2e
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.
5 package runtime
7 import "unsafe"
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
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
22 var debuglock mutex
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'.
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)
39 mp.locks-- // now we know debuglock is held and holding up mp.locks for us.
42 func printunlock() {
43 mp := getg().m
44 mp.printlock--
45 if mp.printlock == 0 {
46 unlock(&debuglock)
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
56 gp := getg()
57 if gp == nil || gp.writebuf == nil {
58 writeErr(b)
59 return
62 n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
63 gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
66 func printsp() {
67 print(" ")
70 func printnl() {
71 print("\n")
74 func printbool(v bool) {
75 if v {
76 print("true")
77 } else {
78 print("false")
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
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] = '-'
103 } else {
104 if v < 0 {
105 v = -v
106 buf[0] = '-'
109 // normalize
110 for v >= 10 {
112 v /= 10
114 for v < 1 {
116 v *= 10
119 // round
120 h := 5.0
121 for i := 0; i < n; i++ {
122 h /= 10
124 v += h
125 if v >= 10 {
127 v /= 10
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
138 buf[1] = buf[2]
139 buf[2] = '.'
141 buf[n+2] = 'e'
142 buf[n+3] = '+'
143 if e < 0 {
144 e = -e
145 buf[n+3] = '-'
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[:])
154 func printcomplex(c complex128) {
155 print("(", real(c), imag(c), "i)")
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
166 v /= 10
168 gwrite(buf[i:])
171 func printint(v int64) {
172 if v < 0 {
173 print("-")
174 v = -v
176 printuint(uint64(v))
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
188 v /= 16
191 buf[i] = 'x'
193 buf[i] = '0'
194 gwrite(buf[i:])
197 func printpointer(p unsafe.Pointer) {
198 printhex(uint64(uintptr(p)))
201 func printstring(s string) {
202 if uintptr(len(s)) > maxstring {
203 gwrite(bytes("[string too long]"))
204 return
206 gwrite(bytes(s))
209 func printslice(s []byte) {
210 sp := (*slice)(unsafe.Pointer(&s))
211 print("[", len(s), "/", cap(s), "]")
212 printpointer(sp.array)
215 func printeface(e eface) {
216 print("(", e._type, ",", e.data, ")")
219 func printiface(i iface) {
220 print("(", i.tab, ",", i.data, ")")