common.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /*
  2. * Copyright (c) 2013 Dave Collins <dave@davec.name>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. package spew
  17. import (
  18. "fmt"
  19. "io"
  20. "reflect"
  21. "sort"
  22. "strconv"
  23. "unsafe"
  24. )
  25. const (
  26. // ptrSize is the size of a pointer on the current arch.
  27. ptrSize = unsafe.Sizeof((*byte)(nil))
  28. )
  29. var (
  30. // offsetPtr, offsetScalar, and offsetFlag are the offsets for the
  31. // internal reflect.Value fields. These values are valid before golang
  32. // commit ecccf07e7f9d which changed the format. The are also valid
  33. // after commit 82f48826c6c7 which changed the format again to mirror
  34. // the original format. Code in the init function updates these offsets
  35. // as necessary.
  36. offsetPtr = uintptr(ptrSize)
  37. offsetScalar = uintptr(0)
  38. offsetFlag = uintptr(ptrSize * 2)
  39. // flagKindWidth and flagKindShift indicate various bits that the
  40. // reflect package uses internally to track kind information.
  41. //
  42. // flagRO indicates whether or not the value field of a reflect.Value is
  43. // read-only.
  44. //
  45. // flagIndir indicates whether the value field of a reflect.Value is
  46. // the actual data or a pointer to the data.
  47. //
  48. // These values are valid before golang commit 90a7c3c86944 which
  49. // changed their positions. Code in the init function updates these
  50. // flags as necessary.
  51. flagKindWidth = uintptr(5)
  52. flagKindShift = uintptr(flagKindWidth - 1)
  53. flagRO = uintptr(1 << 0)
  54. flagIndir = uintptr(1 << 1)
  55. )
  56. func init() {
  57. // Older versions of reflect.Value stored small integers directly in the
  58. // ptr field (which is named val in the older versions). Versions
  59. // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
  60. // scalar for this purpose which unfortunately came before the flag
  61. // field, so the offset of the flag field is different for those
  62. // versions.
  63. //
  64. // This code constructs a new reflect.Value from a known small integer
  65. // and checks if the size of the reflect.Value struct indicates it has
  66. // the scalar field. When it does, the offsets are updated accordingly.
  67. vv := reflect.ValueOf(0xf00)
  68. if unsafe.Sizeof(vv) == (ptrSize * 4) {
  69. offsetScalar = ptrSize * 2
  70. offsetFlag = ptrSize * 3
  71. }
  72. // Commit 90a7c3c86944 changed the flag positions such that the low
  73. // order bits are the kind. This code extracts the kind from the flags
  74. // field and ensures it's the correct type. When it's not, the flag
  75. // order has been changed to the newer format, so the flags are updated
  76. // accordingly.
  77. upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
  78. upfv := *(*uintptr)(upf)
  79. flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
  80. if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
  81. flagKindShift = 0
  82. flagRO = 1 << 5
  83. flagIndir = 1 << 6
  84. }
  85. }
  86. // unsafeReflectValue converts the passed reflect.Value into a one that bypasses
  87. // the typical safety restrictions preventing access to unaddressable and
  88. // unexported data. It works by digging the raw pointer to the underlying
  89. // value out of the protected value and generating a new unprotected (unsafe)
  90. // reflect.Value to it.
  91. //
  92. // This allows us to check for implementations of the Stringer and error
  93. // interfaces to be used for pretty printing ordinarily unaddressable and
  94. // inaccessible values such as unexported struct fields.
  95. func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
  96. indirects := 1
  97. vt := v.Type()
  98. upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
  99. rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
  100. if rvf&flagIndir != 0 {
  101. vt = reflect.PtrTo(v.Type())
  102. indirects++
  103. } else if offsetScalar != 0 {
  104. upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetScalar)
  105. }
  106. pv := reflect.NewAt(vt, upv)
  107. rv = pv
  108. for i := 0; i < indirects; i++ {
  109. rv = rv.Elem()
  110. }
  111. return rv
  112. }
  113. // Some constants in the form of bytes to avoid string overhead. This mirrors
  114. // the technique used in the fmt package.
  115. var (
  116. panicBytes = []byte("(PANIC=")
  117. plusBytes = []byte("+")
  118. iBytes = []byte("i")
  119. trueBytes = []byte("true")
  120. falseBytes = []byte("false")
  121. interfaceBytes = []byte("(interface {})")
  122. commaNewlineBytes = []byte(",\n")
  123. newlineBytes = []byte("\n")
  124. openBraceBytes = []byte("{")
  125. openBraceNewlineBytes = []byte("{\n")
  126. closeBraceBytes = []byte("}")
  127. asteriskBytes = []byte("*")
  128. colonBytes = []byte(":")
  129. colonSpaceBytes = []byte(": ")
  130. openParenBytes = []byte("(")
  131. closeParenBytes = []byte(")")
  132. spaceBytes = []byte(" ")
  133. pointerChainBytes = []byte("->")
  134. nilAngleBytes = []byte("<nil>")
  135. maxNewlineBytes = []byte("<max depth reached>\n")
  136. maxShortBytes = []byte("<max>")
  137. circularBytes = []byte("<already shown>")
  138. circularShortBytes = []byte("<shown>")
  139. invalidAngleBytes = []byte("<invalid>")
  140. openBracketBytes = []byte("[")
  141. closeBracketBytes = []byte("]")
  142. percentBytes = []byte("%")
  143. precisionBytes = []byte(".")
  144. openAngleBytes = []byte("<")
  145. closeAngleBytes = []byte(">")
  146. openMapBytes = []byte("map[")
  147. closeMapBytes = []byte("]")
  148. lenEqualsBytes = []byte("len=")
  149. capEqualsBytes = []byte("cap=")
  150. )
  151. // hexDigits is used to map a decimal value to a hex digit.
  152. var hexDigits = "0123456789abcdef"
  153. // catchPanic handles any panics that might occur during the handleMethods
  154. // calls.
  155. func catchPanic(w io.Writer, v reflect.Value) {
  156. if err := recover(); err != nil {
  157. w.Write(panicBytes)
  158. fmt.Fprintf(w, "%v", err)
  159. w.Write(closeParenBytes)
  160. }
  161. }
  162. // handleMethods attempts to call the Error and String methods on the underlying
  163. // type the passed reflect.Value represents and outputes the result to Writer w.
  164. //
  165. // It handles panics in any called methods by catching and displaying the error
  166. // as the formatted value.
  167. func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
  168. // We need an interface to check if the type implements the error or
  169. // Stringer interface. However, the reflect package won't give us an
  170. // interface on certain things like unexported struct fields in order
  171. // to enforce visibility rules. We use unsafe to bypass these restrictions
  172. // since this package does not mutate the values.
  173. if !v.CanInterface() {
  174. v = unsafeReflectValue(v)
  175. }
  176. // Choose whether or not to do error and Stringer interface lookups against
  177. // the base type or a pointer to the base type depending on settings.
  178. // Technically calling one of these methods with a pointer receiver can
  179. // mutate the value, however, types which choose to satisify an error or
  180. // Stringer interface with a pointer receiver should not be mutating their
  181. // state inside these interface methods.
  182. var viface interface{}
  183. if !cs.DisablePointerMethods {
  184. if !v.CanAddr() {
  185. v = unsafeReflectValue(v)
  186. }
  187. viface = v.Addr().Interface()
  188. } else {
  189. if v.CanAddr() {
  190. v = v.Addr()
  191. }
  192. viface = v.Interface()
  193. }
  194. // Is it an error or Stringer?
  195. switch iface := viface.(type) {
  196. case error:
  197. defer catchPanic(w, v)
  198. if cs.ContinueOnMethod {
  199. w.Write(openParenBytes)
  200. w.Write([]byte(iface.Error()))
  201. w.Write(closeParenBytes)
  202. w.Write(spaceBytes)
  203. return false
  204. }
  205. w.Write([]byte(iface.Error()))
  206. return true
  207. case fmt.Stringer:
  208. defer catchPanic(w, v)
  209. if cs.ContinueOnMethod {
  210. w.Write(openParenBytes)
  211. w.Write([]byte(iface.String()))
  212. w.Write(closeParenBytes)
  213. w.Write(spaceBytes)
  214. return false
  215. }
  216. w.Write([]byte(iface.String()))
  217. return true
  218. }
  219. return false
  220. }
  221. // printBool outputs a boolean value as true or false to Writer w.
  222. func printBool(w io.Writer, val bool) {
  223. if val {
  224. w.Write(trueBytes)
  225. } else {
  226. w.Write(falseBytes)
  227. }
  228. }
  229. // printInt outputs a signed integer value to Writer w.
  230. func printInt(w io.Writer, val int64, base int) {
  231. w.Write([]byte(strconv.FormatInt(val, base)))
  232. }
  233. // printUint outputs an unsigned integer value to Writer w.
  234. func printUint(w io.Writer, val uint64, base int) {
  235. w.Write([]byte(strconv.FormatUint(val, base)))
  236. }
  237. // printFloat outputs a floating point value using the specified precision,
  238. // which is expected to be 32 or 64bit, to Writer w.
  239. func printFloat(w io.Writer, val float64, precision int) {
  240. w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
  241. }
  242. // printComplex outputs a complex value using the specified float precision
  243. // for the real and imaginary parts to Writer w.
  244. func printComplex(w io.Writer, c complex128, floatPrecision int) {
  245. r := real(c)
  246. w.Write(openParenBytes)
  247. w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
  248. i := imag(c)
  249. if i >= 0 {
  250. w.Write(plusBytes)
  251. }
  252. w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
  253. w.Write(iBytes)
  254. w.Write(closeParenBytes)
  255. }
  256. // printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
  257. // prefix to Writer w.
  258. func printHexPtr(w io.Writer, p uintptr) {
  259. // Null pointer.
  260. num := uint64(p)
  261. if num == 0 {
  262. w.Write(nilAngleBytes)
  263. return
  264. }
  265. // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
  266. buf := make([]byte, 18)
  267. // It's simpler to construct the hex string right to left.
  268. base := uint64(16)
  269. i := len(buf) - 1
  270. for num >= base {
  271. buf[i] = hexDigits[num%base]
  272. num /= base
  273. i--
  274. }
  275. buf[i] = hexDigits[num]
  276. // Add '0x' prefix.
  277. i--
  278. buf[i] = 'x'
  279. i--
  280. buf[i] = '0'
  281. // Strip unused leading bytes.
  282. buf = buf[i:]
  283. w.Write(buf)
  284. }
  285. // valuesSorter implements sort.Interface to allow a slice of reflect.Value
  286. // elements to be sorted.
  287. type valuesSorter struct {
  288. values []reflect.Value
  289. }
  290. // Len returns the number of values in the slice. It is part of the
  291. // sort.Interface implementation.
  292. func (s *valuesSorter) Len() int {
  293. return len(s.values)
  294. }
  295. // Swap swaps the values at the passed indices. It is part of the
  296. // sort.Interface implementation.
  297. func (s *valuesSorter) Swap(i, j int) {
  298. s.values[i], s.values[j] = s.values[j], s.values[i]
  299. }
  300. // Less returns whether the value at index i should sort before the
  301. // value at index j. It is part of the sort.Interface implementation.
  302. func (s *valuesSorter) Less(i, j int) bool {
  303. switch s.values[i].Kind() {
  304. case reflect.Bool:
  305. return !s.values[i].Bool() && s.values[j].Bool()
  306. case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
  307. return s.values[i].Int() < s.values[j].Int()
  308. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  309. return s.values[i].Uint() < s.values[j].Uint()
  310. case reflect.Float32, reflect.Float64:
  311. return s.values[i].Float() < s.values[j].Float()
  312. case reflect.String:
  313. return s.values[i].String() < s.values[j].String()
  314. case reflect.Uintptr:
  315. return s.values[i].Uint() < s.values[j].Uint()
  316. }
  317. return s.values[i].String() < s.values[j].String()
  318. }
  319. // sortValues is a generic sort function for native types: int, uint, bool,
  320. // string and uintptr. Other inputs are sorted according to their
  321. // Value.String() value to ensure display stability.
  322. func sortValues(values []reflect.Value) {
  323. if len(values) == 0 {
  324. return
  325. }
  326. sort.Sort(&valuesSorter{values})
  327. }