Importing Upstream version 4.8.2
[platform/upstream/gcc48.git] / libgo / runtime / print.c
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 #include <stdarg.h>
6 #include "runtime.h"
7 #include "array.h"
8
9 //static Lock debuglock;
10
11 static void go_vprintf(const char*, va_list);
12
13 // write to goroutine-local buffer if diverting output,
14 // or else standard error.
15 static void
16 gwrite(const void *v, int32 n)
17 {
18         G* g = runtime_g();
19
20         if(g == nil || g->writebuf == nil) {
21                 // Avoid -D_FORTIFY_SOURCE problems.
22                 int rv __attribute__((unused));
23
24                 rv = runtime_write(2, v, n);
25                 return;
26         }
27
28         if(g->writenbuf == 0)
29                 return;
30
31         if(n > g->writenbuf)
32                 n = g->writenbuf;
33         runtime_memmove(g->writebuf, v, n);
34         g->writebuf += n;
35         g->writenbuf -= n;
36 }
37
38 void
39 runtime_dump(byte *p, int32 n)
40 {
41         int32 i;
42
43         for(i=0; i<n; i++) {
44                 runtime_printpointer((byte*)(uintptr)(p[i]>>4));
45                 runtime_printpointer((byte*)(uintptr)(p[i]&0xf));
46                 if((i&15) == 15)
47                         runtime_prints("\n");
48                 else
49                         runtime_prints(" ");
50         }
51         if(n & 15)
52                 runtime_prints("\n");
53 }
54
55 void
56 runtime_prints(const char *s)
57 {
58         gwrite(s, runtime_findnull((const byte*)s));
59 }
60
61 void
62 runtime_printf(const char *s, ...)
63 {
64         va_list va;
65
66         va_start(va, s);
67         go_vprintf(s, va);
68         va_end(va);
69 }
70
71 // Very simple printf.  Only for debugging prints.
72 // Do not add to this without checking with Rob.
73 static void
74 go_vprintf(const char *s, va_list va)
75 {
76         const char *p, *lp;
77
78         //runtime_lock(&debuglock);
79
80         lp = p = s;
81         for(; *p; p++) {
82                 if(*p != '%')
83                         continue;
84                 if(p > lp)
85                         gwrite(lp, p-lp);
86                 p++;
87                 switch(*p) {
88                 case 'a':
89                         runtime_printslice(va_arg(va, Slice));
90                         break;
91                 case 'c':
92                         runtime_printbyte(va_arg(va, int32));
93                         break;
94                 case 'd':
95                         runtime_printint(va_arg(va, int32));
96                         break;
97                 case 'D':
98                         runtime_printint(va_arg(va, int64));
99                         break;
100                 case 'e':
101                         runtime_printeface(va_arg(va, Eface));
102                         break;
103                 case 'f':
104                         runtime_printfloat(va_arg(va, float64));
105                         break;
106                 case 'C':
107                         runtime_printcomplex(va_arg(va, __complex double));
108                         break;
109                 case 'i':
110                         runtime_printiface(va_arg(va, Iface));
111                         break;
112                 case 'p':
113                         runtime_printpointer(va_arg(va, void*));
114                         break;
115                 case 's':
116                         runtime_prints(va_arg(va, char*));
117                         break;
118                 case 'S':
119                         runtime_printstring(va_arg(va, String));
120                         break;
121                 case 't':
122                         runtime_printbool(va_arg(va, int));
123                         break;
124                 case 'U':
125                         runtime_printuint(va_arg(va, uint64));
126                         break;
127                 case 'x':
128                         runtime_printhex(va_arg(va, uint32));
129                         break;
130                 case 'X':
131                         runtime_printhex(va_arg(va, uint64));
132                         break;
133                 }
134                 lp = p+1;
135         }
136         if(p > lp)
137                 gwrite(lp, p-lp);
138
139         //runtime_unlock(&debuglock);
140 }
141
142 void
143 runtime_printpc(void *p __attribute__ ((unused)))
144 {
145         runtime_prints("PC=");
146         runtime_printhex((uint64)(uintptr)runtime_getcallerpc(p));
147 }
148
149 void
150 runtime_printbool(_Bool v)
151 {
152         if(v) {
153                 gwrite("true", 4);
154                 return;
155         }
156         gwrite("false", 5);
157 }
158
159 void
160 runtime_printbyte(int8 c)
161 {
162         gwrite(&c, 1);
163 }
164
165 void
166 runtime_printfloat(double v)
167 {
168         byte buf[20];
169         int32 e, s, i, n;
170         float64 h;
171
172         if(ISNAN(v)) {
173                 gwrite("NaN", 3);
174                 return;
175         }
176         i = __builtin_isinf_sign(v);
177         if(i > 0) {
178                 gwrite("+Inf", 4);
179                 return;
180         }
181         if(i < 0) {
182                 gwrite("-Inf", 4);
183                 return;
184         }
185
186         n = 7;  // digits printed
187         e = 0;  // exp
188         s = 0;  // sign
189         if(v != 0) {
190                 // sign
191                 if(v < 0) {
192                         v = -v;
193                         s = 1;
194                 }
195
196                 // normalize
197                 while(v >= 10) {
198                         e++;
199                         v /= 10;
200                 }
201                 while(v < 1) {
202                         e--;
203                         v *= 10;
204                 }
205
206                 // round
207                 h = 5;
208                 for(i=0; i<n; i++)
209                         h /= 10;
210
211                 v += h;
212                 if(v >= 10) {
213                         e++;
214                         v /= 10;
215                 }
216         }
217
218         // format +d.dddd+edd
219         buf[0] = '+';
220         if(s)
221                 buf[0] = '-';
222         for(i=0; i<n; i++) {
223                 s = v;
224                 buf[i+2] = s+'0';
225                 v -= s;
226                 v *= 10.;
227         }
228         buf[1] = buf[2];
229         buf[2] = '.';
230
231         buf[n+2] = 'e';
232         buf[n+3] = '+';
233         if(e < 0) {
234                 e = -e;
235                 buf[n+3] = '-';
236         }
237
238         buf[n+4] = (e/100) + '0';
239         buf[n+5] = (e/10)%10 + '0';
240         buf[n+6] = (e%10) + '0';
241         gwrite(buf, n+7);
242 }
243
244 void
245 runtime_printcomplex(__complex double v)
246 {
247         gwrite("(", 1);
248         runtime_printfloat(__builtin_creal(v));
249         runtime_printfloat(__builtin_cimag(v));
250         gwrite("i)", 2);
251 }
252
253 void
254 runtime_printuint(uint64 v)
255 {
256         byte buf[100];
257         int32 i;
258
259         for(i=nelem(buf)-1; i>0; i--) {
260                 buf[i] = v%10 + '0';
261                 if(v < 10)
262                         break;
263                 v = v/10;
264         }
265         gwrite(buf+i, nelem(buf)-i);
266 }
267
268 void
269 runtime_printint(int64 v)
270 {
271         if(v < 0) {
272                 gwrite("-", 1);
273                 v = -v;
274         }
275         runtime_printuint(v);
276 }
277
278 void
279 runtime_printhex(uint64 v)
280 {
281         static const char *dig = "0123456789abcdef";
282         byte buf[100];
283         int32 i;
284
285         i=nelem(buf);
286         for(; v>0; v/=16)
287                 buf[--i] = dig[v%16];
288         if(i == nelem(buf))
289                 buf[--i] = '0';
290         buf[--i] = 'x';
291         buf[--i] = '0';
292         gwrite(buf+i, nelem(buf)-i);
293 }
294
295 void
296 runtime_printpointer(void *p)
297 {
298         runtime_printhex((uint64)(uintptr)p);
299 }
300
301 void
302 runtime_printstring(String v)
303 {
304         // extern uint32 runtime_maxstring;
305
306         // if(v.len > runtime_maxstring) {
307         //      gwrite("[string too long]", 17);
308         //      return;
309         // }
310         if(v.len > 0)
311                 gwrite(v.str, v.len);
312 }
313
314 void
315 __go_print_space(void)
316 {
317         gwrite(" ", 1);
318 }
319
320 void
321 __go_print_nl(void)
322 {
323         gwrite("\n", 1);
324 }