Browse Source

Add config pointers to format and dump states.

This paves the way to support individual configuration options through a
separate type while still providing the simple global config and package
level methods.
Dave Collins 13 years ago
parent
commit
184d118062
3 changed files with 19 additions and 17 deletions
  1. 2 2
      spew/common.go
  2. 9 8
      spew/dump.go
  3. 8 7
      spew/format.go

+ 2 - 2
spew/common.go

@@ -125,7 +125,7 @@ func catchPanic(w io.Writer, v reflect.Value) {
 //
 //
 // It handles panics in any called methods by catching and displaying the error
 // It handles panics in any called methods by catching and displaying the error
 // as the formatted value.
 // as the formatted value.
-func handleMethods(w io.Writer, v reflect.Value) (handled bool) {
+func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
 	// We need an interface to check if the type implements the error or
 	// We need an interface to check if the type implements the error or
 	// Stringer interface.  However, the reflect package won't give us an
 	// Stringer interface.  However, the reflect package won't give us an
 	// an interface on certain things like unexported struct fields in order
 	// an interface on certain things like unexported struct fields in order
@@ -142,7 +142,7 @@ func handleMethods(w io.Writer, v reflect.Value) (handled bool) {
 	// Stringer interface with a pointer receiver should not be mutating their
 	// Stringer interface with a pointer receiver should not be mutating their
 	// state inside these interface methods.
 	// state inside these interface methods.
 	var viface interface{}
 	var viface interface{}
-	if !Config.DisablePointerMethods {
+	if !cs.DisablePointerMethods {
 		if !v.CanAddr() {
 		if !v.CanAddr() {
 			v = unsafeReflectValue(v)
 			v = unsafeReflectValue(v)
 		}
 		}

+ 9 - 8
spew/dump.go

@@ -32,16 +32,17 @@ type dumpState struct {
 	pointers       map[uintptr]int
 	pointers       map[uintptr]int
 	ignoreNextType bool
 	ignoreNextType bool
 	ignoreNextPad  bool
 	ignoreNextPad  bool
+	cs             *ConfigState
 }
 }
 
 
-// pad performs indentation according to the depth level and Config.Indent
+// pad performs indentation according to the depth level and cs.Indent
 // option.
 // option.
 func (d *dumpState) pad() {
 func (d *dumpState) pad() {
 	if d.ignoreNextPad {
 	if d.ignoreNextPad {
 		d.ignoreNextPad = false
 		d.ignoreNextPad = false
 		return
 		return
 	}
 	}
-	d.w.Write(bytes.Repeat([]byte(Config.Indent), d.depth))
+	d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
 }
 }
 
 
 // dumpPtr handles formatting of pointers by indirecting them as necessary.
 // dumpPtr handles formatting of pointers by indirecting them as necessary.
@@ -146,9 +147,9 @@ func (d *dumpState) dump(v reflect.Value) {
 
 
 	// Call error/Stringer interfaces if they exist and the handle methods flag
 	// Call error/Stringer interfaces if they exist and the handle methods flag
 	// is enabled
 	// is enabled
-	if !Config.DisableMethods {
+	if !d.cs.DisableMethods {
 		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
 		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
-			if handled := handleMethods(d.w, v); handled {
+			if handled := handleMethods(d.cs, d.w, v); handled {
 				return
 				return
 			}
 			}
 		}
 		}
@@ -182,7 +183,7 @@ func (d *dumpState) dump(v reflect.Value) {
 	case reflect.Array, reflect.Slice:
 	case reflect.Array, reflect.Slice:
 		d.w.Write(openBraceNewlineBytes)
 		d.w.Write(openBraceNewlineBytes)
 		d.depth++
 		d.depth++
-		if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
 			d.pad()
 			d.pad()
 			d.w.Write(maxNewlineBytes)
 			d.w.Write(maxNewlineBytes)
 		} else {
 		} else {
@@ -213,7 +214,7 @@ func (d *dumpState) dump(v reflect.Value) {
 	case reflect.Map:
 	case reflect.Map:
 		d.w.Write(openBraceNewlineBytes)
 		d.w.Write(openBraceNewlineBytes)
 		d.depth++
 		d.depth++
-		if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
 			d.pad()
 			d.pad()
 			d.w.Write(maxNewlineBytes)
 			d.w.Write(maxNewlineBytes)
 		} else {
 		} else {
@@ -238,7 +239,7 @@ func (d *dumpState) dump(v reflect.Value) {
 	case reflect.Struct:
 	case reflect.Struct:
 		d.w.Write(openBraceNewlineBytes)
 		d.w.Write(openBraceNewlineBytes)
 		d.depth++
 		d.depth++
-		if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
 			d.pad()
 			d.pad()
 			d.w.Write(maxNewlineBytes)
 			d.w.Write(maxNewlineBytes)
 		} else {
 		} else {
@@ -291,7 +292,7 @@ func Fdump(w io.Writer, a ...interface{}) {
 			continue
 			continue
 		}
 		}
 
 
-		d := dumpState{w: w}
+		d := dumpState{w: w, cs: &Config}
 		d.pointers = make(map[uintptr]int)
 		d.pointers = make(map[uintptr]int)
 		d.dump(reflect.ValueOf(arg))
 		d.dump(reflect.ValueOf(arg))
 		d.w.Write(newlineBytes)
 		d.w.Write(newlineBytes)

+ 8 - 7
spew/format.go

@@ -37,6 +37,7 @@ type formatState struct {
 	depth    int
 	depth    int
 	pointers map[uintptr]int // Holds map of points and depth they were seen at
 	pointers map[uintptr]int // Holds map of points and depth they were seen at
 	fs       fmt.State
 	fs       fmt.State
+	cs       *ConfigState
 }
 }
 
 
 // buildDefaultFormat recreates the original format string without precision
 // buildDefaultFormat recreates the original format string without precision
@@ -175,9 +176,9 @@ func (f *formatState) format(v reflect.Value) {
 	// Call error/Stringer interfaces if they exist and the handle methods
 	// Call error/Stringer interfaces if they exist and the handle methods
 	// flag is enabled.
 	// flag is enabled.
 	kind := v.Kind()
 	kind := v.Kind()
-	if !Config.DisableMethods {
+	if !f.cs.DisableMethods {
 		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
 		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
-			if handled := handleMethods(&f.buffer, v); handled {
+			if handled := handleMethods(f.cs, &f.buffer, v); handled {
 				return
 				return
 			}
 			}
 		}
 		}
@@ -211,7 +212,7 @@ func (f *formatState) format(v reflect.Value) {
 	case reflect.Array, reflect.Slice:
 	case reflect.Array, reflect.Slice:
 		f.buffer.WriteRune('[')
 		f.buffer.WriteRune('[')
 		f.depth++
 		f.depth++
-		if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
 			f.buffer.Write(maxShortBytes)
 			f.buffer.Write(maxShortBytes)
 		} else {
 		} else {
 			numEntries := v.Len()
 			numEntries := v.Len()
@@ -234,7 +235,7 @@ func (f *formatState) format(v reflect.Value) {
 	case reflect.Map:
 	case reflect.Map:
 		f.buffer.Write(openMapBytes)
 		f.buffer.Write(openMapBytes)
 		f.depth++
 		f.depth++
-		if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
 			f.buffer.Write(maxShortBytes)
 			f.buffer.Write(maxShortBytes)
 		} else {
 		} else {
 			keys := v.MapKeys()
 			keys := v.MapKeys()
@@ -257,7 +258,7 @@ func (f *formatState) format(v reflect.Value) {
 		numFields := v.NumField()
 		numFields := v.NumField()
 		f.buffer.WriteRune('{')
 		f.buffer.WriteRune('{')
 		f.depth++
 		f.depth++
-		if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
 			f.buffer.Write(maxShortBytes)
 			f.buffer.Write(maxShortBytes)
 		} else {
 		} else {
 			vt := v.Type()
 			vt := v.Type()
@@ -331,8 +332,8 @@ Typically this function shouldn't be called directly.  It is much easier to make
 use of the custom formatter by calling one of the convenience functions such as
 use of the custom formatter by calling one of the convenience functions such as
 Printf, Println, or Printf.
 Printf, Println, or Printf.
 */
 */
-func NewFormatter(v interface{}) (f fmt.Formatter) {
-	fs := &formatState{value: v}
+func NewFormatter(v interface{}) fmt.Formatter {
+	fs := &formatState{value: v, cs: &Config}
 	fs.pointers = make(map[uintptr]int)
 	fs.pointers = make(map[uintptr]int)
 	return fs
 	return fs
 }
 }