github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/runtime/print.c (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 #include "runtime.h" 6 #include "type.h" 7 #include "../../cmd/ld/textflag.h" 8 9 //static Lock debuglock; 10 11 static void vprintf(int8*, byte*); 12 13 // write to goroutine-local buffer if diverting output, 14 // or else standard error. 15 static void 16 gwrite(void *v, intgo n) 17 { 18 if(g == nil || g->writebuf == nil) { 19 runtime·write(2, v, n); 20 return; 21 } 22 23 if(g->writenbuf == 0) 24 return; 25 26 if(n > g->writenbuf) 27 n = g->writenbuf; 28 runtime·memmove(g->writebuf, v, n); 29 g->writebuf += n; 30 g->writenbuf -= n; 31 } 32 33 void 34 runtime·dump(byte *p, int32 n) 35 { 36 int32 i; 37 38 for(i=0; i<n; i++) { 39 runtime·printpointer((byte*)(p[i]>>4)); 40 runtime·printpointer((byte*)(p[i]&0xf)); 41 if((i&15) == 15) 42 runtime·prints("\n"); 43 else 44 runtime·prints(" "); 45 } 46 if(n & 15) 47 runtime·prints("\n"); 48 } 49 50 void 51 runtime·prints(int8 *s) 52 { 53 gwrite(s, runtime·findnull((byte*)s)); 54 } 55 56 #pragma textflag NOSPLIT 57 void 58 runtime·printf(int8 *s, ...) 59 { 60 byte *arg; 61 62 arg = (byte*)(&s+1); 63 vprintf(s, arg); 64 } 65 66 // Very simple printf. Only for debugging prints. 67 // Do not add to this without checking with Rob. 68 static void 69 vprintf(int8 *s, byte *base) 70 { 71 int8 *p, *lp; 72 uintptr arg, narg; 73 byte *v; 74 75 //runtime·lock(&debuglock); 76 77 lp = p = s; 78 arg = 0; 79 for(; *p; p++) { 80 if(*p != '%') 81 continue; 82 if(p > lp) 83 gwrite(lp, p-lp); 84 p++; 85 narg = 0; 86 switch(*p) { 87 case 't': 88 case 'c': 89 narg = arg + 1; 90 break; 91 case 'd': // 32-bit 92 case 'x': 93 arg = ROUND(arg, 4); 94 narg = arg + 4; 95 break; 96 case 'D': // 64-bit 97 case 'U': 98 case 'X': 99 case 'f': 100 arg = ROUND(arg, sizeof(uintptr)); 101 narg = arg + 8; 102 break; 103 case 'C': 104 arg = ROUND(arg, sizeof(uintptr)); 105 narg = arg + 16; 106 break; 107 case 'p': // pointer-sized 108 case 's': 109 arg = ROUND(arg, sizeof(uintptr)); 110 narg = arg + sizeof(uintptr); 111 break; 112 case 'S': // pointer-aligned but bigger 113 arg = ROUND(arg, sizeof(uintptr)); 114 narg = arg + sizeof(String); 115 break; 116 case 'a': // pointer-aligned but bigger 117 arg = ROUND(arg, sizeof(uintptr)); 118 narg = arg + sizeof(Slice); 119 break; 120 case 'i': // pointer-aligned but bigger 121 case 'e': 122 arg = ROUND(arg, sizeof(uintptr)); 123 narg = arg + sizeof(Eface); 124 break; 125 } 126 v = base+arg; 127 switch(*p) { 128 case 'a': 129 runtime·printslice(*(Slice*)v); 130 break; 131 case 'c': 132 runtime·printbyte(*(int8*)v); 133 break; 134 case 'd': 135 runtime·printint(*(int32*)v); 136 break; 137 case 'D': 138 runtime·printint(*(int64*)v); 139 break; 140 case 'e': 141 runtime·printeface(*(Eface*)v); 142 break; 143 case 'f': 144 runtime·printfloat(*(float64*)v); 145 break; 146 case 'C': 147 runtime·printcomplex(*(Complex128*)v); 148 break; 149 case 'i': 150 runtime·printiface(*(Iface*)v); 151 break; 152 case 'p': 153 runtime·printpointer(*(void**)v); 154 break; 155 case 's': 156 runtime·prints(*(int8**)v); 157 break; 158 case 'S': 159 runtime·printstring(*(String*)v); 160 break; 161 case 't': 162 runtime·printbool(*(bool*)v); 163 break; 164 case 'U': 165 runtime·printuint(*(uint64*)v); 166 break; 167 case 'x': 168 runtime·printhex(*(uint32*)v); 169 break; 170 case 'X': 171 runtime·printhex(*(uint64*)v); 172 break; 173 } 174 arg = narg; 175 lp = p+1; 176 } 177 if(p > lp) 178 gwrite(lp, p-lp); 179 180 //runtime·unlock(&debuglock); 181 } 182 183 #pragma textflag NOSPLIT 184 void 185 runtime·goprintf(String s, ...) 186 { 187 // Can assume s has terminating NUL because only 188 // the Go compiler generates calls to runtime·goprintf, using 189 // string constants, and all the string constants have NULs. 190 vprintf((int8*)s.str, (byte*)(&s+1)); 191 } 192 193 void 194 runtime·printpc(void *p) 195 { 196 runtime·prints("PC="); 197 runtime·printhex((uint64)runtime·getcallerpc(p)); 198 } 199 200 void 201 runtime·printbool(bool v) 202 { 203 if(v) { 204 gwrite((byte*)"true", 4); 205 return; 206 } 207 gwrite((byte*)"false", 5); 208 } 209 210 void 211 runtime·printbyte(int8 c) 212 { 213 gwrite(&c, 1); 214 } 215 216 void 217 runtime·printfloat(float64 v) 218 { 219 byte buf[20]; 220 int32 e, s, i, n; 221 float64 h; 222 223 if(ISNAN(v)) { 224 gwrite("NaN", 3); 225 return; 226 } 227 if(v == runtime·posinf) { 228 gwrite("+Inf", 4); 229 return; 230 } 231 if(v == runtime·neginf) { 232 gwrite("-Inf", 4); 233 return; 234 } 235 236 n = 7; // digits printed 237 e = 0; // exp 238 s = 0; // sign 239 if(v != 0) { 240 // sign 241 if(v < 0) { 242 v = -v; 243 s = 1; 244 } 245 246 // normalize 247 while(v >= 10) { 248 e++; 249 v /= 10; 250 } 251 while(v < 1) { 252 e--; 253 v *= 10; 254 } 255 256 // round 257 h = 5; 258 for(i=0; i<n; i++) 259 h /= 10; 260 261 v += h; 262 if(v >= 10) { 263 e++; 264 v /= 10; 265 } 266 } 267 268 // format +d.dddd+edd 269 buf[0] = '+'; 270 if(s) 271 buf[0] = '-'; 272 for(i=0; i<n; i++) { 273 s = v; 274 buf[i+2] = s+'0'; 275 v -= s; 276 v *= 10.; 277 } 278 buf[1] = buf[2]; 279 buf[2] = '.'; 280 281 buf[n+2] = 'e'; 282 buf[n+3] = '+'; 283 if(e < 0) { 284 e = -e; 285 buf[n+3] = '-'; 286 } 287 288 buf[n+4] = (e/100) + '0'; 289 buf[n+5] = (e/10)%10 + '0'; 290 buf[n+6] = (e%10) + '0'; 291 gwrite(buf, n+7); 292 } 293 294 void 295 runtime·printcomplex(Complex128 v) 296 { 297 gwrite("(", 1); 298 runtime·printfloat(v.real); 299 runtime·printfloat(v.imag); 300 gwrite("i)", 2); 301 } 302 303 void 304 runtime·printuint(uint64 v) 305 { 306 byte buf[100]; 307 int32 i; 308 309 for(i=nelem(buf)-1; i>0; i--) { 310 buf[i] = v%10 + '0'; 311 if(v < 10) 312 break; 313 v = v/10; 314 } 315 gwrite(buf+i, nelem(buf)-i); 316 } 317 318 void 319 runtime·printint(int64 v) 320 { 321 if(v < 0) { 322 gwrite("-", 1); 323 v = -v; 324 } 325 runtime·printuint(v); 326 } 327 328 void 329 runtime·printhex(uint64 v) 330 { 331 static int8 *dig = "0123456789abcdef"; 332 byte buf[100]; 333 int32 i; 334 335 i=nelem(buf); 336 for(; v>0; v/=16) 337 buf[--i] = dig[v%16]; 338 if(i == nelem(buf)) 339 buf[--i] = '0'; 340 buf[--i] = 'x'; 341 buf[--i] = '0'; 342 gwrite(buf+i, nelem(buf)-i); 343 } 344 345 void 346 runtime·printpointer(void *p) 347 { 348 runtime·printhex((uint64)p); 349 } 350 351 void 352 runtime·printstring(String v) 353 { 354 if(v.len > runtime·maxstring) { 355 gwrite("[string too long]", 17); 356 return; 357 } 358 if(v.len > 0) 359 gwrite(v.str, v.len); 360 } 361 362 void 363 runtime·printsp(void) 364 { 365 gwrite(" ", 1); 366 } 367 368 void 369 runtime·printnl(void) 370 { 371 gwrite("\n", 1); 372 } 373 374 void 375 runtime·typestring(Eface e, String s) 376 { 377 s = *e.type->string; 378 FLUSH(&s); 379 } 380