OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / stretchr / testify / vendor / github.com / davecgh / go-spew / spew / format.go
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
17 package spew
18
19 import (
20         "bytes"
21         "fmt"
22         "reflect"
23         "strconv"
24         "strings"
25 )
26
27 // supportedFlags is a list of all the character flags supported by fmt package.
28 const supportedFlags = "0-+# "
29
30 // formatState implements the fmt.Formatter interface and contains information
31 // about the state of a formatting operation.  The NewFormatter function can
32 // be used to get a new Formatter which can be used directly as arguments
33 // in standard fmt package printing calls.
34 type formatState struct {
35         value          interface{}
36         fs             fmt.State
37         depth          int
38         pointers       map[uintptr]int
39         ignoreNextType bool
40         cs             *ConfigState
41 }
42
43 // buildDefaultFormat recreates the original format string without precision
44 // and width information to pass in to fmt.Sprintf in the case of an
45 // unrecognized type.  Unless new types are added to the language, this
46 // function won't ever be called.
47 func (f *formatState) buildDefaultFormat() (format string) {
48         buf := bytes.NewBuffer(percentBytes)
49
50         for _, flag := range supportedFlags {
51                 if f.fs.Flag(int(flag)) {
52                         buf.WriteRune(flag)
53                 }
54         }
55
56         buf.WriteRune('v')
57
58         format = buf.String()
59         return format
60 }
61
62 // constructOrigFormat recreates the original format string including precision
63 // and width information to pass along to the standard fmt package.  This allows
64 // automatic deferral of all format strings this package doesn't support.
65 func (f *formatState) constructOrigFormat(verb rune) (format string) {
66         buf := bytes.NewBuffer(percentBytes)
67
68         for _, flag := range supportedFlags {
69                 if f.fs.Flag(int(flag)) {
70                         buf.WriteRune(flag)
71                 }
72         }
73
74         if width, ok := f.fs.Width(); ok {
75                 buf.WriteString(strconv.Itoa(width))
76         }
77
78         if precision, ok := f.fs.Precision(); ok {
79                 buf.Write(precisionBytes)
80                 buf.WriteString(strconv.Itoa(precision))
81         }
82
83         buf.WriteRune(verb)
84
85         format = buf.String()
86         return format
87 }
88
89 // unpackValue returns values inside of non-nil interfaces when possible and
90 // ensures that types for values which have been unpacked from an interface
91 // are displayed when the show types flag is also set.
92 // This is useful for data types like structs, arrays, slices, and maps which
93 // can contain varying types packed inside an interface.
94 func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
95         if v.Kind() == reflect.Interface {
96                 f.ignoreNextType = false
97                 if !v.IsNil() {
98                         v = v.Elem()
99                 }
100         }
101         return v
102 }
103
104 // formatPtr handles formatting of pointers by indirecting them as necessary.
105 func (f *formatState) formatPtr(v reflect.Value) {
106         // Display nil if top level pointer is nil.
107         showTypes := f.fs.Flag('#')
108         if v.IsNil() && (!showTypes || f.ignoreNextType) {
109                 f.fs.Write(nilAngleBytes)
110                 return
111         }
112
113         // Remove pointers at or below the current depth from map used to detect
114         // circular refs.
115         for k, depth := range f.pointers {
116                 if depth >= f.depth {
117                         delete(f.pointers, k)
118                 }
119         }
120
121         // Keep list of all dereferenced pointers to possibly show later.
122         pointerChain := make([]uintptr, 0)
123
124         // Figure out how many levels of indirection there are by derferencing
125         // pointers and unpacking interfaces down the chain while detecting circular
126         // references.
127         nilFound := false
128         cycleFound := false
129         indirects := 0
130         ve := v
131         for ve.Kind() == reflect.Ptr {
132                 if ve.IsNil() {
133                         nilFound = true
134                         break
135                 }
136                 indirects++
137                 addr := ve.Pointer()
138                 pointerChain = append(pointerChain, addr)
139                 if pd, ok := f.pointers[addr]; ok && pd < f.depth {
140                         cycleFound = true
141                         indirects--
142                         break
143                 }
144                 f.pointers[addr] = f.depth
145
146                 ve = ve.Elem()
147                 if ve.Kind() == reflect.Interface {
148                         if ve.IsNil() {
149                                 nilFound = true
150                                 break
151                         }
152                         ve = ve.Elem()
153                 }
154         }
155
156         // Display type or indirection level depending on flags.
157         if showTypes && !f.ignoreNextType {
158                 f.fs.Write(openParenBytes)
159                 f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
160                 f.fs.Write([]byte(ve.Type().String()))
161                 f.fs.Write(closeParenBytes)
162         } else {
163                 if nilFound || cycleFound {
164                         indirects += strings.Count(ve.Type().String(), "*")
165                 }
166                 f.fs.Write(openAngleBytes)
167                 f.fs.Write([]byte(strings.Repeat("*", indirects)))
168                 f.fs.Write(closeAngleBytes)
169         }
170
171         // Display pointer information depending on flags.
172         if f.fs.Flag('+') && (len(pointerChain) > 0) {
173                 f.fs.Write(openParenBytes)
174                 for i, addr := range pointerChain {
175                         if i > 0 {
176                                 f.fs.Write(pointerChainBytes)
177                         }
178                         printHexPtr(f.fs, addr)
179                 }
180                 f.fs.Write(closeParenBytes)
181         }
182
183         // Display dereferenced value.
184         switch {
185         case nilFound == true:
186                 f.fs.Write(nilAngleBytes)
187
188         case cycleFound == true:
189                 f.fs.Write(circularShortBytes)
190
191         default:
192                 f.ignoreNextType = true
193                 f.format(ve)
194         }
195 }
196
197 // format is the main workhorse for providing the Formatter interface.  It
198 // uses the passed reflect value to figure out what kind of object we are
199 // dealing with and formats it appropriately.  It is a recursive function,
200 // however circular data structures are detected and handled properly.
201 func (f *formatState) format(v reflect.Value) {
202         // Handle invalid reflect values immediately.
203         kind := v.Kind()
204         if kind == reflect.Invalid {
205                 f.fs.Write(invalidAngleBytes)
206                 return
207         }
208
209         // Handle pointers specially.
210         if kind == reflect.Ptr {
211                 f.formatPtr(v)
212                 return
213         }
214
215         // Print type information unless already handled elsewhere.
216         if !f.ignoreNextType && f.fs.Flag('#') {
217                 f.fs.Write(openParenBytes)
218                 f.fs.Write([]byte(v.Type().String()))
219                 f.fs.Write(closeParenBytes)
220         }
221         f.ignoreNextType = false
222
223         // Call Stringer/error interfaces if they exist and the handle methods
224         // flag is enabled.
225         if !f.cs.DisableMethods {
226                 if (kind != reflect.Invalid) && (kind != reflect.Interface) {
227                         if handled := handleMethods(f.cs, f.fs, v); handled {
228                                 return
229                         }
230                 }
231         }
232
233         switch kind {
234         case reflect.Invalid:
235                 // Do nothing.  We should never get here since invalid has already
236                 // been handled above.
237
238         case reflect.Bool:
239                 printBool(f.fs, v.Bool())
240
241         case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
242                 printInt(f.fs, v.Int(), 10)
243
244         case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
245                 printUint(f.fs, v.Uint(), 10)
246
247         case reflect.Float32:
248                 printFloat(f.fs, v.Float(), 32)
249
250         case reflect.Float64:
251                 printFloat(f.fs, v.Float(), 64)
252
253         case reflect.Complex64:
254                 printComplex(f.fs, v.Complex(), 32)
255
256         case reflect.Complex128:
257                 printComplex(f.fs, v.Complex(), 64)
258
259         case reflect.Slice:
260                 if v.IsNil() {
261                         f.fs.Write(nilAngleBytes)
262                         break
263                 }
264                 fallthrough
265
266         case reflect.Array:
267                 f.fs.Write(openBracketBytes)
268                 f.depth++
269                 if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
270                         f.fs.Write(maxShortBytes)
271                 } else {
272                         numEntries := v.Len()
273                         for i := 0; i < numEntries; i++ {
274                                 if i > 0 {
275                                         f.fs.Write(spaceBytes)
276                                 }
277                                 f.ignoreNextType = true
278                                 f.format(f.unpackValue(v.Index(i)))
279                         }
280                 }
281                 f.depth--
282                 f.fs.Write(closeBracketBytes)
283
284         case reflect.String:
285                 f.fs.Write([]byte(v.String()))
286
287         case reflect.Interface:
288                 // The only time we should get here is for nil interfaces due to
289                 // unpackValue calls.
290                 if v.IsNil() {
291                         f.fs.Write(nilAngleBytes)
292                 }
293
294         case reflect.Ptr:
295                 // Do nothing.  We should never get here since pointers have already
296                 // been handled above.
297
298         case reflect.Map:
299                 // nil maps should be indicated as different than empty maps
300                 if v.IsNil() {
301                         f.fs.Write(nilAngleBytes)
302                         break
303                 }
304
305                 f.fs.Write(openMapBytes)
306                 f.depth++
307                 if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
308                         f.fs.Write(maxShortBytes)
309                 } else {
310                         keys := v.MapKeys()
311                         if f.cs.SortKeys {
312                                 sortValues(keys, f.cs)
313                         }
314                         for i, key := range keys {
315                                 if i > 0 {
316                                         f.fs.Write(spaceBytes)
317                                 }
318                                 f.ignoreNextType = true
319                                 f.format(f.unpackValue(key))
320                                 f.fs.Write(colonBytes)
321                                 f.ignoreNextType = true
322                                 f.format(f.unpackValue(v.MapIndex(key)))
323                         }
324                 }
325                 f.depth--
326                 f.fs.Write(closeMapBytes)
327
328         case reflect.Struct:
329                 numFields := v.NumField()
330                 f.fs.Write(openBraceBytes)
331                 f.depth++
332                 if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
333                         f.fs.Write(maxShortBytes)
334                 } else {
335                         vt := v.Type()
336                         for i := 0; i < numFields; i++ {
337                                 if i > 0 {
338                                         f.fs.Write(spaceBytes)
339                                 }
340                                 vtf := vt.Field(i)
341                                 if f.fs.Flag('+') || f.fs.Flag('#') {
342                                         f.fs.Write([]byte(vtf.Name))
343                                         f.fs.Write(colonBytes)
344                                 }
345                                 f.format(f.unpackValue(v.Field(i)))
346                         }
347                 }
348                 f.depth--
349                 f.fs.Write(closeBraceBytes)
350
351         case reflect.Uintptr:
352                 printHexPtr(f.fs, uintptr(v.Uint()))
353
354         case reflect.UnsafePointer, reflect.Chan, reflect.Func:
355                 printHexPtr(f.fs, v.Pointer())
356
357         // There were not any other types at the time this code was written, but
358         // fall back to letting the default fmt package handle it if any get added.
359         default:
360                 format := f.buildDefaultFormat()
361                 if v.CanInterface() {
362                         fmt.Fprintf(f.fs, format, v.Interface())
363                 } else {
364                         fmt.Fprintf(f.fs, format, v.String())
365                 }
366         }
367 }
368
369 // Format satisfies the fmt.Formatter interface. See NewFormatter for usage
370 // details.
371 func (f *formatState) Format(fs fmt.State, verb rune) {
372         f.fs = fs
373
374         // Use standard formatting for verbs that are not v.
375         if verb != 'v' {
376                 format := f.constructOrigFormat(verb)
377                 fmt.Fprintf(fs, format, f.value)
378                 return
379         }
380
381         if f.value == nil {
382                 if fs.Flag('#') {
383                         fs.Write(interfaceBytes)
384                 }
385                 fs.Write(nilAngleBytes)
386                 return
387         }
388
389         f.format(reflect.ValueOf(f.value))
390 }
391
392 // newFormatter is a helper function to consolidate the logic from the various
393 // public methods which take varying config states.
394 func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
395         fs := &formatState{value: v, cs: cs}
396         fs.pointers = make(map[uintptr]int)
397         return fs
398 }
399
400 /*
401 NewFormatter returns a custom formatter that satisfies the fmt.Formatter
402 interface.  As a result, it integrates cleanly with standard fmt package
403 printing functions.  The formatter is useful for inline printing of smaller data
404 types similar to the standard %v format specifier.
405
406 The custom formatter only responds to the %v (most compact), %+v (adds pointer
407 addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
408 combinations.  Any other verbs such as %x and %q will be sent to the the
409 standard fmt package for formatting.  In addition, the custom formatter ignores
410 the width and precision arguments (however they will still work on the format
411 specifiers not handled by the custom formatter).
412
413 Typically this function shouldn't be called directly.  It is much easier to make
414 use of the custom formatter by calling one of the convenience functions such as
415 Printf, Println, or Fprintf.
416 */
417 func NewFormatter(v interface{}) fmt.Formatter {
418         return newFormatter(&Config, v)
419 }