OSDN Git Service

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