PR target/60017
[official-gcc.git] / libgo / runtime / print.c
blob766ddbdc499c3f8a09d46b2a2f9433a9e5f18b2a
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 #include <stdarg.h>
6 #include "runtime.h"
7 #include "array.h"
8 #include "go-type.h"
10 //static Lock debuglock;
12 static void go_vprintf(const char*, va_list);
14 // write to goroutine-local buffer if diverting output,
15 // or else standard error.
16 static void
17 gwrite(const void *v, intgo n)
19 G* g = runtime_g();
21 if(g == nil || g->writebuf == nil) {
22 // Avoid -D_FORTIFY_SOURCE problems.
23 int rv __attribute__((unused));
25 rv = runtime_write(2, v, n);
26 return;
29 if(g->writenbuf == 0)
30 return;
32 if(n > g->writenbuf)
33 n = g->writenbuf;
34 runtime_memmove(g->writebuf, v, n);
35 g->writebuf += n;
36 g->writenbuf -= n;
39 void
40 runtime_dump(byte *p, int32 n)
42 int32 i;
44 for(i=0; i<n; i++) {
45 runtime_printpointer((byte*)(uintptr)(p[i]>>4));
46 runtime_printpointer((byte*)(uintptr)(p[i]&0xf));
47 if((i&15) == 15)
48 runtime_prints("\n");
49 else
50 runtime_prints(" ");
52 if(n & 15)
53 runtime_prints("\n");
56 void
57 runtime_prints(const char *s)
59 gwrite(s, runtime_findnull((const byte*)s));
62 void
63 runtime_printf(const char *s, ...)
65 va_list va;
67 va_start(va, s);
68 go_vprintf(s, va);
69 va_end(va);
72 // Very simple printf. Only for debugging prints.
73 // Do not add to this without checking with Rob.
74 static void
75 go_vprintf(const char *s, va_list va)
77 const char *p, *lp;
79 //runtime_lock(&debuglock);
81 lp = p = s;
82 for(; *p; p++) {
83 if(*p != '%')
84 continue;
85 if(p > lp)
86 gwrite(lp, p-lp);
87 p++;
88 switch(*p) {
89 case 'a':
90 runtime_printslice(va_arg(va, Slice));
91 break;
92 case 'c':
93 runtime_printbyte(va_arg(va, int32));
94 break;
95 case 'd':
96 runtime_printint(va_arg(va, int32));
97 break;
98 case 'D':
99 runtime_printint(va_arg(va, int64));
100 break;
101 case 'e':
102 runtime_printeface(va_arg(va, Eface));
103 break;
104 case 'f':
105 runtime_printfloat(va_arg(va, float64));
106 break;
107 case 'C':
108 runtime_printcomplex(va_arg(va, __complex double));
109 break;
110 case 'i':
111 runtime_printiface(va_arg(va, Iface));
112 break;
113 case 'p':
114 runtime_printpointer(va_arg(va, void*));
115 break;
116 case 's':
117 runtime_prints(va_arg(va, char*));
118 break;
119 case 'S':
120 runtime_printstring(va_arg(va, String));
121 break;
122 case 't':
123 runtime_printbool(va_arg(va, int));
124 break;
125 case 'U':
126 runtime_printuint(va_arg(va, uint64));
127 break;
128 case 'x':
129 runtime_printhex(va_arg(va, uint32));
130 break;
131 case 'X':
132 runtime_printhex(va_arg(va, uint64));
133 break;
135 lp = p+1;
137 if(p > lp)
138 gwrite(lp, p-lp);
140 //runtime_unlock(&debuglock);
143 void
144 runtime_printpc(void *p __attribute__ ((unused)))
146 runtime_prints("PC=");
147 runtime_printhex((uint64)(uintptr)runtime_getcallerpc(p));
150 void
151 runtime_printbool(_Bool v)
153 if(v) {
154 gwrite("true", 4);
155 return;
157 gwrite("false", 5);
160 void
161 runtime_printbyte(int8 c)
163 gwrite(&c, 1);
166 void
167 runtime_printfloat(double v)
169 byte buf[20];
170 int32 e, s, i, n;
171 float64 h;
173 if(ISNAN(v)) {
174 gwrite("NaN", 3);
175 return;
177 i = __builtin_isinf_sign(v);
178 if(i > 0) {
179 gwrite("+Inf", 4);
180 return;
182 if(i < 0) {
183 gwrite("-Inf", 4);
184 return;
187 n = 7; // digits printed
188 e = 0; // exp
189 s = 0; // sign
190 if(v != 0) {
191 // sign
192 if(v < 0) {
193 v = -v;
194 s = 1;
197 // normalize
198 while(v >= 10) {
199 e++;
200 v /= 10;
202 while(v < 1) {
203 e--;
204 v *= 10;
207 // round
208 h = 5;
209 for(i=0; i<n; i++)
210 h /= 10;
212 v += h;
213 if(v >= 10) {
214 e++;
215 v /= 10;
219 // format +d.dddd+edd
220 buf[0] = '+';
221 if(s)
222 buf[0] = '-';
223 for(i=0; i<n; i++) {
224 s = v;
225 buf[i+2] = s+'0';
226 v -= s;
227 v *= 10.;
229 buf[1] = buf[2];
230 buf[2] = '.';
232 buf[n+2] = 'e';
233 buf[n+3] = '+';
234 if(e < 0) {
235 e = -e;
236 buf[n+3] = '-';
239 buf[n+4] = (e/100) + '0';
240 buf[n+5] = (e/10)%10 + '0';
241 buf[n+6] = (e%10) + '0';
242 gwrite(buf, n+7);
245 void
246 runtime_printcomplex(__complex double v)
248 gwrite("(", 1);
249 runtime_printfloat(__builtin_creal(v));
250 runtime_printfloat(__builtin_cimag(v));
251 gwrite("i)", 2);
254 void
255 runtime_printuint(uint64 v)
257 byte buf[100];
258 int32 i;
260 for(i=nelem(buf)-1; i>0; i--) {
261 buf[i] = v%10 + '0';
262 if(v < 10)
263 break;
264 v = v/10;
266 gwrite(buf+i, nelem(buf)-i);
269 void
270 runtime_printint(int64 v)
272 if(v < 0) {
273 gwrite("-", 1);
274 v = -v;
276 runtime_printuint(v);
279 void
280 runtime_printhex(uint64 v)
282 static const char *dig = "0123456789abcdef";
283 byte buf[100];
284 int32 i;
286 i=nelem(buf);
287 for(; v>0; v/=16)
288 buf[--i] = dig[v%16];
289 if(i == nelem(buf))
290 buf[--i] = '0';
291 buf[--i] = 'x';
292 buf[--i] = '0';
293 gwrite(buf+i, nelem(buf)-i);
296 void
297 runtime_printpointer(void *p)
299 runtime_printhex((uint64)(uintptr)p);
302 void
303 runtime_printstring(String v)
305 // if(v.len > runtime_maxstring) {
306 // gwrite("[string too long]", 17);
307 // return;
308 // }
309 if(v.len > 0)
310 gwrite(v.str, v.len);
313 void
314 __go_print_space(void)
316 gwrite(" ", 1);
319 void
320 __go_print_nl(void)
322 gwrite("\n", 1);