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