123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- package spew
- import (
- "fmt"
- "io"
- "reflect"
- "sort"
- "strconv"
- "unsafe"
- )
- const (
-
- ptrSize = unsafe.Sizeof((*byte)(nil))
- )
- var (
-
-
-
-
-
-
- offsetPtr = uintptr(ptrSize)
- offsetScalar = uintptr(0)
- offsetFlag = uintptr(ptrSize * 2)
-
-
-
-
-
-
-
-
-
-
-
-
- flagKindWidth = uintptr(5)
- flagKindShift = uintptr(flagKindWidth - 1)
- flagRO = uintptr(1 << 0)
- flagIndir = uintptr(1 << 1)
- )
- func init() {
-
-
-
-
-
-
-
-
-
-
- vv := reflect.ValueOf(0xf00)
- if unsafe.Sizeof(vv) == (ptrSize * 4) {
- offsetScalar = ptrSize * 2
- offsetFlag = ptrSize * 3
- }
-
-
-
-
-
- upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
- upfv := *(*uintptr)(upf)
- flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
- if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
- flagKindShift = 0
- flagRO = 1 << 5
- flagIndir = 1 << 6
- }
- }
- func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
- indirects := 1
- vt := v.Type()
- upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
- rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
- if rvf&flagIndir != 0 {
- vt = reflect.PtrTo(v.Type())
- indirects++
- } else if offsetScalar != 0 {
-
-
- switch vt.Kind() {
- case reflect.Uintptr:
- case reflect.Chan:
- case reflect.Func:
- case reflect.Map:
- case reflect.Ptr:
- case reflect.UnsafePointer:
- default:
- upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
- offsetScalar)
- }
- }
- pv := reflect.NewAt(vt, upv)
- rv = pv
- for i := 0; i < indirects; i++ {
- rv = rv.Elem()
- }
- return rv
- }
- var (
- panicBytes = []byte("(PANIC=")
- plusBytes = []byte("+")
- iBytes = []byte("i")
- trueBytes = []byte("true")
- falseBytes = []byte("false")
- interfaceBytes = []byte("(interface {})")
- commaNewlineBytes = []byte(",\n")
- newlineBytes = []byte("\n")
- openBraceBytes = []byte("{")
- openBraceNewlineBytes = []byte("{\n")
- closeBraceBytes = []byte("}")
- asteriskBytes = []byte("*")
- colonBytes = []byte(":")
- colonSpaceBytes = []byte(": ")
- openParenBytes = []byte("(")
- closeParenBytes = []byte(")")
- spaceBytes = []byte(" ")
- pointerChainBytes = []byte("->")
- nilAngleBytes = []byte("<nil>")
- maxNewlineBytes = []byte("<max depth reached>\n")
- maxShortBytes = []byte("<max>")
- circularBytes = []byte("<already shown>")
- circularShortBytes = []byte("<shown>")
- invalidAngleBytes = []byte("<invalid>")
- openBracketBytes = []byte("[")
- closeBracketBytes = []byte("]")
- percentBytes = []byte("%")
- precisionBytes = []byte(".")
- openAngleBytes = []byte("<")
- closeAngleBytes = []byte(">")
- openMapBytes = []byte("map[")
- closeMapBytes = []byte("]")
- lenEqualsBytes = []byte("len=")
- capEqualsBytes = []byte("cap=")
- )
- var hexDigits = "0123456789abcdef"
- func catchPanic(w io.Writer, v reflect.Value) {
- if err := recover(); err != nil {
- w.Write(panicBytes)
- fmt.Fprintf(w, "%v", err)
- w.Write(closeParenBytes)
- }
- }
- func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
-
-
-
-
-
- if !v.CanInterface() {
- v = unsafeReflectValue(v)
- }
-
-
-
-
-
-
- var viface interface{}
- if !cs.DisablePointerMethods {
- if !v.CanAddr() {
- v = unsafeReflectValue(v)
- }
- viface = v.Addr().Interface()
- } else {
- if v.CanAddr() {
- v = v.Addr()
- }
- viface = v.Interface()
- }
-
- switch iface := viface.(type) {
- case error:
- defer catchPanic(w, v)
- if cs.ContinueOnMethod {
- w.Write(openParenBytes)
- w.Write([]byte(iface.Error()))
- w.Write(closeParenBytes)
- w.Write(spaceBytes)
- return false
- }
- w.Write([]byte(iface.Error()))
- return true
- case fmt.Stringer:
- defer catchPanic(w, v)
- if cs.ContinueOnMethod {
- w.Write(openParenBytes)
- w.Write([]byte(iface.String()))
- w.Write(closeParenBytes)
- w.Write(spaceBytes)
- return false
- }
- w.Write([]byte(iface.String()))
- return true
- }
- return false
- }
- func printBool(w io.Writer, val bool) {
- if val {
- w.Write(trueBytes)
- } else {
- w.Write(falseBytes)
- }
- }
- func printInt(w io.Writer, val int64, base int) {
- w.Write([]byte(strconv.FormatInt(val, base)))
- }
- func printUint(w io.Writer, val uint64, base int) {
- w.Write([]byte(strconv.FormatUint(val, base)))
- }
- func printFloat(w io.Writer, val float64, precision int) {
- w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
- }
- func printComplex(w io.Writer, c complex128, floatPrecision int) {
- r := real(c)
- w.Write(openParenBytes)
- w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
- i := imag(c)
- if i >= 0 {
- w.Write(plusBytes)
- }
- w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
- w.Write(iBytes)
- w.Write(closeParenBytes)
- }
- func printHexPtr(w io.Writer, p uintptr) {
-
- num := uint64(p)
- if num == 0 {
- w.Write(nilAngleBytes)
- return
- }
-
- buf := make([]byte, 18)
-
- base := uint64(16)
- i := len(buf) - 1
- for num >= base {
- buf[i] = hexDigits[num%base]
- num /= base
- i--
- }
- buf[i] = hexDigits[num]
-
- i--
- buf[i] = 'x'
- i--
- buf[i] = '0'
-
- buf = buf[i:]
- w.Write(buf)
- }
- type valuesSorter struct {
- values []reflect.Value
- }
- func (s *valuesSorter) Len() int {
- return len(s.values)
- }
- func (s *valuesSorter) Swap(i, j int) {
- s.values[i], s.values[j] = s.values[j], s.values[i]
- }
- func valueSortLess(a, b reflect.Value) bool {
- switch a.Kind() {
- case reflect.Bool:
- return !a.Bool() && b.Bool()
- case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
- return a.Int() < b.Int()
- case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
- return a.Uint() < b.Uint()
- case reflect.Float32, reflect.Float64:
- return a.Float() < b.Float()
- case reflect.String:
- return a.String() < b.String()
- case reflect.Uintptr:
- return a.Uint() < b.Uint()
- case reflect.Array:
-
- l := a.Len()
- for i := 0; i < l; i++ {
- av := a.Index(i)
- bv := b.Index(i)
- if av.Interface() == bv.Interface() {
- continue
- }
- return valueSortLess(av, bv)
- }
- }
- return a.String() < b.String()
- }
- func (s *valuesSorter) Less(i, j int) bool {
- return valueSortLess(s.values[i], s.values[j])
- }
- func sortValues(values []reflect.Value) {
- if len(values) == 0 {
- return
- }
- sort.Sort(&valuesSorter{values})
- }
|