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