github.com/alash3al/go@v0.0.0-20150827002835-d497eeb00540/src/runtime/print1.go (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  package runtime
     6  
     7  import "unsafe"
     8  
     9  // The compiler knows that a print of a value of this type
    10  // should use printhex instead of printuint (decimal).
    11  type hex uint64
    12  
    13  func bytes(s string) (ret []byte) {
    14  	rp := (*slice)(unsafe.Pointer(&ret))
    15  	sp := (*_string)(noescape(unsafe.Pointer(&s)))
    16  	rp.array = unsafe.Pointer(sp.str)
    17  	rp.len = sp.len
    18  	rp.cap = sp.len
    19  	return
    20  }
    21  
    22  var debuglock mutex
    23  
    24  // The compiler emits calls to printlock and printunlock around
    25  // the multiple calls that implement a single Go print or println
    26  // statement. Some of the print helpers (printsp, for example)
    27  // call print recursively. There is also the problem of a crash
    28  // happening during the print routines and needing to acquire
    29  // the print lock to print information about the crash.
    30  // For both these reasons, let a thread acquire the printlock 'recursively'.
    31  
    32  func printlock() {
    33  	mp := getg().m
    34  	mp.locks++ // do not reschedule between printlock++ and lock(&debuglock).
    35  	mp.printlock++
    36  	if mp.printlock == 1 {
    37  		lock(&debuglock)
    38  	}
    39  	mp.locks-- // now we know debuglock is held and holding up mp.locks for us.
    40  }
    41  
    42  func printunlock() {
    43  	mp := getg().m
    44  	mp.printlock--
    45  	if mp.printlock == 0 {
    46  		unlock(&debuglock)
    47  	}
    48  }
    49  
    50  // write to goroutine-local buffer if diverting output,
    51  // or else standard error.
    52  func gwrite(b []byte) {
    53  	if len(b) == 0 {
    54  		return
    55  	}
    56  	gp := getg()
    57  	if gp == nil || gp.writebuf == nil {
    58  		writeErr(b)
    59  		return
    60  	}
    61  
    62  	n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
    63  	gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
    64  }
    65  
    66  func printsp() {
    67  	print(" ")
    68  }
    69  
    70  func printnl() {
    71  	print("\n")
    72  }
    73  
    74  func printpc(p unsafe.Pointer) {
    75  	print("PC=", hex(uintptr(p)))
    76  }
    77  
    78  func printbool(v bool) {
    79  	if v {
    80  		print("true")
    81  	} else {
    82  		print("false")
    83  	}
    84  }
    85  
    86  func printbyte(c byte) {
    87  	gwrite((*[1]byte)(unsafe.Pointer(&c))[:])
    88  }
    89  
    90  func printfloat(v float64) {
    91  	switch {
    92  	case v != v:
    93  		print("NaN")
    94  		return
    95  	case v+v == v && v > 0:
    96  		print("+Inf")
    97  		return
    98  	case v+v == v && v < 0:
    99  		print("-Inf")
   100  		return
   101  	}
   102  
   103  	const n = 7 // digits printed
   104  	var buf [n + 7]byte
   105  	buf[0] = '+'
   106  	e := 0 // exp
   107  	if v == 0 {
   108  		if 1/v < 0 {
   109  			buf[0] = '-'
   110  		}
   111  	} else {
   112  		if v < 0 {
   113  			v = -v
   114  			buf[0] = '-'
   115  		}
   116  
   117  		// normalize
   118  		for v >= 10 {
   119  			e++
   120  			v /= 10
   121  		}
   122  		for v < 1 {
   123  			e--
   124  			v *= 10
   125  		}
   126  
   127  		// round
   128  		h := 5.0
   129  		for i := 0; i < n; i++ {
   130  			h /= 10
   131  		}
   132  		v += h
   133  		if v >= 10 {
   134  			e++
   135  			v /= 10
   136  		}
   137  	}
   138  
   139  	// format +d.dddd+edd
   140  	for i := 0; i < n; i++ {
   141  		s := int(v)
   142  		buf[i+2] = byte(s + '0')
   143  		v -= float64(s)
   144  		v *= 10
   145  	}
   146  	buf[1] = buf[2]
   147  	buf[2] = '.'
   148  
   149  	buf[n+2] = 'e'
   150  	buf[n+3] = '+'
   151  	if e < 0 {
   152  		e = -e
   153  		buf[n+3] = '-'
   154  	}
   155  
   156  	buf[n+4] = byte(e/100) + '0'
   157  	buf[n+5] = byte(e/10)%10 + '0'
   158  	buf[n+6] = byte(e%10) + '0'
   159  	gwrite(buf[:])
   160  }
   161  
   162  func printcomplex(c complex128) {
   163  	print("(", real(c), imag(c), "i)")
   164  }
   165  
   166  func printuint(v uint64) {
   167  	var buf [100]byte
   168  	i := len(buf)
   169  	for i--; i > 0; i-- {
   170  		buf[i] = byte(v%10 + '0')
   171  		if v < 10 {
   172  			break
   173  		}
   174  		v /= 10
   175  	}
   176  	gwrite(buf[i:])
   177  }
   178  
   179  func printint(v int64) {
   180  	if v < 0 {
   181  		print("-")
   182  		v = -v
   183  	}
   184  	printuint(uint64(v))
   185  }
   186  
   187  func printhex(v uint64) {
   188  	const dig = "0123456789abcdef"
   189  	var buf [100]byte
   190  	i := len(buf)
   191  	for i--; i > 0; i-- {
   192  		buf[i] = dig[v%16]
   193  		if v < 16 {
   194  			break
   195  		}
   196  		v /= 16
   197  	}
   198  	i--
   199  	buf[i] = 'x'
   200  	i--
   201  	buf[i] = '0'
   202  	gwrite(buf[i:])
   203  }
   204  
   205  func printpointer(p unsafe.Pointer) {
   206  	printhex(uint64(uintptr(p)))
   207  }
   208  
   209  func printstring(s string) {
   210  	if uintptr(len(s)) > maxstring {
   211  		gwrite(bytes("[string too long]"))
   212  		return
   213  	}
   214  	gwrite(bytes(s))
   215  }
   216  
   217  func printslice(s []byte) {
   218  	sp := (*slice)(unsafe.Pointer(&s))
   219  	print("[", len(s), "/", cap(s), "]")
   220  	printpointer(unsafe.Pointer(sp.array))
   221  }
   222  
   223  func printeface(e interface{}) {
   224  	ep := (*eface)(unsafe.Pointer(&e))
   225  	print("(", ep._type, ",", ep.data, ")")
   226  }
   227  
   228  func printiface(i fInterface) {
   229  	ip := (*iface)(unsafe.Pointer(&i))
   230  	print("(", ip.tab, ",", ip.data, ")")
   231  }