This source file includes following definitions.
- gwrite
- runtimeツキdump
- runtimeツキprints
- runtimeツキprintf
- runtimeツキsnprintf
- vprintf
- runtimeツキgoprintf
- runtimeツキprintpc
- runtimeツキprintbool
- runtimeツキprintbyte
- runtimeツキprintfloat
- runtimeツキprintcomplex
- runtimeツキprintuint
- runtimeツキprintint
- runtimeツキprinthex
- runtimeツキprintpointer
- runtimeツキprintstring
- runtimeツキprintsp
- runtimeツキprintnl
#include "runtime.h"
#include "type.h"
#include "../../cmd/ld/textflag.h"
static void vprintf(int8*, byte*);
static void
gwrite(void *v, intgo n)
{
if(g == nil || g->writebuf == nil) {
runtimeツキwrite(2, v, n);
return;
}
if(g->writenbuf == 0)
return;
if(n > g->writenbuf)
n = g->writenbuf;
runtimeツキmemmove(g->writebuf, v, n);
g->writebuf += n;
g->writenbuf -= n;
}
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)
{
gwrite(s, runtimeツキfindnull((byte*)s));
}
#pragma textflag NOSPLIT
void
runtimeツキprintf(int8 *s, ...)
{
byte *arg;
arg = (byte*)(&s+1);
vprintf(s, arg);
}
#pragma textflag NOSPLIT
int32
runtimeツキsnprintf(byte *buf, int32 n, int8 *s, ...)
{
byte *arg;
int32 m;
arg = (byte*)(&s+1);
g->writebuf = buf;
g->writenbuf = n-1;
vprintf(s, arg);
*g->writebuf = '\0';
m = g->writebuf - buf;
g->writenbuf = 0;
g->writebuf = nil;
return m;
}
static void
vprintf(int8 *s, byte *base)
{
int8 *p, *lp;
uintptr arg, siz;
byte *v;
lp = p = s;
arg = (uintptr)base;
for(; *p; p++) {
if(*p != '%')
continue;
if(p > lp)
gwrite(lp, p-lp);
p++;
siz = 0;
switch(*p) {
case 't':
case 'c':
siz = 1;
break;
case 'd':
case 'x':
arg = ROUND(arg, 4);
siz = 4;
break;
case 'D':
case 'U':
case 'X':
case 'f':
arg = ROUND(arg, sizeof(uintreg));
siz = 8;
break;
case 'C':
arg = ROUND(arg, sizeof(uintreg));
siz = 16;
break;
case 'p':
case 's':
arg = ROUND(arg, sizeof(uintptr));
siz = sizeof(uintptr);
break;
case 'S':
arg = ROUND(arg, sizeof(uintptr));
siz = sizeof(String);
break;
case 'a':
arg = ROUND(arg, sizeof(uintptr));
siz = sizeof(Slice);
break;
case 'i':
case 'e':
arg = ROUND(arg, sizeof(uintptr));
siz = sizeof(Eface);
break;
}
v = (byte*)arg;
switch(*p) {
case 'a':
runtimeツキprintslice(*(Slice*)v);
break;
case 'c':
runtimeツキprintbyte(*(int8*)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 += siz;
lp = p+1;
}
if(p > lp)
gwrite(lp, p-lp);
}
#pragma textflag NOSPLIT
void
runtimeツキgoprintf(String s, ...)
{
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) {
gwrite((byte*)"true", 4);
return;
}
gwrite((byte*)"false", 5);
}
void
runtimeツキprintbyte(int8 c)
{
gwrite(&c, 1);
}
void
runtimeツキprintfloat(float64 v)
{
byte buf[20];
int32 e, s, i, n;
float64 h;
if(ISNAN(v)) {
gwrite("NaN", 3);
return;
}
if(v == runtimeツキposinf) {
gwrite("+Inf", 4);
return;
}
if(v == runtimeツキneginf) {
gwrite("-Inf", 4);
return;
}
n = 7;
e = 0;
s = 0;
if(v == 0) {
if(1/v == runtimeツキneginf)
s = 1;
} else {
if(v < 0) {
v = -v;
s = 1;
}
while(v >= 10) {
e++;
v /= 10;
}
while(v < 1) {
e--;
v *= 10;
}
h = 5;
for(i=0; i<n; i++)
h /= 10;
v += h;
if(v >= 10) {
e++;
v /= 10;
}
}
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';
gwrite(buf, n+7);
}
void
runtimeツキprintcomplex(Complex128 v)
{
gwrite("(", 1);
runtimeツキprintfloat(v.real);
runtimeツキprintfloat(v.imag);
gwrite("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;
}
gwrite(buf+i, nelem(buf)-i);
}
void
runtimeツキprintint(int64 v)
{
if(v < 0) {
gwrite("-", 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';
gwrite(buf+i, nelem(buf)-i);
}
void
runtimeツキprintpointer(void *p)
{
runtimeツキprinthex((uintptr)p);
}
void
runtimeツキprintstring(String v)
{
if(v.len > runtimeツキmaxstring) {
gwrite("[string too long]", 17);
return;
}
if(v.len > 0)
gwrite(v.str, v.len);
}
void
runtimeツキprintsp(void)
{
gwrite(" ", 1);
}
void
runtimeツキprintnl(void)
{
gwrite("\n", 1);
}