common.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. // offsetPtr, offsetScalar, and offsetFlag are the offsets for the internal
  26. // reflect.Value fields.
  27. var offsetPtr, offsetScalar, offsetFlag uintptr
  28. // reflectValueOld mirrors the struct layout of the reflect package Value type
  29. // before golang commit ecccf07e7f9d.
  30. var reflectValueOld struct {
  31. typ unsafe.Pointer
  32. val unsafe.Pointer
  33. flag uintptr
  34. }
  35. // reflectValueNew mirrors the struct layout of the reflect package Value type
  36. // after golang commit ecccf07e7f9d.
  37. var reflectValueNew struct {
  38. typ unsafe.Pointer
  39. ptr unsafe.Pointer
  40. scalar uintptr
  41. flag uintptr
  42. }
  43. func init() {
  44. // Older versions of reflect.Value stored small integers directly in the
  45. // ptr field (which is named val in the older versions). Newer versions
  46. // added a new field named scalar for this purpose which unfortuantely
  47. // comes before the flag field. Further the new field is before the
  48. // flag field, so the offset of the flag field is different as well.
  49. // This code constructs a new reflect.Value from a known small integer
  50. // and checks if the val field within it matches. When it matches, the
  51. // old style reflect.Value is being used. Otherwise it's the new style.
  52. v := 0xf00
  53. vv := reflect.ValueOf(v)
  54. upv := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) +
  55. unsafe.Offsetof(reflectValueOld.val))
  56. // Assume the old style by default.
  57. offsetPtr = unsafe.Offsetof(reflectValueOld.val)
  58. offsetScalar = 0
  59. offsetFlag = unsafe.Offsetof(reflectValueOld.flag)
  60. // Use the new style offsets if the ptr field doesn't match the value
  61. // since it must be in the new scalar field.
  62. if int(*(*uintptr)(upv)) != v {
  63. offsetPtr = unsafe.Offsetof(reflectValueNew.ptr)
  64. offsetScalar = unsafe.Offsetof(reflectValueNew.scalar)
  65. offsetFlag = unsafe.Offsetof(reflectValueNew.flag)
  66. }
  67. }
  68. // flagIndir indicates whether the value field of a reflect.Value is the actual
  69. // data or a pointer to the data.
  70. const flagIndir = 1 << 1
  71. // unsafeReflectValue converts the passed reflect.Value into a one that bypasses
  72. // the typical safety restrictions preventing access to unaddressable and
  73. // unexported data. It works by digging the raw pointer to the underlying
  74. // value out of the protected value and generating a new unprotected (unsafe)
  75. // reflect.Value to it.
  76. //
  77. // This allows us to check for implementations of the Stringer and error
  78. // interfaces to be used for pretty printing ordinarily unaddressable and
  79. // inaccessible values such as unexported struct fields.
  80. func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
  81. indirects := 1
  82. vt := v.Type()
  83. upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
  84. rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
  85. if rvf&flagIndir != 0 {
  86. vt = reflect.PtrTo(v.Type())
  87. indirects++
  88. } else if offsetScalar != 0 {
  89. upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetScalar)
  90. }
  91. pv := reflect.NewAt(vt, upv)
  92. rv = pv
  93. for i := 0; i < indirects; i++ {
  94. rv = rv.Elem()
  95. }
  96. return rv
  97. }
  98. // Some constants in the form of bytes to avoid string overhead. This mirrors
  99. // the technique used in the fmt package.
  100. var (
  101. panicBytes = []byte("(PANIC=")
  102. plusBytes = []byte("+")
  103. iBytes = []byte("i")
  104. trueBytes = []byte("true")
  105. falseBytes = []byte("false")
  106. interfaceBytes = []byte("(interface {})")
  107. commaNewlineBytes = []byte(",\n")
  108. newlineBytes = []byte("\n")
  109. openBraceBytes = []byte("{")
  110. openBraceNewlineBytes = []byte("{\n")
  111. closeBraceBytes = []byte("}")
  112. asteriskBytes = []byte("*")
  113. colonBytes = []byte(":")
  114. colonSpaceBytes = []byte(": ")
  115. openParenBytes = []byte("(")
  116. closeParenBytes = []byte(")")
  117. spaceBytes = []byte(" ")
  118. pointerChainBytes = []byte("->")
  119. nilAngleBytes = []byte("<nil>")
  120. maxNewlineBytes = []byte("<max depth reached>\n")
  121. maxShortBytes = []byte("<max>")
  122. circularBytes = []byte("<already shown>")
  123. circularShortBytes = []byte("<shown>")
  124. invalidAngleBytes = []byte("<invalid>")
  125. openBracketBytes = []byte("[")
  126. closeBracketBytes = []byte("]")
  127. percentBytes = []byte("%")
  128. precisionBytes = []byte(".")
  129. openAngleBytes = []byte("<")
  130. closeAngleBytes = []byte(">")
  131. openMapBytes = []byte("map[")
  132. closeMapBytes = []byte("]")
  133. )
  134. // hexDigits is used to map a decimal value to a hex digit.
  135. var hexDigits = "0123456789abcdef"
  136. // catchPanic handles any panics that might occur during the handleMethods
  137. // calls.
  138. func catchPanic(w io.Writer, v reflect.Value) {
  139. if err := recover(); err != nil {
  140. w.Write(panicBytes)
  141. fmt.Fprintf(w, "%v", err)
  142. w.Write(closeParenBytes)
  143. }
  144. }
  145. // handleMethods attempts to call the Error and String methods on the underlying
  146. // type the passed reflect.Value represents and outputes the result to Writer w.
  147. //
  148. // It handles panics in any called methods by catching and displaying the error
  149. // as the formatted value.
  150. func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
  151. // We need an interface to check if the type implements the error or
  152. // Stringer interface. However, the reflect package won't give us an
  153. // interface on certain things like unexported struct fields in order
  154. // to enforce visibility rules. We use unsafe to bypass these restrictions
  155. // since this package does not mutate the values.
  156. if !v.CanInterface() {
  157. v = unsafeReflectValue(v)
  158. }
  159. // Choose whether or not to do error and Stringer interface lookups against
  160. // the base type or a pointer to the base type depending on settings.
  161. // Technically calling one of these methods with a pointer receiver can
  162. // mutate the value, however, types which choose to satisify an error or
  163. // Stringer interface with a pointer receiver should not be mutating their
  164. // state inside these interface methods.
  165. var viface interface{}
  166. if !cs.DisablePointerMethods {
  167. if !v.CanAddr() {
  168. v = unsafeReflectValue(v)
  169. }
  170. viface = v.Addr().Interface()
  171. } else {
  172. if v.CanAddr() {
  173. v = v.Addr()
  174. }
  175. viface = v.Interface()
  176. }
  177. // Is it an error or Stringer?
  178. switch iface := viface.(type) {
  179. case error:
  180. defer catchPanic(w, v)
  181. if cs.ContinueOnMethod {
  182. w.Write(openParenBytes)
  183. w.Write([]byte(iface.Error()))
  184. w.Write(closeParenBytes)
  185. w.Write(spaceBytes)
  186. return false
  187. }
  188. w.Write([]byte(iface.Error()))
  189. return true
  190. case fmt.Stringer:
  191. defer catchPanic(w, v)
  192. if cs.ContinueOnMethod {
  193. w.Write(openParenBytes)
  194. w.Write([]byte(iface.String()))
  195. w.Write(closeParenBytes)
  196. w.Write(spaceBytes)
  197. return false
  198. }
  199. w.Write([]byte(iface.String()))
  200. return true
  201. }
  202. return false
  203. }
  204. // printBool outputs a boolean value as true or false to Writer w.
  205. func printBool(w io.Writer, val bool) {
  206. if val {
  207. w.Write(trueBytes)
  208. } else {
  209. w.Write(falseBytes)
  210. }
  211. }
  212. // printInt outputs a signed integer value to Writer w.
  213. func printInt(w io.Writer, val int64, base int) {
  214. w.Write([]byte(strconv.FormatInt(val, base)))
  215. }
  216. // printUint outputs an unsigned integer value to Writer w.
  217. func printUint(w io.Writer, val uint64, base int) {
  218. w.Write([]byte(strconv.FormatUint(val, base)))
  219. }
  220. // printFloat outputs a floating point value using the specified precision,
  221. // which is expected to be 32 or 64bit, to Writer w.
  222. func printFloat(w io.Writer, val float64, precision int) {
  223. w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
  224. }
  225. // printComplex outputs a complex value using the specified float precision
  226. // for the real and imaginary parts to Writer w.
  227. func printComplex(w io.Writer, c complex128, floatPrecision int) {
  228. r := real(c)
  229. w.Write(openParenBytes)
  230. w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
  231. i := imag(c)
  232. if i >= 0 {
  233. w.Write(plusBytes)
  234. }
  235. w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
  236. w.Write(iBytes)
  237. w.Write(closeParenBytes)
  238. }
  239. // printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
  240. // prefix to Writer w.
  241. func printHexPtr(w io.Writer, p uintptr) {
  242. // Null pointer.
  243. num := uint64(p)
  244. if num == 0 {
  245. w.Write(nilAngleBytes)
  246. return
  247. }
  248. // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
  249. buf := make([]byte, 18)
  250. // It's simpler to construct the hex string right to left.
  251. base := uint64(16)
  252. i := len(buf) - 1
  253. for num >= base {
  254. buf[i] = hexDigits[num%base]
  255. num /= base
  256. i--
  257. }
  258. buf[i] = hexDigits[num]
  259. // Add '0x' prefix.
  260. i--
  261. buf[i] = 'x'
  262. i--
  263. buf[i] = '0'
  264. // Strip unused leading bytes.
  265. buf = buf[i:]
  266. w.Write(buf)
  267. }
  268. // valuesSorter implements sort.Interface to allow a slice of reflect.Value
  269. // elements to be sorted.
  270. type valuesSorter struct {
  271. values []reflect.Value
  272. }
  273. // Len returns the number of values in the slice. It is part of the
  274. // sort.Interface implementation.
  275. func (s *valuesSorter) Len() int {
  276. return len(s.values)
  277. }
  278. // Swap swaps the values at the passed indices. It is part of the
  279. // sort.Interface implementation.
  280. func (s *valuesSorter) Swap(i, j int) {
  281. s.values[i], s.values[j] = s.values[j], s.values[i]
  282. }
  283. // Less returns whether the value at index i should sort before the
  284. // value at index j. It is part of the sort.Interface implementation.
  285. func (s *valuesSorter) Less(i, j int) bool {
  286. switch s.values[i].Kind() {
  287. case reflect.Bool:
  288. return !s.values[i].Bool() && s.values[j].Bool()
  289. case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
  290. return s.values[i].Int() < s.values[j].Int()
  291. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  292. return s.values[i].Uint() < s.values[j].Uint()
  293. case reflect.Float32, reflect.Float64:
  294. return s.values[i].Float() < s.values[j].Float()
  295. case reflect.String:
  296. return s.values[i].String() < s.values[j].String()
  297. case reflect.Uintptr:
  298. return s.values[i].Uint() < s.values[j].Uint()
  299. }
  300. return s.values[i].String() < s.values[j].String()
  301. }
  302. // sortValues is a generic sort function for native types: int, uint, bool,
  303. // string and uintptr. Other inputs are sorted according to their
  304. // Value.String() value to ensure display stability.
  305. func sortValues(values []reflect.Value) {
  306. if len(values) == 0 {
  307. return
  308. }
  309. sort.Sort(&valuesSorter{values})
  310. }