diff options
Diffstat (limited to 'src/pkg/runtime/print.c')
-rw-r--r-- | src/pkg/runtime/print.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/src/pkg/runtime/print.c b/src/pkg/runtime/print.c new file mode 100644 index 000000000..3ce779495 --- /dev/null +++ b/src/pkg/runtime/print.c @@ -0,0 +1,351 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "runtime.h" +#include "type.h" + +//static Lock debuglock; + +static void vprintf(int8*, byte*); + +void +runtime·dump(byte *p, int32 n) +{ + int32 i; + + for(i=0; i<n; i++) { + runtime·printpointer((byte*)(p[i]>>4)); + runtime·printpointer((byte*)(p[i]&0xf)); + if((i&15) == 15) + runtime·prints("\n"); + else + runtime·prints(" "); + } + if(n & 15) + runtime·prints("\n"); +} + +void +runtime·prints(int8 *s) +{ + runtime·write(2, s, runtime·findnull((byte*)s)); +} + +#pragma textflag 7 +void +runtime·printf(int8 *s, ...) +{ + byte *arg; + + arg = (byte*)(&s+1); + vprintf(s, arg); +} + +// Very simple printf. Only for debugging prints. +// Do not add to this without checking with Rob. +static void +vprintf(int8 *s, byte *base) +{ + int8 *p, *lp; + uintptr arg, narg; + byte *v; + +// lock(&debuglock); + + lp = p = s; + arg = 0; + for(; *p; p++) { + if(*p != '%') + continue; + if(p > lp) + runtime·write(2, lp, p-lp); + p++; + narg = 0; + switch(*p) { + case 't': + narg = arg + 1; + break; + case 'd': // 32-bit + case 'x': + arg = runtime·rnd(arg, 4); + narg = arg + 4; + break; + case 'D': // 64-bit + case 'U': + case 'X': + case 'f': + arg = runtime·rnd(arg, sizeof(uintptr)); + narg = arg + 8; + break; + case 'C': + arg = runtime·rnd(arg, sizeof(uintptr)); + narg = arg + 16; + break; + case 'p': // pointer-sized + case 's': + arg = runtime·rnd(arg, sizeof(uintptr)); + narg = arg + sizeof(uintptr); + break; + case 'S': // pointer-aligned but bigger + arg = runtime·rnd(arg, sizeof(uintptr)); + narg = arg + sizeof(String); + break; + case 'a': // pointer-aligned but bigger + arg = runtime·rnd(arg, sizeof(uintptr)); + narg = arg + sizeof(Slice); + break; + case 'i': // pointer-aligned but bigger + case 'e': + arg = runtime·rnd(arg, sizeof(uintptr)); + narg = arg + sizeof(Eface); + break; + } + v = base+arg; + switch(*p) { + case 'a': + runtime·printslice(*(Slice*)v); + break; + case 'd': + runtime·printint(*(int32*)v); + break; + case 'D': + runtime·printint(*(int64*)v); + break; + case 'e': + runtime·printeface(*(Eface*)v); + break; + case 'f': + runtime·printfloat(*(float64*)v); + break; + case 'C': + runtime·printcomplex(*(Complex128*)v); + break; + case 'i': + runtime·printiface(*(Iface*)v); + break; + case 'p': + runtime·printpointer(*(void**)v); + break; + case 's': + runtime·prints(*(int8**)v); + break; + case 'S': + runtime·printstring(*(String*)v); + break; + case 't': + runtime·printbool(*(bool*)v); + break; + case 'U': + runtime·printuint(*(uint64*)v); + break; + case 'x': + runtime·printhex(*(uint32*)v); + break; + case 'X': + runtime·printhex(*(uint64*)v); + break; + } + arg = narg; + lp = p+1; + } + if(p > lp) + runtime·write(2, lp, p-lp); + +// unlock(&debuglock); +} + +#pragma textflag 7 +void +runtime·goprintf(String s, ...) +{ + // Can assume s has terminating NUL because only + // the Go compiler generates calls to runtime·goprintf, using + // string constants, and all the string constants have NULs. + vprintf((int8*)s.str, (byte*)(&s+1)); +} + +void +runtime·printpc(void *p) +{ + runtime·prints("PC="); + runtime·printhex((uint64)runtime·getcallerpc(p)); +} + +void +runtime·printbool(bool v) +{ + if(v) { + runtime·write(2, (byte*)"true", 4); + return; + } + runtime·write(2, (byte*)"false", 5); +} + +void +runtime·printfloat(float64 v) +{ + byte buf[20]; + int32 e, s, i, n; + float64 h; + + if(runtime·isNaN(v)) { + runtime·write(2, "NaN", 3); + return; + } + if(runtime·isInf(v, 1)) { + runtime·write(2, "+Inf", 4); + return; + } + if(runtime·isInf(v, -1)) { + runtime·write(2, "-Inf", 4); + return; + } + + n = 7; // digits printed + e = 0; // exp + s = 0; // sign + if(v != 0) { + // sign + if(v < 0) { + v = -v; + s = 1; + } + + // normalize + while(v >= 10) { + e++; + v /= 10; + } + while(v < 1) { + e--; + v *= 10; + } + + // round + h = 5; + for(i=0; i<n; i++) + h /= 10; + + v += h; + if(v >= 10) { + e++; + v /= 10; + } + } + + // format +d.dddd+edd + buf[0] = '+'; + if(s) + buf[0] = '-'; + for(i=0; i<n; i++) { + s = v; + buf[i+2] = s+'0'; + v -= s; + v *= 10.; + } + buf[1] = buf[2]; + buf[2] = '.'; + + buf[n+2] = 'e'; + buf[n+3] = '+'; + if(e < 0) { + e = -e; + buf[n+3] = '-'; + } + + buf[n+4] = (e/100) + '0'; + buf[n+5] = (e/10)%10 + '0'; + buf[n+6] = (e%10) + '0'; + runtime·write(2, buf, n+7); +} + +void +runtime·printcomplex(Complex128 v) +{ + runtime·write(2, "(", 1); + runtime·printfloat(v.real); + runtime·printfloat(v.imag); + runtime·write(2, "i)", 2); +} + +void +runtime·printuint(uint64 v) +{ + byte buf[100]; + int32 i; + + for(i=nelem(buf)-1; i>0; i--) { + buf[i] = v%10 + '0'; + if(v < 10) + break; + v = v/10; + } + runtime·write(2, buf+i, nelem(buf)-i); +} + +void +runtime·printint(int64 v) +{ + if(v < 0) { + runtime·write(2, "-", 1); + v = -v; + } + runtime·printuint(v); +} + +void +runtime·printhex(uint64 v) +{ + static int8 *dig = "0123456789abcdef"; + byte buf[100]; + int32 i; + + i=nelem(buf); + for(; v>0; v/=16) + buf[--i] = dig[v%16]; + if(i == nelem(buf)) + buf[--i] = '0'; + buf[--i] = 'x'; + buf[--i] = '0'; + runtime·write(2, buf+i, nelem(buf)-i); +} + +void +runtime·printpointer(void *p) +{ + runtime·printhex((uint64)p); +} + +void +runtime·printstring(String v) +{ + extern uint32 runtime·maxstring; + + if(v.len > runtime·maxstring) { + runtime·write(2, "[invalid string]", 16); + return; + } + if(v.len > 0) + runtime·write(2, v.str, v.len); +} + +void +runtime·printsp(void) +{ + runtime·write(2, " ", 1); +} + +void +runtime·printnl(void) +{ + runtime·write(2, "\n", 1); +} + +void +runtime·typestring(Eface e, String s) +{ + s = *e.type->string; + FLUSH(&s); +} + |