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