OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / davecgh / go-spew / spew / common.go
1 /*
2  * Copyright (c) 2013-2016 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
17 package spew
18
19 import (
20         "bytes"
21         "fmt"
22         "io"
23         "reflect"
24         "sort"
25         "strconv"
26 )
27
28 // Some constants in the form of bytes to avoid string overhead.  This mirrors
29 // the technique used in the fmt package.
30 var (
31         panicBytes            = []byte("(PANIC=")
32         plusBytes             = []byte("+")
33         iBytes                = []byte("i")
34         trueBytes             = []byte("true")
35         falseBytes            = []byte("false")
36         interfaceBytes        = []byte("(interface {})")
37         commaNewlineBytes     = []byte(",\n")
38         newlineBytes          = []byte("\n")
39         openBraceBytes        = []byte("{")
40         openBraceNewlineBytes = []byte("{\n")
41         closeBraceBytes       = []byte("}")
42         asteriskBytes         = []byte("*")
43         colonBytes            = []byte(":")
44         colonSpaceBytes       = []byte(": ")
45         openParenBytes        = []byte("(")
46         closeParenBytes       = []byte(")")
47         spaceBytes            = []byte(" ")
48         pointerChainBytes     = []byte("->")
49         nilAngleBytes         = []byte("<nil>")
50         maxNewlineBytes       = []byte("<max depth reached>\n")
51         maxShortBytes         = []byte("<max>")
52         circularBytes         = []byte("<already shown>")
53         circularShortBytes    = []byte("<shown>")
54         invalidAngleBytes     = []byte("<invalid>")
55         openBracketBytes      = []byte("[")
56         closeBracketBytes     = []byte("]")
57         percentBytes          = []byte("%")
58         precisionBytes        = []byte(".")
59         openAngleBytes        = []byte("<")
60         closeAngleBytes       = []byte(">")
61         openMapBytes          = []byte("map[")
62         closeMapBytes         = []byte("]")
63         lenEqualsBytes        = []byte("len=")
64         capEqualsBytes        = []byte("cap=")
65 )
66
67 // hexDigits is used to map a decimal value to a hex digit.
68 var hexDigits = "0123456789abcdef"
69
70 // catchPanic handles any panics that might occur during the handleMethods
71 // calls.
72 func catchPanic(w io.Writer, v reflect.Value) {
73         if err := recover(); err != nil {
74                 w.Write(panicBytes)
75                 fmt.Fprintf(w, "%v", err)
76                 w.Write(closeParenBytes)
77         }
78 }
79
80 // handleMethods attempts to call the Error and String methods on the underlying
81 // type the passed reflect.Value represents and outputes the result to Writer w.
82 //
83 // It handles panics in any called methods by catching and displaying the error
84 // as the formatted value.
85 func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
86         // We need an interface to check if the type implements the error or
87         // Stringer interface.  However, the reflect package won't give us an
88         // interface on certain things like unexported struct fields in order
89         // to enforce visibility rules.  We use unsafe, when it's available,
90         // to bypass these restrictions since this package does not mutate the
91         // values.
92         if !v.CanInterface() {
93                 if UnsafeDisabled {
94                         return false
95                 }
96
97                 v = unsafeReflectValue(v)
98         }
99
100         // Choose whether or not to do error and Stringer interface lookups against
101         // the base type or a pointer to the base type depending on settings.
102         // Technically calling one of these methods with a pointer receiver can
103         // mutate the value, however, types which choose to satisify an error or
104         // Stringer interface with a pointer receiver should not be mutating their
105         // state inside these interface methods.
106         if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
107                 v = unsafeReflectValue(v)
108         }
109         if v.CanAddr() {
110                 v = v.Addr()
111         }
112
113         // Is it an error or Stringer?
114         switch iface := v.Interface().(type) {
115         case error:
116                 defer catchPanic(w, v)
117                 if cs.ContinueOnMethod {
118                         w.Write(openParenBytes)
119                         w.Write([]byte(iface.Error()))
120                         w.Write(closeParenBytes)
121                         w.Write(spaceBytes)
122                         return false
123                 }
124
125                 w.Write([]byte(iface.Error()))
126                 return true
127
128         case fmt.Stringer:
129                 defer catchPanic(w, v)
130                 if cs.ContinueOnMethod {
131                         w.Write(openParenBytes)
132                         w.Write([]byte(iface.String()))
133                         w.Write(closeParenBytes)
134                         w.Write(spaceBytes)
135                         return false
136                 }
137                 w.Write([]byte(iface.String()))
138                 return true
139         }
140         return false
141 }
142
143 // printBool outputs a boolean value as true or false to Writer w.
144 func printBool(w io.Writer, val bool) {
145         if val {
146                 w.Write(trueBytes)
147         } else {
148                 w.Write(falseBytes)
149         }
150 }
151
152 // printInt outputs a signed integer value to Writer w.
153 func printInt(w io.Writer, val int64, base int) {
154         w.Write([]byte(strconv.FormatInt(val, base)))
155 }
156
157 // printUint outputs an unsigned integer value to Writer w.
158 func printUint(w io.Writer, val uint64, base int) {
159         w.Write([]byte(strconv.FormatUint(val, base)))
160 }
161
162 // printFloat outputs a floating point value using the specified precision,
163 // which is expected to be 32 or 64bit, to Writer w.
164 func printFloat(w io.Writer, val float64, precision int) {
165         w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
166 }
167
168 // printComplex outputs a complex value using the specified float precision
169 // for the real and imaginary parts to Writer w.
170 func printComplex(w io.Writer, c complex128, floatPrecision int) {
171         r := real(c)
172         w.Write(openParenBytes)
173         w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
174         i := imag(c)
175         if i >= 0 {
176                 w.Write(plusBytes)
177         }
178         w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
179         w.Write(iBytes)
180         w.Write(closeParenBytes)
181 }
182
183 // printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
184 // prefix to Writer w.
185 func printHexPtr(w io.Writer, p uintptr) {
186         // Null pointer.
187         num := uint64(p)
188         if num == 0 {
189                 w.Write(nilAngleBytes)
190                 return
191         }
192
193         // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
194         buf := make([]byte, 18)
195
196         // It's simpler to construct the hex string right to left.
197         base := uint64(16)
198         i := len(buf) - 1
199         for num >= base {
200                 buf[i] = hexDigits[num%base]
201                 num /= base
202                 i--
203         }
204         buf[i] = hexDigits[num]
205
206         // Add '0x' prefix.
207         i--
208         buf[i] = 'x'
209         i--
210         buf[i] = '0'
211
212         // Strip unused leading bytes.
213         buf = buf[i:]
214         w.Write(buf)
215 }
216
217 // valuesSorter implements sort.Interface to allow a slice of reflect.Value
218 // elements to be sorted.
219 type valuesSorter struct {
220         values  []reflect.Value
221         strings []string // either nil or same len and values
222         cs      *ConfigState
223 }
224
225 // newValuesSorter initializes a valuesSorter instance, which holds a set of
226 // surrogate keys on which the data should be sorted.  It uses flags in
227 // ConfigState to decide if and how to populate those surrogate keys.
228 func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
229         vs := &valuesSorter{values: values, cs: cs}
230         if canSortSimply(vs.values[0].Kind()) {
231                 return vs
232         }
233         if !cs.DisableMethods {
234                 vs.strings = make([]string, len(values))
235                 for i := range vs.values {
236                         b := bytes.Buffer{}
237                         if !handleMethods(cs, &b, vs.values[i]) {
238                                 vs.strings = nil
239                                 break
240                         }
241                         vs.strings[i] = b.String()
242                 }
243         }
244         if vs.strings == nil && cs.SpewKeys {
245                 vs.strings = make([]string, len(values))
246                 for i := range vs.values {
247                         vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
248                 }
249         }
250         return vs
251 }
252
253 // canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
254 // directly, or whether it should be considered for sorting by surrogate keys
255 // (if the ConfigState allows it).
256 func canSortSimply(kind reflect.Kind) bool {
257         // This switch parallels valueSortLess, except for the default case.
258         switch kind {
259         case reflect.Bool:
260                 return true
261         case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
262                 return true
263         case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
264                 return true
265         case reflect.Float32, reflect.Float64:
266                 return true
267         case reflect.String:
268                 return true
269         case reflect.Uintptr:
270                 return true
271         case reflect.Array:
272                 return true
273         }
274         return false
275 }
276
277 // Len returns the number of values in the slice.  It is part of the
278 // sort.Interface implementation.
279 func (s *valuesSorter) Len() int {
280         return len(s.values)
281 }
282
283 // Swap swaps the values at the passed indices.  It is part of the
284 // sort.Interface implementation.
285 func (s *valuesSorter) Swap(i, j int) {
286         s.values[i], s.values[j] = s.values[j], s.values[i]
287         if s.strings != nil {
288                 s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
289         }
290 }
291
292 // valueSortLess returns whether the first value should sort before the second
293 // value.  It is used by valueSorter.Less as part of the sort.Interface
294 // implementation.
295 func valueSortLess(a, b reflect.Value) bool {
296         switch a.Kind() {
297         case reflect.Bool:
298                 return !a.Bool() && b.Bool()
299         case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
300                 return a.Int() < b.Int()
301         case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
302                 return a.Uint() < b.Uint()
303         case reflect.Float32, reflect.Float64:
304                 return a.Float() < b.Float()
305         case reflect.String:
306                 return a.String() < b.String()
307         case reflect.Uintptr:
308                 return a.Uint() < b.Uint()
309         case reflect.Array:
310                 // Compare the contents of both arrays.
311                 l := a.Len()
312                 for i := 0; i < l; i++ {
313                         av := a.Index(i)
314                         bv := b.Index(i)
315                         if av.Interface() == bv.Interface() {
316                                 continue
317                         }
318                         return valueSortLess(av, bv)
319                 }
320         }
321         return a.String() < b.String()
322 }
323
324 // Less returns whether the value at index i should sort before the
325 // value at index j.  It is part of the sort.Interface implementation.
326 func (s *valuesSorter) Less(i, j int) bool {
327         if s.strings == nil {
328                 return valueSortLess(s.values[i], s.values[j])
329         }
330         return s.strings[i] < s.strings[j]
331 }
332
333 // sortValues is a sort function that handles both native types and any type that
334 // can be converted to error or Stringer.  Other inputs are sorted according to
335 // their Value.String() value to ensure display stability.
336 func sortValues(values []reflect.Value, cs *ConfigState) {
337         if len(values) == 0 {
338                 return
339         }
340         sort.Sort(newValuesSorter(values, cs))
341 }