Browse Source

vendor: update ugorji to v1.1.2

Sophos 6 years ago
parent
commit
1adc288223
37 changed files with 4115 additions and 2125 deletions
  1. 2 2
      go.mod
  2. 6 4
      go.sum
  3. 108 0
      vendor/github.com/dustin/go-humanize/comma.go
  4. 40 0
      vendor/github.com/dustin/go-humanize/commaf.go
  5. 23 0
      vendor/github.com/dustin/go-humanize/ftoa.go
  6. 8 0
      vendor/github.com/dustin/go-humanize/humanize.go
  7. 192 0
      vendor/github.com/dustin/go-humanize/number.go
  8. 25 0
      vendor/github.com/dustin/go-humanize/ordinals.go
  9. 113 0
      vendor/github.com/dustin/go-humanize/si.go
  10. 117 0
      vendor/github.com/dustin/go-humanize/times.go
  11. 1 38
      vendor/github.com/ugorji/go/codec/0doc.go
  12. 0 0
      vendor/github.com/ugorji/go/codec/LICENSE
  13. 65 29
      vendor/github.com/ugorji/go/codec/binc.go
  14. 47 34
      vendor/github.com/ugorji/go/codec/cbor.go
  15. 13 0
      vendor/github.com/ugorji/go/codec/codecgen.go
  16. 532 365
      vendor/github.com/ugorji/go/codec/decode.go
  17. 482 162
      vendor/github.com/ugorji/go/codec/encode.go
  18. 162 156
      vendor/github.com/ugorji/go/codec/fast-path.generated.go
  19. 1 1
      vendor/github.com/ugorji/go/codec/fast-path.not.go
  20. 24 8
      vendor/github.com/ugorji/go/codec/gen-helper.generated.go
  21. 2 2
      vendor/github.com/ugorji/go/codec/gen.generated.go
  22. 25 15
      vendor/github.com/ugorji/go/codec/gen.go
  23. 464 318
      vendor/github.com/ugorji/go/codec/helper.go
  24. 63 9
      vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
  25. 122 21
      vendor/github.com/ugorji/go/codec/helper_unsafe.go
  26. 151 66
      vendor/github.com/ugorji/go/codec/json.go
  27. 91 60
      vendor/github.com/ugorji/go/codec/msgpack.go
  28. 26 33
      vendor/github.com/ugorji/go/codec/rpc.go
  29. 29 14
      vendor/github.com/ugorji/go/codec/simple.go
  30. 63 65
      vendor/github.com/urfave/cli/app.go
  31. 3 0
      vendor/github.com/urfave/cli/cli.go
  32. 55 30
      vendor/github.com/urfave/cli/command.go
  33. 81 352
      vendor/github.com/urfave/cli/context.go
  34. 31 8
      vendor/github.com/urfave/cli/errors.go
  35. 216 299
      vendor/github.com/urfave/cli/flag.go
  36. 627 0
      vendor/github.com/urfave/cli/flag_generated.go
  37. 105 34
      vendor/github.com/urfave/cli/help.go

+ 2 - 2
go.mod

@@ -42,8 +42,8 @@ require (
 	github.com/spf13/pflag v1.0.1
 	github.com/spf13/pflag v1.0.1
 	github.com/stretchr/testify v1.2.2 // indirect
 	github.com/stretchr/testify v1.2.2 // indirect
 	github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8
 	github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8
-	github.com/ugorji/go v1.1.1
-	github.com/urfave/cli v1.18.0
+	github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43
+	github.com/urfave/cli v1.20.0
 	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2
 	github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2
 	go.etcd.io/bbolt v1.3.2
 	go.etcd.io/bbolt v1.3.2
 	go.uber.org/atomic v1.3.2 // indirect
 	go.uber.org/atomic v1.3.2 // indirect

+ 6 - 4
go.sum

@@ -86,10 +86,12 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/ugorji/go v1.1.1 h1:gmervu+jDMvXTbcHQ0pd2wee85nEoE0BsVyEuzkfK8w=
-github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
-github.com/urfave/cli v1.18.0 h1:m9MfmZWX7bwr9kUcs/Asr95j0IVXzGNNc+/5ku2m26Q=
-github.com/urfave/cli v1.18.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs=
+github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
+github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 h1:BasDe+IErOQKrMVXab7UayvSlIpiyGwRvuX3EKYY7UA=
+github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
+github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
 go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=

+ 108 - 0
vendor/github.com/dustin/go-humanize/comma.go

@@ -0,0 +1,108 @@
+package humanize
+
+import (
+	"bytes"
+	"math"
+	"math/big"
+	"strconv"
+	"strings"
+)
+
+// Comma produces a string form of the given number in base 10 with
+// commas after every three orders of magnitude.
+//
+// e.g. Comma(834142) -> 834,142
+func Comma(v int64) string {
+	sign := ""
+
+	// Min int64 can't be negated to a usable value, so it has to be special cased.
+	if v == math.MinInt64 {
+		return "-9,223,372,036,854,775,808"
+	}
+
+	if v < 0 {
+		sign = "-"
+		v = 0 - v
+	}
+
+	parts := []string{"", "", "", "", "", "", ""}
+	j := len(parts) - 1
+
+	for v > 999 {
+		parts[j] = strconv.FormatInt(v%1000, 10)
+		switch len(parts[j]) {
+		case 2:
+			parts[j] = "0" + parts[j]
+		case 1:
+			parts[j] = "00" + parts[j]
+		}
+		v = v / 1000
+		j--
+	}
+	parts[j] = strconv.Itoa(int(v))
+	return sign + strings.Join(parts[j:], ",")
+}
+
+// Commaf produces a string form of the given number in base 10 with
+// commas after every three orders of magnitude.
+//
+// e.g. Commaf(834142.32) -> 834,142.32
+func Commaf(v float64) string {
+	buf := &bytes.Buffer{}
+	if v < 0 {
+		buf.Write([]byte{'-'})
+		v = 0 - v
+	}
+
+	comma := []byte{','}
+
+	parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
+	pos := 0
+	if len(parts[0])%3 != 0 {
+		pos += len(parts[0]) % 3
+		buf.WriteString(parts[0][:pos])
+		buf.Write(comma)
+	}
+	for ; pos < len(parts[0]); pos += 3 {
+		buf.WriteString(parts[0][pos : pos+3])
+		buf.Write(comma)
+	}
+	buf.Truncate(buf.Len() - 1)
+
+	if len(parts) > 1 {
+		buf.Write([]byte{'.'})
+		buf.WriteString(parts[1])
+	}
+	return buf.String()
+}
+
+// BigComma produces a string form of the given big.Int in base 10
+// with commas after every three orders of magnitude.
+func BigComma(b *big.Int) string {
+	sign := ""
+	if b.Sign() < 0 {
+		sign = "-"
+		b.Abs(b)
+	}
+
+	athousand := big.NewInt(1000)
+	c := (&big.Int{}).Set(b)
+	_, m := oom(c, athousand)
+	parts := make([]string, m+1)
+	j := len(parts) - 1
+
+	mod := &big.Int{}
+	for b.Cmp(athousand) >= 0 {
+		b.DivMod(b, athousand, mod)
+		parts[j] = strconv.FormatInt(mod.Int64(), 10)
+		switch len(parts[j]) {
+		case 2:
+			parts[j] = "0" + parts[j]
+		case 1:
+			parts[j] = "00" + parts[j]
+		}
+		j--
+	}
+	parts[j] = strconv.Itoa(int(b.Int64()))
+	return sign + strings.Join(parts[j:], ",")
+}

+ 40 - 0
vendor/github.com/dustin/go-humanize/commaf.go

@@ -0,0 +1,40 @@
+// +build go1.6
+
+package humanize
+
+import (
+	"bytes"
+	"math/big"
+	"strings"
+)
+
+// BigCommaf produces a string form of the given big.Float in base 10
+// with commas after every three orders of magnitude.
+func BigCommaf(v *big.Float) string {
+	buf := &bytes.Buffer{}
+	if v.Sign() < 0 {
+		buf.Write([]byte{'-'})
+		v.Abs(v)
+	}
+
+	comma := []byte{','}
+
+	parts := strings.Split(v.Text('f', -1), ".")
+	pos := 0
+	if len(parts[0])%3 != 0 {
+		pos += len(parts[0]) % 3
+		buf.WriteString(parts[0][:pos])
+		buf.Write(comma)
+	}
+	for ; pos < len(parts[0]); pos += 3 {
+		buf.WriteString(parts[0][pos : pos+3])
+		buf.Write(comma)
+	}
+	buf.Truncate(buf.Len() - 1)
+
+	if len(parts) > 1 {
+		buf.Write([]byte{'.'})
+		buf.WriteString(parts[1])
+	}
+	return buf.String()
+}

+ 23 - 0
vendor/github.com/dustin/go-humanize/ftoa.go

@@ -0,0 +1,23 @@
+package humanize
+
+import "strconv"
+
+func stripTrailingZeros(s string) string {
+	offset := len(s) - 1
+	for offset > 0 {
+		if s[offset] == '.' {
+			offset--
+			break
+		}
+		if s[offset] != '0' {
+			break
+		}
+		offset--
+	}
+	return s[:offset+1]
+}
+
+// Ftoa converts a float to a string with no trailing zeros.
+func Ftoa(num float64) string {
+	return stripTrailingZeros(strconv.FormatFloat(num, 'f', 6, 64))
+}

+ 8 - 0
vendor/github.com/dustin/go-humanize/humanize.go

@@ -0,0 +1,8 @@
+/*
+Package humanize converts boring ugly numbers to human-friendly strings and back.
+
+Durations can be turned into strings such as "3 days ago", numbers
+representing sizes like 82854982 into useful strings like, "83 MB" or
+"79 MiB" (whichever you prefer).
+*/
+package humanize

+ 192 - 0
vendor/github.com/dustin/go-humanize/number.go

@@ -0,0 +1,192 @@
+package humanize
+
+/*
+Slightly adapted from the source to fit go-humanize.
+
+Author: https://github.com/gorhill
+Source: https://gist.github.com/gorhill/5285193
+
+*/
+
+import (
+	"math"
+	"strconv"
+)
+
+var (
+	renderFloatPrecisionMultipliers = [...]float64{
+		1,
+		10,
+		100,
+		1000,
+		10000,
+		100000,
+		1000000,
+		10000000,
+		100000000,
+		1000000000,
+	}
+
+	renderFloatPrecisionRounders = [...]float64{
+		0.5,
+		0.05,
+		0.005,
+		0.0005,
+		0.00005,
+		0.000005,
+		0.0000005,
+		0.00000005,
+		0.000000005,
+		0.0000000005,
+	}
+)
+
+// FormatFloat produces a formatted number as string based on the following user-specified criteria:
+// * thousands separator
+// * decimal separator
+// * decimal precision
+//
+// Usage: s := RenderFloat(format, n)
+// The format parameter tells how to render the number n.
+//
+// See examples: http://play.golang.org/p/LXc1Ddm1lJ
+//
+// Examples of format strings, given n = 12345.6789:
+// "#,###.##" => "12,345.67"
+// "#,###." => "12,345"
+// "#,###" => "12345,678"
+// "#\u202F###,##" => "12 345,68"
+// "#.###,###### => 12.345,678900
+// "" (aka default format) => 12,345.67
+//
+// The highest precision allowed is 9 digits after the decimal symbol.
+// There is also a version for integer number, FormatInteger(),
+// which is convenient for calls within template.
+func FormatFloat(format string, n float64) string {
+	// Special cases:
+	//   NaN = "NaN"
+	//   +Inf = "+Infinity"
+	//   -Inf = "-Infinity"
+	if math.IsNaN(n) {
+		return "NaN"
+	}
+	if n > math.MaxFloat64 {
+		return "Infinity"
+	}
+	if n < -math.MaxFloat64 {
+		return "-Infinity"
+	}
+
+	// default format
+	precision := 2
+	decimalStr := "."
+	thousandStr := ","
+	positiveStr := ""
+	negativeStr := "-"
+
+	if len(format) > 0 {
+		format := []rune(format)
+
+		// If there is an explicit format directive,
+		// then default values are these:
+		precision = 9
+		thousandStr = ""
+
+		// collect indices of meaningful formatting directives
+		formatIndx := []int{}
+		for i, char := range format {
+			if char != '#' && char != '0' {
+				formatIndx = append(formatIndx, i)
+			}
+		}
+
+		if len(formatIndx) > 0 {
+			// Directive at index 0:
+			//   Must be a '+'
+			//   Raise an error if not the case
+			// index: 0123456789
+			//        +0.000,000
+			//        +000,000.0
+			//        +0000.00
+			//        +0000
+			if formatIndx[0] == 0 {
+				if format[formatIndx[0]] != '+' {
+					panic("RenderFloat(): invalid positive sign directive")
+				}
+				positiveStr = "+"
+				formatIndx = formatIndx[1:]
+			}
+
+			// Two directives:
+			//   First is thousands separator
+			//   Raise an error if not followed by 3-digit
+			// 0123456789
+			// 0.000,000
+			// 000,000.00
+			if len(formatIndx) == 2 {
+				if (formatIndx[1] - formatIndx[0]) != 4 {
+					panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers")
+				}
+				thousandStr = string(format[formatIndx[0]])
+				formatIndx = formatIndx[1:]
+			}
+
+			// One directive:
+			//   Directive is decimal separator
+			//   The number of digit-specifier following the separator indicates wanted precision
+			// 0123456789
+			// 0.00
+			// 000,0000
+			if len(formatIndx) == 1 {
+				decimalStr = string(format[formatIndx[0]])
+				precision = len(format) - formatIndx[0] - 1
+			}
+		}
+	}
+
+	// generate sign part
+	var signStr string
+	if n >= 0.000000001 {
+		signStr = positiveStr
+	} else if n <= -0.000000001 {
+		signStr = negativeStr
+		n = -n
+	} else {
+		signStr = ""
+		n = 0.0
+	}
+
+	// split number into integer and fractional parts
+	intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision])
+
+	// generate integer part string
+	intStr := strconv.FormatInt(int64(intf), 10)
+
+	// add thousand separator if required
+	if len(thousandStr) > 0 {
+		for i := len(intStr); i > 3; {
+			i -= 3
+			intStr = intStr[:i] + thousandStr + intStr[i:]
+		}
+	}
+
+	// no fractional part, we can leave now
+	if precision == 0 {
+		return signStr + intStr
+	}
+
+	// generate fractional part
+	fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision]))
+	// may need padding
+	if len(fracStr) < precision {
+		fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr
+	}
+
+	return signStr + intStr + decimalStr + fracStr
+}
+
+// FormatInteger produces a formatted number as string.
+// See FormatFloat.
+func FormatInteger(format string, n int) string {
+	return FormatFloat(format, float64(n))
+}

+ 25 - 0
vendor/github.com/dustin/go-humanize/ordinals.go

@@ -0,0 +1,25 @@
+package humanize
+
+import "strconv"
+
+// Ordinal gives you the input number in a rank/ordinal format.
+//
+// Ordinal(3) -> 3rd
+func Ordinal(x int) string {
+	suffix := "th"
+	switch x % 10 {
+	case 1:
+		if x%100 != 11 {
+			suffix = "st"
+		}
+	case 2:
+		if x%100 != 12 {
+			suffix = "nd"
+		}
+	case 3:
+		if x%100 != 13 {
+			suffix = "rd"
+		}
+	}
+	return strconv.Itoa(x) + suffix
+}

+ 113 - 0
vendor/github.com/dustin/go-humanize/si.go

@@ -0,0 +1,113 @@
+package humanize
+
+import (
+	"errors"
+	"math"
+	"regexp"
+	"strconv"
+)
+
+var siPrefixTable = map[float64]string{
+	-24: "y", // yocto
+	-21: "z", // zepto
+	-18: "a", // atto
+	-15: "f", // femto
+	-12: "p", // pico
+	-9:  "n", // nano
+	-6:  "µ", // micro
+	-3:  "m", // milli
+	0:   "",
+	3:   "k", // kilo
+	6:   "M", // mega
+	9:   "G", // giga
+	12:  "T", // tera
+	15:  "P", // peta
+	18:  "E", // exa
+	21:  "Z", // zetta
+	24:  "Y", // yotta
+}
+
+var revSIPrefixTable = revfmap(siPrefixTable)
+
+// revfmap reverses the map and precomputes the power multiplier
+func revfmap(in map[float64]string) map[string]float64 {
+	rv := map[string]float64{}
+	for k, v := range in {
+		rv[v] = math.Pow(10, k)
+	}
+	return rv
+}
+
+var riParseRegex *regexp.Regexp
+
+func init() {
+	ri := `^([\-0-9.]+)\s?([`
+	for _, v := range siPrefixTable {
+		ri += v
+	}
+	ri += `]?)(.*)`
+
+	riParseRegex = regexp.MustCompile(ri)
+}
+
+// ComputeSI finds the most appropriate SI prefix for the given number
+// and returns the prefix along with the value adjusted to be within
+// that prefix.
+//
+// See also: SI, ParseSI.
+//
+// e.g. ComputeSI(2.2345e-12) -> (2.2345, "p")
+func ComputeSI(input float64) (float64, string) {
+	if input == 0 {
+		return 0, ""
+	}
+	mag := math.Abs(input)
+	exponent := math.Floor(logn(mag, 10))
+	exponent = math.Floor(exponent/3) * 3
+
+	value := mag / math.Pow(10, exponent)
+
+	// Handle special case where value is exactly 1000.0
+	// Should return 1 M instead of 1000 k
+	if value == 1000.0 {
+		exponent += 3
+		value = mag / math.Pow(10, exponent)
+	}
+
+	value = math.Copysign(value, input)
+
+	prefix := siPrefixTable[exponent]
+	return value, prefix
+}
+
+// SI returns a string with default formatting.
+//
+// SI uses Ftoa to format float value, removing trailing zeros.
+//
+// See also: ComputeSI, ParseSI.
+//
+// e.g. SI(1000000, "B") -> 1 MB
+// e.g. SI(2.2345e-12, "F") -> 2.2345 pF
+func SI(input float64, unit string) string {
+	value, prefix := ComputeSI(input)
+	return Ftoa(value) + " " + prefix + unit
+}
+
+var errInvalid = errors.New("invalid input")
+
+// ParseSI parses an SI string back into the number and unit.
+//
+// See also: SI, ComputeSI.
+//
+// e.g. ParseSI("2.2345 pF") -> (2.2345e-12, "F", nil)
+func ParseSI(input string) (float64, string, error) {
+	found := riParseRegex.FindStringSubmatch(input)
+	if len(found) != 4 {
+		return 0, "", errInvalid
+	}
+	mag := revSIPrefixTable[found[2]]
+	unit := found[3]
+
+	base, err := strconv.ParseFloat(found[1], 64)
+	return base * mag, unit, err
+}

+ 117 - 0
vendor/github.com/dustin/go-humanize/times.go

@@ -0,0 +1,117 @@
+package humanize
+
+import (
+	"fmt"
+	"math"
+	"sort"
+	"time"
+)
+
+// Seconds-based time units
+const (
+	Day      = 24 * time.Hour
+	Week     = 7 * Day
+	Month    = 30 * Day
+	Year     = 12 * Month
+	LongTime = 37 * Year
+)
+
+// Time formats a time into a relative string.
+//
+// Time(someT) -> "3 weeks ago"
+func Time(then time.Time) string {
+	return RelTime(then, time.Now(), "ago", "from now")
+}
+
+// A RelTimeMagnitude struct contains a relative time point at which
+// the relative format of time will switch to a new format string.  A
+// slice of these in ascending order by their "D" field is passed to
+// CustomRelTime to format durations.
+//
+// The Format field is a string that may contain a "%s" which will be
+// replaced with the appropriate signed label (e.g. "ago" or "from
+// now") and a "%d" that will be replaced by the quantity.
+//
+// The DivBy field is the amount of time the time difference must be
+// divided by in order to display correctly.
+//
+// e.g. if D is 2*time.Minute and you want to display "%d minutes %s"
+// DivBy should be time.Minute so whatever the duration is will be
+// expressed in minutes.
+type RelTimeMagnitude struct {
+	D      time.Duration
+	Format string
+	DivBy  time.Duration
+}
+
+var defaultMagnitudes = []RelTimeMagnitude{
+	{time.Second, "now", time.Second},
+	{2 * time.Second, "1 second %s", 1},
+	{time.Minute, "%d seconds %s", time.Second},
+	{2 * time.Minute, "1 minute %s", 1},
+	{time.Hour, "%d minutes %s", time.Minute},
+	{2 * time.Hour, "1 hour %s", 1},
+	{Day, "%d hours %s", time.Hour},
+	{2 * Day, "1 day %s", 1},
+	{Week, "%d days %s", Day},
+	{2 * Week, "1 week %s", 1},
+	{Month, "%d weeks %s", Week},
+	{2 * Month, "1 month %s", 1},
+	{Year, "%d months %s", Month},
+	{18 * Month, "1 year %s", 1},
+	{2 * Year, "2 years %s", 1},
+	{LongTime, "%d years %s", Year},
+	{math.MaxInt64, "a long while %s", 1},
+}
+
+// RelTime formats a time into a relative string.
+//
+// It takes two times and two labels.  In addition to the generic time
+// delta string (e.g. 5 minutes), the labels are used applied so that
+// the label corresponding to the smaller time is applied.
+//
+// RelTime(timeInPast, timeInFuture, "earlier", "later") -> "3 weeks earlier"
+func RelTime(a, b time.Time, albl, blbl string) string {
+	return CustomRelTime(a, b, albl, blbl, defaultMagnitudes)
+}
+
+// CustomRelTime formats a time into a relative string.
+//
+// It takes two times two labels and a table of relative time formats.
+// In addition to the generic time delta string (e.g. 5 minutes), the
+// labels are used applied so that the label corresponding to the
+// smaller time is applied.
+func CustomRelTime(a, b time.Time, albl, blbl string, magnitudes []RelTimeMagnitude) string {
+	lbl := albl
+	diff := b.Sub(a)
+
+	if a.After(b) {
+		lbl = blbl
+		diff = a.Sub(b)
+	}
+
+	n := sort.Search(len(magnitudes), func(i int) bool {
+		return magnitudes[i].D > diff
+	})
+
+	if n >= len(magnitudes) {
+		n = len(magnitudes) - 1
+	}
+	mag := magnitudes[n]
+	args := []interface{}{}
+	escaped := false
+	for _, ch := range mag.Format {
+		if escaped {
+			switch ch {
+			case 's':
+				args = append(args, lbl)
+			case 'd':
+				args = append(args, diff/mag.DivBy)
+			}
+			escaped = false
+		} else {
+			escaped = ch == '%'
+		}
+	}
+	return fmt.Sprintf(mag.Format, args...)
+}

+ 1 - 38
vendor/github.com/ugorji/go/codec/0doc.go

@@ -39,6 +39,7 @@ Rich Feature Set includes:
   - Careful selected use of 'unsafe' for targeted performance gains.
   - Careful selected use of 'unsafe' for targeted performance gains.
     100% mode exists where 'unsafe' is not used at all.
     100% mode exists where 'unsafe' is not used at all.
   - Lock-free (sans mutex) concurrency for scaling to 100's of cores
   - Lock-free (sans mutex) concurrency for scaling to 100's of cores
+  - In-place updates during decode, with option to zero value in maps and slices prior to decode
   - Coerce types where appropriate
   - Coerce types where appropriate
     e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
     e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
   - Corner Cases:
   - Corner Cases:
@@ -224,41 +225,3 @@ with some caveats. See Encode documentation.
 */
 */
 package codec
 package codec
 
 
-// TODO:
-//   - For Go 1.11, when mid-stack inlining is enabled,
-//     we should use committed functions for writeXXX and readXXX calls.
-//     This involves uncommenting the methods for decReaderSwitch and encWriterSwitch
-//     and using those (decReaderSwitch and encWriterSwitch) in all handles
-//     instead of encWriter and decReader.
-//     The benefit is that, for the (En|De)coder over []byte, the encWriter/decReader
-//     will be inlined, giving a performance bump for that typical case.
-//     However, it will only  be inlined if mid-stack inlining is enabled,
-//     as we call panic to raise errors, and panic currently prevents inlining.
-//
-// PUNTED:
-//   - To make Handle comparable, make extHandle in BasicHandle a non-embedded pointer,
-//     and use overlay methods on *BasicHandle to call through to extHandle after initializing
-//     the "xh *extHandle" to point to a real slice.
-//
-// BEFORE EACH RELEASE:
-//   - Look through and fix padding for each type, to eliminate false sharing
-//     - critical shared objects that are read many times
-//       TypeInfos
-//     - pooled objects:
-//       decNaked, decNakedContainers, codecFner, typeInfoLoadArray, 
-//     - small objects allocated independently, that we read/use much across threads:
-//       codecFn, typeInfo
-//     - Objects allocated independently and used a lot
-//       Decoder, Encoder,
-//       xxxHandle, xxxEncDriver, xxxDecDriver (xxx = json, msgpack, cbor, binc, simple)
-//     - In all above, arrange values modified together to be close to each other.
-//
-//     For all of these, either ensure that they occupy full cache lines,
-//     or ensure that the things just past the cache line boundary are hardly read/written
-//     e.g. JsonHandle.RawBytesExt - which is copied into json(En|De)cDriver at init
-//
-//     Occupying full cache lines means they occupy 8*N words (where N is an integer).
-//     Check this out by running: ./run.sh -z
-//     - look at those tagged ****, meaning they are not occupying full cache lines
-//     - look at those tagged <<<<, meaning they are larger than 32 words (something to watch)
-//   - Run "golint -min_confidence 0.81"

+ 0 - 0
vendor/github.com/ugorji/go/LICENSE → vendor/github.com/ugorji/go/codec/LICENSE


+ 65 - 29
vendor/github.com/ugorji/go/codec/binc.go

@@ -102,7 +102,7 @@ func bincdesc(vd, vs byte) string {
 type bincEncDriver struct {
 type bincEncDriver struct {
 	e *Encoder
 	e *Encoder
 	h *BincHandle
 	h *BincHandle
-	w encWriter
+	w *encWriterSwitch
 	m map[string]uint16 // symbols
 	m map[string]uint16 // symbols
 	b [16]byte          // scratch, used for encoding numbers - bigendian style
 	b [16]byte          // scratch, used for encoding numbers - bigendian style
 	s uint16            // symbols sequencer
 	s uint16            // symbols sequencer
@@ -110,6 +110,7 @@ type bincEncDriver struct {
 	encDriverTrackContainerWriter
 	encDriverTrackContainerWriter
 	noBuiltInTypes
 	noBuiltInTypes
 	// encNoSeparator
 	// encNoSeparator
+	_ [1]uint64 // padding
 }
 }
 
 
 func (e *bincEncDriver) EncodeNil() {
 func (e *bincEncDriver) EncodeNil() {
@@ -182,7 +183,7 @@ func (e *bincEncDriver) encIntegerPrune(bd byte, pos bool, v uint64, lim uint8)
 }
 }
 
 
 func (e *bincEncDriver) EncodeInt(v int64) {
 func (e *bincEncDriver) EncodeInt(v int64) {
-	const nbd byte = bincVdNegInt << 4
+	// const nbd byte = bincVdNegInt << 4
 	if v >= 0 {
 	if v >= 0 {
 		e.encUint(bincVdPosInt<<4, true, uint64(v))
 		e.encUint(bincVdPosInt<<4, true, uint64(v))
 	} else if v == -1 {
 	} else if v == -1 {
@@ -243,18 +244,6 @@ func (e *bincEncDriver) WriteMapStart(length int) {
 	e.c = containerMapStart
 	e.c = containerMapStart
 }
 }
 
 
-func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
-	if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
-		e.EncodeSymbol(v)
-		return
-	}
-	l := uint64(len(v))
-	e.encBytesLen(c, l)
-	if l > 0 {
-		e.w.writestr(v)
-	}
-}
-
 func (e *bincEncDriver) EncodeSymbol(v string) {
 func (e *bincEncDriver) EncodeSymbol(v string) {
 	// if WriteSymbolsNoRefs {
 	// if WriteSymbolsNoRefs {
 	// 	e.encodeString(cUTF8, v)
 	// 	e.encodeString(cUTF8, v)
@@ -319,6 +308,31 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
 	}
 	}
 }
 }
 
 
+func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
+	if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
+		e.EncodeSymbol(v)
+		return
+	}
+	l := uint64(len(v))
+	e.encBytesLen(c, l)
+	if l > 0 {
+		e.w.writestr(v)
+	}
+}
+
+func (e *bincEncDriver) EncodeStringEnc(c charEncoding, v string) {
+	if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
+		e.EncodeSymbol(v)
+		return
+	}
+	l := uint64(len(v))
+	e.encLen(bincVdString<<4, l) // e.encBytesLen(c, l)
+	if l > 0 {
+		e.w.writestr(v)
+	}
+
+}
+
 func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 	if v == nil {
 	if v == nil {
 		e.EncodeNil()
 		e.EncodeNil()
@@ -331,6 +345,18 @@ func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 	}
 	}
 }
 }
 
 
+func (e *bincEncDriver) EncodeStringBytesRaw(v []byte) {
+	if v == nil {
+		e.EncodeNil()
+		return
+	}
+	l := uint64(len(v))
+	e.encLen(bincVdByteArray<<4, l) // e.encBytesLen(c, l)
+	if l > 0 {
+		e.w.writeb(v)
+	}
+}
+
 func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
 func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
 	//TODO: support bincUnicodeOther (for now, just use string or bytearray)
 	//TODO: support bincUnicodeOther (for now, just use string or bytearray)
 	if c == cRAW {
 	if c == cRAW {
@@ -377,7 +403,7 @@ type bincDecDriver struct {
 
 
 	d      *Decoder
 	d      *Decoder
 	h      *BincHandle
 	h      *BincHandle
-	r      decReader
+	r      *decReaderSwitch
 	br     bool // bytes reader
 	br     bool // bytes reader
 	bdRead bool
 	bdRead bool
 	bd     byte
 	bd     byte
@@ -391,7 +417,7 @@ type bincDecDriver struct {
 	// noStreamingCodec
 	// noStreamingCodec
 	// decNoSeparator
 	// decNoSeparator
 
 
-	b [8 * 8]byte // scratch
+	b [(8 + 1) * 8]byte // scratch
 }
 }
 
 
 func (d *bincDecDriver) readNextBd() {
 func (d *bincDecDriver) readNextBd() {
@@ -452,7 +478,7 @@ func (d *bincDecDriver) DecodeTime() (t time.Time) {
 		d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
 		d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
 		return
 		return
 	}
 	}
-	t, err := bincDecodeTime(d.r.readx(int(d.vs)))
+	t, err := bincDecodeTime(d.r.readx(uint(d.vs)))
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
@@ -485,7 +511,8 @@ func (d *bincDecDriver) decFloat() (f float64) {
 		d.decFloatPre(d.vs, 8)
 		d.decFloatPre(d.vs, 8)
 		f = math.Float64frombits(bigen.Uint64(d.b[0:8]))
 		f = math.Float64frombits(bigen.Uint64(d.b[0:8]))
 	} else {
 	} else {
-		d.d.errorf("read float - only float32 and float64 are supported - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("read float - only float32 and float64 are supported - %s %x-%x/%s",
+			msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
 		return
 		return
 	}
 	}
 	return
 	return
@@ -507,9 +534,9 @@ func (d *bincDecDriver) decUint() (v uint64) {
 		d.r.readb(d.b[4:8])
 		d.r.readb(d.b[4:8])
 		v = uint64(bigen.Uint32(d.b[4:8]))
 		v = uint64(bigen.Uint32(d.b[4:8]))
 	case 4, 5, 6:
 	case 4, 5, 6:
-		lim := int(7 - d.vs)
+		lim := 7 - d.vs
 		d.r.readb(d.b[lim:8])
 		d.r.readb(d.b[lim:8])
-		for i := 0; i < lim; i++ {
+		for i := uint8(0); i < lim; i++ {
 			d.b[i] = 0
 			d.b[i] = 0
 		}
 		}
 		v = uint64(bigen.Uint64(d.b[:8]))
 		v = uint64(bigen.Uint64(d.b[:8]))
@@ -684,7 +711,7 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
 		slen = d.decLen()
 		slen = d.decLen()
 		if zerocopy {
 		if zerocopy {
 			if d.br {
 			if d.br {
-				bs2 = d.r.readx(slen)
+				bs2 = d.r.readx(uint(slen))
 			} else if len(bs) == 0 {
 			} else if len(bs) == 0 {
 				bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, d.b[:])
 				bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, d.b[:])
 			} else {
 			} else {
@@ -793,7 +820,7 @@ func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 	d.bdRead = false
 	d.bdRead = false
 	if zerocopy {
 	if zerocopy {
 		if d.br {
 		if d.br {
-			return d.r.readx(clen)
+			return d.r.readx(uint(clen))
 		} else if len(bs) == 0 {
 		} else if len(bs) == 0 {
 			bs = d.b[:]
 			bs = d.b[:]
 		}
 		}
@@ -829,11 +856,16 @@ func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []b
 			d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag)
 			d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag)
 			return
 			return
 		}
 		}
-		xbs = d.r.readx(l)
+		if d.br {
+			xbs = d.r.readx(uint(l))
+		} else {
+			xbs = decByteSlice(d.r, l, d.d.h.MaxInitLen, d.d.b[:])
+		}
 	} else if d.vd == bincVdByteArray {
 	} else if d.vd == bincVdByteArray {
 		xbs = d.DecodeBytes(nil, true)
 		xbs = d.DecodeBytes(nil, true)
 	} else {
 	} else {
-		d.d.errorf("ext - expecting extensions or byte array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		d.d.errorf("ext - expecting extensions or byte array - %s %x-%x/%s",
+			msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
 		return
 		return
 	}
 	}
 	d.bdRead = false
 	d.bdRead = false
@@ -845,7 +877,7 @@ func (d *bincDecDriver) DecodeNaked() {
 		d.readNextBd()
 		d.readNextBd()
 	}
 	}
 
 
-	n := d.d.n
+	n := d.d.naked()
 	var decodeFurther bool
 	var decodeFurther bool
 
 
 	switch d.vd {
 	switch d.vd {
@@ -878,7 +910,8 @@ func (d *bincDecDriver) DecodeNaked() {
 			n.v = valueTypeInt
 			n.v = valueTypeInt
 			n.i = int64(-1) // int8(-1)
 			n.i = int64(-1) // int8(-1)
 		default:
 		default:
-			d.d.errorf("cannot infer value - unrecognized special value from descriptor %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
+			d.d.errorf("cannot infer value - unrecognized special value from descriptor %x-%x/%s",
+				d.vd, d.vs, bincdesc(d.vd, d.vs))
 		}
 		}
 	case bincVdSmallInt:
 	case bincVdSmallInt:
 		n.v = valueTypeUint
 		n.v = valueTypeUint
@@ -903,7 +936,7 @@ func (d *bincDecDriver) DecodeNaked() {
 		n.l = d.DecodeBytes(nil, false)
 		n.l = d.DecodeBytes(nil, false)
 	case bincVdTimestamp:
 	case bincVdTimestamp:
 		n.v = valueTypeTime
 		n.v = valueTypeTime
-		tt, err := bincDecodeTime(d.r.readx(int(d.vs)))
+		tt, err := bincDecodeTime(d.r.readx(uint(d.vs)))
 		if err != nil {
 		if err != nil {
 			panic(err)
 			panic(err)
 		}
 		}
@@ -912,7 +945,11 @@ func (d *bincDecDriver) DecodeNaked() {
 		n.v = valueTypeExt
 		n.v = valueTypeExt
 		l := d.decLen()
 		l := d.decLen()
 		n.u = uint64(d.r.readn1())
 		n.u = uint64(d.r.readn1())
-		n.l = d.r.readx(l)
+		if d.br {
+			n.l = d.r.readx(uint(l))
+		} else {
+			n.l = decByteSlice(d.r, l, d.d.h.MaxInitLen, d.d.b[:])
+		}
 	case bincVdArray:
 	case bincVdArray:
 		n.v = valueTypeArray
 		n.v = valueTypeArray
 		decodeFurther = true
 		decodeFurther = true
@@ -930,7 +967,6 @@ func (d *bincDecDriver) DecodeNaked() {
 		n.v = valueTypeInt
 		n.v = valueTypeInt
 		n.i = int64(n.u)
 		n.i = int64(n.u)
 	}
 	}
-	return
 }
 }
 
 
 //------------------------------------
 //------------------------------------

+ 47 - 34
vendor/github.com/ugorji/go/codec/cbor.go

@@ -33,31 +33,31 @@ const (
 
 
 const (
 const (
 	cborBdIndefiniteBytes  byte = 0x5f
 	cborBdIndefiniteBytes  byte = 0x5f
-	cborBdIndefiniteString      = 0x7f
-	cborBdIndefiniteArray       = 0x9f
-	cborBdIndefiniteMap         = 0xbf
-	cborBdBreak                 = 0xff
+	cborBdIndefiniteString byte = 0x7f
+	cborBdIndefiniteArray  byte = 0x9f
+	cborBdIndefiniteMap    byte = 0xbf
+	cborBdBreak            byte = 0xff
 )
 )
 
 
 // These define some in-stream descriptors for
 // These define some in-stream descriptors for
 // manual encoding e.g. when doing explicit indefinite-length
 // manual encoding e.g. when doing explicit indefinite-length
 const (
 const (
 	CborStreamBytes  byte = 0x5f
 	CborStreamBytes  byte = 0x5f
-	CborStreamString      = 0x7f
-	CborStreamArray       = 0x9f
-	CborStreamMap         = 0xbf
-	CborStreamBreak       = 0xff
+	CborStreamString byte = 0x7f
+	CborStreamArray  byte = 0x9f
+	CborStreamMap    byte = 0xbf
+	CborStreamBreak  byte = 0xff
 )
 )
 
 
 const (
 const (
 	cborBaseUint   byte = 0x00
 	cborBaseUint   byte = 0x00
-	cborBaseNegInt      = 0x20
-	cborBaseBytes       = 0x40
-	cborBaseString      = 0x60
-	cborBaseArray       = 0x80
-	cborBaseMap         = 0xa0
-	cborBaseTag         = 0xc0
-	cborBaseSimple      = 0xe0
+	cborBaseNegInt byte = 0x20
+	cborBaseBytes  byte = 0x40
+	cborBaseString byte = 0x60
+	cborBaseArray  byte = 0x80
+	cborBaseMap    byte = 0xa0
+	cborBaseTag    byte = 0xc0
+	cborBaseSimple byte = 0xe0
 )
 )
 
 
 func cbordesc(bd byte) string {
 func cbordesc(bd byte) string {
@@ -105,12 +105,11 @@ func cbordesc(bd byte) string {
 type cborEncDriver struct {
 type cborEncDriver struct {
 	noBuiltInTypes
 	noBuiltInTypes
 	encDriverNoopContainerWriter
 	encDriverNoopContainerWriter
-	// encNoSeparator
 	e *Encoder
 	e *Encoder
-	w encWriter
+	w *encWriterSwitch
 	h *CborHandle
 	h *CborHandle
 	x [8]byte
 	x [8]byte
-	_ [3]uint64 // padding
+	// _ [3]uint64 // padding
 }
 }
 
 
 func (e *cborEncDriver) EncodeNil() {
 func (e *cborEncDriver) EncodeNil() {
@@ -173,7 +172,7 @@ func (e *cborEncDriver) EncodeTime(t time.Time) {
 		e.EncodeNil()
 		e.EncodeNil()
 	} else if e.h.TimeRFC3339 {
 	} else if e.h.TimeRFC3339 {
 		e.encUint(0, cborBaseTag)
 		e.encUint(0, cborBaseTag)
-		e.EncodeString(cUTF8, t.Format(time.RFC3339Nano))
+		e.EncodeStringEnc(cUTF8, t.Format(time.RFC3339Nano))
 	} else {
 	} else {
 		e.encUint(1, cborBaseTag)
 		e.encUint(1, cborBaseTag)
 		t = t.UTC().Round(time.Microsecond)
 		t = t.UTC().Round(time.Microsecond)
@@ -197,9 +196,11 @@ func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Enco
 
 
 func (e *cborEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
 func (e *cborEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
 	e.encUint(uint64(re.Tag), cborBaseTag)
 	e.encUint(uint64(re.Tag), cborBaseTag)
-	if false && re.Data != nil {
-		en.encode(re.Data)
-	} else if re.Value != nil {
+	// only encodes re.Value (never re.Data)
+	// if false && re.Data != nil {
+	// 	en.encode(re.Data)
+	// } else if re.Value != nil {
+	if re.Value != nil {
 		en.encode(re.Value)
 		en.encode(re.Value)
 	} else {
 	} else {
 		e.EncodeNil()
 		e.EncodeNil()
@@ -238,6 +239,10 @@ func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
 	e.encStringBytesS(cborBaseString, v)
 	e.encStringBytesS(cborBaseString, v)
 }
 }
 
 
+func (e *cborEncDriver) EncodeStringEnc(c charEncoding, v string) {
+	e.encStringBytesS(cborBaseString, v)
+}
+
 func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 	if v == nil {
 	if v == nil {
 		e.EncodeNil()
 		e.EncodeNil()
@@ -248,6 +253,14 @@ func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 	}
 	}
 }
 }
 
 
+func (e *cborEncDriver) EncodeStringBytesRaw(v []byte) {
+	if v == nil {
+		e.EncodeNil()
+	} else {
+		e.encStringBytesS(cborBaseBytes, stringView(v))
+	}
+}
+
 func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
 func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
 	if e.h.IndefiniteLength {
 	if e.h.IndefiniteLength {
 		if bb == cborBaseBytes {
 		if bb == cborBaseBytes {
@@ -255,16 +268,17 @@ func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
 		} else {
 		} else {
 			e.w.writen1(cborBdIndefiniteString)
 			e.w.writen1(cborBdIndefiniteString)
 		}
 		}
-		blen := len(v) / 4
+		var vlen uint = uint(len(v))
+		blen := vlen / 4
 		if blen == 0 {
 		if blen == 0 {
 			blen = 64
 			blen = 64
 		} else if blen > 1024 {
 		} else if blen > 1024 {
 			blen = 1024
 			blen = 1024
 		}
 		}
-		for i := 0; i < len(v); {
+		for i := uint(0); i < vlen; {
 			var v2 string
 			var v2 string
 			i2 := i + blen
 			i2 := i + blen
-			if i2 < len(v) {
+			if i2 < vlen {
 				v2 = v[i:i2]
 				v2 = v[i:i2]
 			} else {
 			} else {
 				v2 = v[i:]
 				v2 = v[i:]
@@ -283,17 +297,16 @@ func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
 // ----------------------
 // ----------------------
 
 
 type cborDecDriver struct {
 type cborDecDriver struct {
-	d *Decoder
-	h *CborHandle
-	r decReader
-	// b      [scratchByteArrayLen]byte
+	d      *Decoder
+	h      *CborHandle
+	r      *decReaderSwitch
 	br     bool // bytes reader
 	br     bool // bytes reader
 	bdRead bool
 	bdRead bool
 	bd     byte
 	bd     byte
 	noBuiltInTypes
 	noBuiltInTypes
 	// decNoSeparator
 	// decNoSeparator
 	decDriverNoopContainerReader
 	decDriverNoopContainerReader
-	_ [3]uint64 // padding
+	// _ [3]uint64 // padding
 }
 }
 
 
 func (d *cborDecDriver) readNextBd() {
 func (d *cborDecDriver) readNextBd() {
@@ -382,7 +395,8 @@ func (d *cborDecDriver) decCheckInteger() (neg bool) {
 	} else if major == cborMajorNegInt {
 	} else if major == cborMajorNegInt {
 		neg = true
 		neg = true
 	} else {
 	} else {
-		d.d.errorf("not an integer - invalid major %v from descriptor %x/%s", major, d.bd, cbordesc(d.bd))
+		d.d.errorf("not an integer - invalid major %v from descriptor %x/%s",
+			major, d.bd, cbordesc(d.bd))
 		return
 		return
 	}
 	}
 	return
 	return
@@ -529,7 +543,7 @@ func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 	d.bdRead = false
 	d.bdRead = false
 	if zerocopy {
 	if zerocopy {
 		if d.br {
 		if d.br {
-			return d.r.readx(clen)
+			return d.r.readx(uint(clen))
 		} else if len(bs) == 0 {
 		} else if len(bs) == 0 {
 			bs = d.d.b[:]
 			bs = d.d.b[:]
 		}
 		}
@@ -619,7 +633,7 @@ func (d *cborDecDriver) DecodeNaked() {
 		d.readNextBd()
 		d.readNextBd()
 	}
 	}
 
 
-	n := d.d.n
+	n := d.d.naked()
 	var decodeFurther bool
 	var decodeFurther bool
 
 
 	switch d.bd {
 	switch d.bd {
@@ -692,7 +706,6 @@ func (d *cborDecDriver) DecodeNaked() {
 	if !decodeFurther {
 	if !decodeFurther {
 		d.bdRead = false
 		d.bdRead = false
 	}
 	}
-	return
 }
 }
 
 
 // -------------------------
 // -------------------------

+ 13 - 0
vendor/github.com/ugorji/go/codec/codecgen.go

@@ -0,0 +1,13 @@
+// +build codecgen generated
+
+package codec
+
+// this file is here, to set the codecgen variable to true
+// when the build tag codecgen is set.
+//
+// this allows us do specific things e.g. skip missing fields tests,
+// when running in codecgen mode.
+
+func init() {
+	codecgen = true
+}

File diff suppressed because it is too large
+ 532 - 365
vendor/github.com/ugorji/go/codec/decode.go


File diff suppressed because it is too large
+ 482 - 162
vendor/github.com/ugorji/go/codec/encode.go


File diff suppressed because it is too large
+ 162 - 156
vendor/github.com/ugorji/go/codec/fast-path.generated.go


+ 1 - 1
vendor/github.com/ugorji/go/codec/fast-path.not.go

@@ -35,7 +35,7 @@ type fastpathA [0]fastpathE
 func (x fastpathA) index(rtid uintptr) int { return -1 }
 func (x fastpathA) index(rtid uintptr) int { return -1 }
 
 
 func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
 func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
-	fn := d.cfer().get(uint8SliceTyp, true, true)
+	fn := d.h.fn(uint8SliceTyp, true, true)
 	d.kSlice(&fn.i, reflect.ValueOf(&v).Elem())
 	d.kSlice(&fn.i, reflect.ValueOf(&v).Elem())
 	return v, true
 	return v, true
 }
 }

+ 24 - 8
vendor/github.com/ugorji/go/codec/gen-helper.generated.go

@@ -1,6 +1,6 @@
-/* // +build ignore */
+// comment this out // + build ignore
 
 
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 
 // Code generated from gen-helper.go.tmpl - DO NOT EDIT.
 // Code generated from gen-helper.go.tmpl - DO NOT EDIT.
@@ -10,10 +10,11 @@ package codec
 import (
 import (
 	"encoding"
 	"encoding"
 	"reflect"
 	"reflect"
+	"strconv"
 )
 )
 
 
 // GenVersion is the current version of codecgen.
 // GenVersion is the current version of codecgen.
-const GenVersion = 8
+const GenVersion = 10
 
 
 // This file is used to generate helper code for codecgen.
 // This file is used to generate helper code for codecgen.
 // The values here i.e. genHelper(En|De)coder are not to be used directly by
 // The values here i.e. genHelper(En|De)coder are not to be used directly by
@@ -49,10 +50,20 @@ type genHelperEncDriver struct {
 
 
 func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
 func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
 func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
 func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
-	encStructFieldKey(x.encDriver, keyType, s)
+	var m must
+	if keyType == valueTypeString {
+		x.encDriver.EncodeStringEnc(cUTF8, s)
+	} else if keyType == valueTypeInt {
+		x.encDriver.EncodeInt(m.Int(strconv.ParseInt(s, 10, 64)))
+	} else if keyType == valueTypeUint {
+		x.encDriver.EncodeUint(m.Uint(strconv.ParseUint(s, 10, 64)))
+	} else if keyType == valueTypeFloat {
+		x.encDriver.EncodeFloat64(m.Float(strconv.ParseFloat(s, 64)))
+	}
+	// encStructFieldKey(x.encDriver, keyType, s)
 }
 }
 func (x genHelperEncDriver) EncodeSymbol(s string) {
 func (x genHelperEncDriver) EncodeSymbol(s string) {
-	x.encDriver.EncodeString(cUTF8, s)
+	x.encDriver.EncodeStringEnc(cUTF8, s)
 }
 }
 
 
 type genHelperDecDriver struct {
 type genHelperDecDriver struct {
@@ -124,19 +135,19 @@ func (f genHelperEncoder) EncFallback(iv interface{}) {
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
 func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
 	bs, fnerr := iv.MarshalText()
 	bs, fnerr := iv.MarshalText()
-	f.e.marshal(bs, fnerr, false, cUTF8)
+	f.e.marshalUtf8(bs, fnerr)
 }
 }
 
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
 func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
 	bs, fnerr := iv.MarshalJSON()
 	bs, fnerr := iv.MarshalJSON()
-	f.e.marshal(bs, fnerr, true, cUTF8)
+	f.e.marshalAsis(bs, fnerr)
 }
 }
 
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
 func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
 	bs, fnerr := iv.MarshalBinary()
 	bs, fnerr := iv.MarshalBinary()
-	f.e.marshal(bs, fnerr, false, cRAW)
+	f.e.marshalRaw(bs, fnerr)
 }
 }
 
 
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
@@ -169,6 +180,11 @@ func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
 	f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
 	f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
 }
 }
 
 
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) WriteStr(s string) {
+	f.e.w.writestr(s)
+}
+
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 //
 //
 // Deprecated: No longer used,
 // Deprecated: No longer used,

+ 2 - 2
vendor/github.com/ugorji/go/codec/gen.generated.go

@@ -1,6 +1,6 @@
 // +build codecgen.exec
 // +build codecgen.exec
 
 
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 // Use of this source code is governed by a MIT license found in the LICENSE file.
 
 
 package codec
 package codec
@@ -88,7 +88,7 @@ if {{var "l"}} == 0 {
 	} {{end}}
 	} {{end}}
 	var {{var "j"}} int 
 	var {{var "j"}} int 
     // var {{var "dn"}} bool 
     // var {{var "dn"}} bool 
-	for ; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
+	for {{var "j"}} = 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ { // bounds-check-elimination
 		{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
 		{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
 			if {{var "hl"}} {
 			if {{var "hl"}} {
 				{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
 				{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})

+ 25 - 15
vendor/github.com/ugorji/go/codec/gen.go

@@ -41,6 +41,8 @@ import (
 // However, codecgen doesn't support the following:
 // However, codecgen doesn't support the following:
 //   - Canonical option. (codecgen IGNORES it currently)
 //   - Canonical option. (codecgen IGNORES it currently)
 //     This is just because it has not been implemented.
 //     This is just because it has not been implemented.
+//   - MissingFielder implementation.
+//     If a type implements MissingFielder, it is completely ignored by codecgen.
 //
 //
 // During encode/decode, Selfer takes precedence.
 // During encode/decode, Selfer takes precedence.
 // A type implementing Selfer will know how to encode/decode itself statically.
 // A type implementing Selfer will know how to encode/decode itself statically.
@@ -102,7 +104,9 @@ import (
 // v6: removed unsafe from gen, and now uses codecgen.exec tag
 // v6: removed unsafe from gen, and now uses codecgen.exec tag
 // v7:
 // v7:
 // v8: current - we now maintain compatibility with old generated code.
 // v8: current - we now maintain compatibility with old generated code.
-const genVersion = 8
+// v9: skipped
+// v10: modified encDriver and decDriver interfaces. Remove deprecated methods after Jan 1, 2019
+const genVersion = 10
 
 
 const (
 const (
 	genCodecPkg        = "codec1978"
 	genCodecPkg        = "codec1978"
@@ -297,7 +301,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
 	// x.out(`panic(fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", `)
 	// x.out(`panic(fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", `)
 	// x.linef(`%v, %sGenVersion, file))`, genVersion, x.cpfx)
 	// x.linef(`%v, %sGenVersion, file))`, genVersion, x.cpfx)
 	x.linef("}")
 	x.linef("}")
-	x.line("if false { // reference the types, but skip this branch at build/run time")
+	x.line("if false { var _ byte = 0; // reference the types, but skip this branch at build/run time")
 	// x.line("_ = strconv.ParseInt")
 	// x.line("_ = strconv.ParseInt")
 	var n int
 	var n int
 	// for k, t := range x.im {
 	// for k, t := range x.im {
@@ -738,8 +742,8 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
 	defer func() { x.line("}") }() //end if block
 	defer func() { x.line("}") }() //end if block
 
 
 	if t == timeTyp {
 	if t == timeTyp {
-		x.linef("} else { r.EncodeTime(%s)", varname)
-		return
+		x.linef("} else if !z.EncBasicHandle().TimeNotBuiltin { r.EncodeTime(%s)", varname)
+		// return
 	}
 	}
 	if t == rawTyp {
 	if t == rawTyp {
 		x.linef("} else { z.EncRaw(%s)", varname)
 		x.linef("} else { z.EncRaw(%s)", varname)
@@ -794,7 +798,7 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
 	case reflect.Bool:
 	case reflect.Bool:
 		x.line("r.EncodeBool(bool(" + varname + "))")
 		x.line("r.EncodeBool(bool(" + varname + "))")
 	case reflect.String:
 	case reflect.String:
-		x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + ", string(" + varname + "))")
+		x.line("r.EncodeStringEnc(codecSelferCcUTF8" + x.xs + ", string(" + varname + "))")
 	case reflect.Chan:
 	case reflect.Chan:
 		x.xtraSM(varname, t, true, false)
 		x.xtraSM(varname, t, true, false)
 		// x.encListFallback(varname, rtid, t)
 		// x.encListFallback(varname, rtid, t)
@@ -808,7 +812,7 @@ func (x *genRunner) enc(varname string, t reflect.Type) {
 		// - if elements are primitives or Selfers, call dedicated function on each member.
 		// - if elements are primitives or Selfers, call dedicated function on each member.
 		// - else call Encoder.encode(XXX) on it.
 		// - else call Encoder.encode(XXX) on it.
 		if rtid == uint8SliceTypId {
 		if rtid == uint8SliceTypId {
-			x.line("r.EncodeStringBytes(codecSelferCcRAW" + x.xs + ", []byte(" + varname + "))")
+			x.line("r.EncodeStringBytesRaw([]byte(" + varname + "))")
 		} else if fastpathAV.index(rtid) != -1 {
 		} else if fastpathAV.index(rtid) != -1 {
 			g := x.newGenV(t)
 			g := x.newGenV(t)
 			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", e)")
 			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", e)")
@@ -858,7 +862,7 @@ func (x *genRunner) encZero(t reflect.Type) {
 	case reflect.Bool:
 	case reflect.Bool:
 		x.line("r.EncodeBool(false)")
 		x.line("r.EncodeBool(false)")
 	case reflect.String:
 	case reflect.String:
-		x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + `, "")`)
+		x.line("r.EncodeStringEnc(codecSelferCcUTF8" + x.xs + `, "")`)
 	default:
 	default:
 		x.line("r.EncodeNil()")
 		x.line("r.EncodeNil()")
 	}
 	}
@@ -1047,7 +1051,7 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 		}
 		}
 		x.line("r.WriteMapElemKey()")
 		x.line("r.WriteMapElemKey()")
 
 
-		// x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + ", `" + si.encName + "`)")
+		// x.line("r.EncodeStringEnc(codecSelferCcUTF8" + x.xs + ", `" + si.encName + "`)")
 		// emulate EncStructFieldKey
 		// emulate EncStructFieldKey
 		switch ti.keyType {
 		switch ti.keyType {
 		case valueTypeInt:
 		case valueTypeInt:
@@ -1057,7 +1061,13 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 		case valueTypeFloat:
 		case valueTypeFloat:
 			x.linef("r.EncodeFloat64(z.M.Float(strconv.ParseFloat(`%s`, 64)))", si.encName)
 			x.linef("r.EncodeFloat64(z.M.Float(strconv.ParseFloat(`%s`, 64)))", si.encName)
 		default: // string
 		default: // string
-			x.linef("r.EncodeString(codecSelferCcUTF8%s, `%s`)", x.xs, si.encName)
+			if si.encNameAsciiAlphaNum {
+				x.linef(`if z.IsJSONHandle() { z.WriteStr("\"%s\"") } else { `, si.encName)
+			}
+			x.linef("r.EncodeStringEnc(codecSelferCcUTF8%s, `%s`)", x.xs, si.encName)
+			if si.encNameAsciiAlphaNum {
+				x.linef("}")
+			}
 		}
 		}
 		// x.linef("r.EncStructFieldKey(codecSelferValueType%s%s, `%s`)", ti.keyType.String(), x.xs, si.encName)
 		// x.linef("r.EncStructFieldKey(codecSelferValueType%s%s, `%s`)", ti.keyType.String(), x.xs, si.encName)
 		x.line("r.WriteMapElemValue()")
 		x.line("r.WriteMapElemValue()")
@@ -1084,11 +1094,11 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
 func (x *genRunner) encListFallback(varname string, t reflect.Type) {
 func (x *genRunner) encListFallback(varname string, t reflect.Type) {
 	elemBytes := t.Elem().Kind() == reflect.Uint8
 	elemBytes := t.Elem().Kind() == reflect.Uint8
 	if t.AssignableTo(uint8SliceTyp) {
 	if t.AssignableTo(uint8SliceTyp) {
-		x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, []byte(%s))", x.xs, varname)
+		x.linef("r.EncodeStringBytesRaw([]byte(%s))", varname)
 		return
 		return
 	}
 	}
 	if t.Kind() == reflect.Array && elemBytes {
 	if t.Kind() == reflect.Array && elemBytes {
-		x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, ((*[%d]byte)(%s))[:])", x.xs, t.Len(), varname)
+		x.linef("r.EncodeStringBytesRaw(((*[%d]byte)(%s))[:])", t.Len(), varname)
 		return
 		return
 	}
 	}
 	i := x.varsfx()
 	i := x.varsfx()
@@ -1108,7 +1118,7 @@ func (x *genRunner) encListFallback(varname string, t reflect.Type) {
 		}
 		}
 		// x.linef("%s = sch%s", varname, i)
 		// x.linef("%s = sch%s", varname, i)
 		if elemBytes {
 		if elemBytes {
-			x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, []byte(%s))", x.xs, "sch"+i)
+			x.linef("r.EncodeStringBytesRaw([]byte(%s))", "sch"+i)
 			x.line("}")
 			x.line("}")
 			return
 			return
 		}
 		}
@@ -1324,8 +1334,8 @@ func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
 		addrPfx = "&"
 		addrPfx = "&"
 	}
 	}
 	if t == timeTyp {
 	if t == timeTyp {
-		x.linef("} else { %s%v = r.DecodeTime()", ptrPfx, varname)
-		return
+		x.linef("} else if !z.DecBasicHandle().TimeNotBuiltin { %s%v = r.DecodeTime()", ptrPfx, varname)
+		// return
 	}
 	}
 	if t == rawTyp {
 	if t == rawTyp {
 		x.linef("} else { %s%v = z.DecRaw()", ptrPfx, varname)
 		x.linef("} else { %s%v = z.DecRaw()", ptrPfx, varname)
@@ -1927,7 +1937,7 @@ func genInternalEncCommandAsString(s string, vname string) string {
 	case "int", "int8", "int16", "int32", "int64":
 	case "int", "int8", "int16", "int32", "int64":
 		return "ee.EncodeInt(int64(" + vname + "))"
 		return "ee.EncodeInt(int64(" + vname + "))"
 	case "string":
 	case "string":
-		return "ee.EncodeString(cUTF8, " + vname + ")"
+		return "ee.EncodeStringEnc(cUTF8, " + vname + ")"
 	case "float32":
 	case "float32":
 		return "ee.EncodeFloat32(" + vname + ")"
 		return "ee.EncodeFloat32(" + vname + ")"
 	case "float64":
 	case "float64":

File diff suppressed because it is too large
+ 464 - 318
vendor/github.com/ugorji/go/codec/helper.go


+ 63 - 9
vendor/github.com/ugorji/go/codec/helper_not_unsafe.go

@@ -47,9 +47,9 @@ func rt2id(rt reflect.Type) uintptr {
 	return reflect.ValueOf(rt).Pointer()
 	return reflect.ValueOf(rt).Pointer()
 }
 }
 
 
-func rv2rtid(rv reflect.Value) uintptr {
-	return reflect.ValueOf(rv.Type()).Pointer()
-}
+// func rv2rtid(rv reflect.Value) uintptr {
+// 	return reflect.ValueOf(rv.Type()).Pointer()
+// }
 
 
 func i2rtid(i interface{}) uintptr {
 func i2rtid(i interface{}) uintptr {
 	return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
 	return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
@@ -93,23 +93,77 @@ func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) b
 // 	return reflect.ValueOf(i).Elem()
 // 	return reflect.ValueOf(i).Elem()
 // }
 // }
 
 
+// --------------------------
+type atomicClsErr struct {
+	v atomic.Value
+}
+
+func (x *atomicClsErr) load() (e clsErr) {
+	if i := x.v.Load(); i != nil {
+		e = i.(clsErr)
+	}
+	return
+}
+
+func (x *atomicClsErr) store(p clsErr) {
+	x.v.Store(p)
+}
+
 // --------------------------
 // --------------------------
 type atomicTypeInfoSlice struct { // expected to be 2 words
 type atomicTypeInfoSlice struct { // expected to be 2 words
 	v atomic.Value
 	v atomic.Value
 }
 }
 
 
-func (x *atomicTypeInfoSlice) load() []rtid2ti {
-	i := x.v.Load()
-	if i == nil {
-		return nil
+func (x *atomicTypeInfoSlice) load() (e []rtid2ti) {
+	if i := x.v.Load(); i != nil {
+		e = i.([]rtid2ti)
 	}
 	}
-	return i.([]rtid2ti)
+	return
 }
 }
 
 
 func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
 func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
 	x.v.Store(p)
 	x.v.Store(p)
 }
 }
 
 
+// --------------------------
+type atomicRtidFnSlice struct { // expected to be 2 words
+	v atomic.Value
+}
+
+func (x *atomicRtidFnSlice) load() (e []codecRtidFn) {
+	if i := x.v.Load(); i != nil {
+		e = i.([]codecRtidFn)
+	}
+	return
+}
+
+func (x *atomicRtidFnSlice) store(p []codecRtidFn) {
+	x.v.Store(p)
+}
+
+// --------------------------
+func (n *decNaked) ru() reflect.Value {
+	return reflect.ValueOf(&n.u).Elem()
+}
+func (n *decNaked) ri() reflect.Value {
+	return reflect.ValueOf(&n.i).Elem()
+}
+func (n *decNaked) rf() reflect.Value {
+	return reflect.ValueOf(&n.f).Elem()
+}
+func (n *decNaked) rl() reflect.Value {
+	return reflect.ValueOf(&n.l).Elem()
+}
+func (n *decNaked) rs() reflect.Value {
+	return reflect.ValueOf(&n.s).Elem()
+}
+func (n *decNaked) rt() reflect.Value {
+	return reflect.ValueOf(&n.t).Elem()
+}
+func (n *decNaked) rb() reflect.Value {
+	return reflect.ValueOf(&n.b).Elem()
+}
+
 // --------------------------
 // --------------------------
 func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
 func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
 	rv.SetBytes(d.rawBytes())
 	rv.SetBytes(d.rawBytes())
@@ -194,7 +248,7 @@ func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
 }
 }
 
 
 func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
 func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeString(cUTF8, rv.String())
+	e.e.EncodeStringEnc(cUTF8, rv.String())
 }
 }
 
 
 func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
 func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {

+ 122 - 21
vendor/github.com/ugorji/go/codec/helper_unsafe.go

@@ -97,9 +97,9 @@ func rt2id(rt reflect.Type) uintptr {
 	return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
 	return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
 }
 }
 
 
-func rv2rtid(rv reflect.Value) uintptr {
-	return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
-}
+// func rv2rtid(rv reflect.Value) uintptr {
+// 	return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
+// }
 
 
 func i2rtid(i interface{}) uintptr {
 func i2rtid(i interface{}) uintptr {
 	return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
 	return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
@@ -176,31 +176,132 @@ func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) b
 
 
 // --------------------------
 // --------------------------
 
 
-// atomicTypeInfoSlice contains length and pointer to the array for a slice.
-// It is expected to be 2 words.
+// atomicXXX is expected to be 2 words (for symmetry with atomic.Value)
+//
+// Note that we do not atomically load/store length and data pointer separately,
+// as this could lead to some races. Instead, we atomically load/store cappedSlice.
 //
 //
-// Previously, we atomically loaded and stored the length and array pointer separately,
-// which could lead to some races.
-// We now just atomically store and load the pointer to the value directly.
+// Note: with atomic.(Load|Store)Pointer, we MUST work with an unsafe.Pointer directly.
 
 
-type atomicTypeInfoSlice struct { // expected to be 2 words
-	l int            // length of the data array (must be first in struct, for 64-bit alignment necessary for 386)
-	v unsafe.Pointer // data array - Pointer (not uintptr) to maintain GC reference
+// ----------------------
+type atomicTypeInfoSlice struct {
+	v unsafe.Pointer // *[]rtid2ti
+	_ uintptr        // padding (atomicXXX expected to be 2 words)
 }
 }
 
 
-func (x *atomicTypeInfoSlice) load() []rtid2ti {
-	xp := unsafe.Pointer(x)
-	x2 := *(*atomicTypeInfoSlice)(atomic.LoadPointer(&xp))
-	if x2.l == 0 {
-		return nil
+func (x *atomicTypeInfoSlice) load() (s []rtid2ti) {
+	x2 := atomic.LoadPointer(&x.v)
+	if x2 != nil {
+		s = *(*[]rtid2ti)(x2)
 	}
 	}
-	return *(*[]rtid2ti)(unsafe.Pointer(&unsafeSlice{Data: x2.v, Len: x2.l, Cap: x2.l}))
+	return
 }
 }
 
 
 func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
 func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
-	s := (*unsafeSlice)(unsafe.Pointer(&p))
-	xp := unsafe.Pointer(x)
-	atomic.StorePointer(&xp, unsafe.Pointer(&atomicTypeInfoSlice{l: s.Len, v: s.Data}))
+	atomic.StorePointer(&x.v, unsafe.Pointer(&p))
+}
+
+// --------------------------
+type atomicRtidFnSlice struct {
+	v unsafe.Pointer // *[]codecRtidFn
+	_ uintptr        // padding (atomicXXX expected to be 2 words)
+}
+
+func (x *atomicRtidFnSlice) load() (s []codecRtidFn) {
+	x2 := atomic.LoadPointer(&x.v)
+	if x2 != nil {
+		s = *(*[]codecRtidFn)(x2)
+	}
+	return
+}
+
+func (x *atomicRtidFnSlice) store(p []codecRtidFn) {
+	atomic.StorePointer(&x.v, unsafe.Pointer(&p))
+}
+
+// --------------------------
+type atomicClsErr struct {
+	v unsafe.Pointer // *clsErr
+	_ uintptr        // padding (atomicXXX expected to be 2 words)
+}
+
+func (x *atomicClsErr) load() (e clsErr) {
+	x2 := (*clsErr)(atomic.LoadPointer(&x.v))
+	if x2 != nil {
+		e = *x2
+	}
+	return
+}
+
+func (x *atomicClsErr) store(p clsErr) {
+	atomic.StorePointer(&x.v, unsafe.Pointer(&p))
+}
+
+// --------------------------
+
+// to create a reflect.Value for each member field of decNaked,
+// we first create a global decNaked, and create reflect.Value
+// for them all.
+// This way, we have the flags and type in the reflect.Value.
+// Then, when a reflect.Value is called, we just copy it,
+// update the ptr to the decNaked's, and return it.
+
+type unsafeDecNakedWrapper struct {
+	decNaked
+	ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
+}
+
+func (n *unsafeDecNakedWrapper) init() {
+	n.ru = reflect.ValueOf(&n.u).Elem()
+	n.ri = reflect.ValueOf(&n.i).Elem()
+	n.rf = reflect.ValueOf(&n.f).Elem()
+	n.rl = reflect.ValueOf(&n.l).Elem()
+	n.rs = reflect.ValueOf(&n.s).Elem()
+	n.rt = reflect.ValueOf(&n.t).Elem()
+	n.rb = reflect.ValueOf(&n.b).Elem()
+	// n.rr[] = reflect.ValueOf(&n.)
+}
+
+var defUnsafeDecNakedWrapper unsafeDecNakedWrapper
+
+func init() {
+	defUnsafeDecNakedWrapper.init()
+}
+
+func (n *decNaked) ru() (v reflect.Value) {
+	v = defUnsafeDecNakedWrapper.ru
+	((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.u)
+	return
+}
+func (n *decNaked) ri() (v reflect.Value) {
+	v = defUnsafeDecNakedWrapper.ri
+	((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.i)
+	return
+}
+func (n *decNaked) rf() (v reflect.Value) {
+	v = defUnsafeDecNakedWrapper.rf
+	((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.f)
+	return
+}
+func (n *decNaked) rl() (v reflect.Value) {
+	v = defUnsafeDecNakedWrapper.rl
+	((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.l)
+	return
+}
+func (n *decNaked) rs() (v reflect.Value) {
+	v = defUnsafeDecNakedWrapper.rs
+	((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.s)
+	return
+}
+func (n *decNaked) rt() (v reflect.Value) {
+	v = defUnsafeDecNakedWrapper.rt
+	((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.t)
+	return
+}
+func (n *decNaked) rb() (v reflect.Value) {
+	v = defUnsafeDecNakedWrapper.rb
+	((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.b)
+	return
 }
 }
 
 
 // --------------------------
 // --------------------------
@@ -307,7 +408,7 @@ func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
 
 
 func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
 func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
 	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
 	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeString(cUTF8, *(*string)(v.ptr))
+	e.e.EncodeStringEnc(cUTF8, *(*string)(v.ptr))
 }
 }
 
 
 func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
 func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {

+ 151 - 66
vendor/github.com/ugorji/go/codec/json.go

@@ -46,8 +46,14 @@ const (
 	jsonLitTrue   = 1
 	jsonLitTrue   = 1
 	jsonLitFalseQ = 6
 	jsonLitFalseQ = 6
 	jsonLitFalse  = 7
 	jsonLitFalse  = 7
-	jsonLitNullQ  = 13
-	jsonLitNull   = 14
+	// jsonLitNullQ  = 13
+	jsonLitNull = 14
+)
+
+var (
+	jsonLiteral4True  = jsonLiterals[jsonLitTrue+1 : jsonLitTrue+4]
+	jsonLiteral4False = jsonLiterals[jsonLitFalse+1 : jsonLitFalse+5]
+	jsonLiteral4Null  = jsonLiterals[jsonLitNull+1 : jsonLitNull+4]
 )
 )
 
 
 const (
 const (
@@ -76,14 +82,15 @@ var (
 	// jsonTabs and jsonSpaces are used as caches for indents
 	// jsonTabs and jsonSpaces are used as caches for indents
 	jsonTabs, jsonSpaces [jsonSpacesOrTabsLen]byte
 	jsonTabs, jsonSpaces [jsonSpacesOrTabsLen]byte
 
 
-	jsonCharHtmlSafeSet   bitset128
-	jsonCharSafeSet       bitset128
+	jsonCharHtmlSafeSet   bitset256
+	jsonCharSafeSet       bitset256
 	jsonCharWhitespaceSet bitset256
 	jsonCharWhitespaceSet bitset256
 	jsonNumSet            bitset256
 	jsonNumSet            bitset256
 )
 )
 
 
 func init() {
 func init() {
-	for i := 0; i < jsonSpacesOrTabsLen; i++ {
+	var i byte
+	for i = 0; i < jsonSpacesOrTabsLen; i++ {
 		jsonSpaces[i] = ' '
 		jsonSpaces[i] = ' '
 		jsonTabs[i] = '\t'
 		jsonTabs[i] = '\t'
 	}
 	}
@@ -91,7 +98,6 @@ func init() {
 	// populate the safe values as true: note: ASCII control characters are (0-31)
 	// populate the safe values as true: note: ASCII control characters are (0-31)
 	// jsonCharSafeSet:     all true except (0-31) " \
 	// jsonCharSafeSet:     all true except (0-31) " \
 	// jsonCharHtmlSafeSet: all true except (0-31) " \ < > &
 	// jsonCharHtmlSafeSet: all true except (0-31) " \ < > &
-	var i byte
 	for i = 32; i < utf8.RuneSelf; i++ {
 	for i = 32; i < utf8.RuneSelf; i++ {
 		switch i {
 		switch i {
 		case '"', '\\':
 		case '"', '\\':
@@ -115,8 +121,7 @@ func init() {
 // ----------------
 // ----------------
 
 
 type jsonEncDriverTypical struct {
 type jsonEncDriverTypical struct {
-	w encWriter
-	// w  *encWriterSwitch
+	w  *encWriterSwitch
 	b  *[jsonScratchArrayLen]byte
 	b  *[jsonScratchArrayLen]byte
 	tw bool // term white space
 	tw bool // term white space
 	c  containerState
 	c  containerState
@@ -126,7 +131,6 @@ func (e *jsonEncDriverTypical) typical() {}
 
 
 func (e *jsonEncDriverTypical) reset(ee *jsonEncDriver) {
 func (e *jsonEncDriverTypical) reset(ee *jsonEncDriver) {
 	e.w = ee.ew
 	e.w = ee.ew
-	// e.w = &ee.e.encWriterSwitch
 	e.b = &ee.b
 	e.b = &ee.b
 	e.tw = ee.h.TermWhitespace
 	e.tw = ee.h.TermWhitespace
 	e.c = 0
 	e.c = 0
@@ -205,7 +209,7 @@ func (e *jsonEncDriverTypical) atEndOfEncode() {
 // ----------------
 // ----------------
 
 
 type jsonEncDriverGeneric struct {
 type jsonEncDriverGeneric struct {
-	w encWriter // encWriter // *encWriterSwitch
+	w *encWriterSwitch
 	b *[jsonScratchArrayLen]byte
 	b *[jsonScratchArrayLen]byte
 	c containerState
 	c containerState
 	// ds string // indent string
 	// ds string // indent string
@@ -407,12 +411,13 @@ type jsonEncDriver struct {
 	noBuiltInTypes
 	noBuiltInTypes
 	e  *Encoder
 	e  *Encoder
 	h  *JsonHandle
 	h  *JsonHandle
-	ew encWriter // encWriter // *encWriterSwitch
+	ew *encWriterSwitch
 	se extWrapper
 	se extWrapper
 	// ---- cpu cache line boundary?
 	// ---- cpu cache line boundary?
 	bs []byte // scratch
 	bs []byte // scratch
 	// ---- cpu cache line boundary?
 	// ---- cpu cache line boundary?
 	b [jsonScratchArrayLen]byte // scratch (encode time,
 	b [jsonScratchArrayLen]byte // scratch (encode time,
+	_ [2]uint64                 // padding
 }
 }
 
 
 func (e *jsonEncDriver) EncodeNil() {
 func (e *jsonEncDriver) EncodeNil() {
@@ -463,6 +468,10 @@ func (e *jsonEncDriver) EncodeString(c charEncoding, v string) {
 	e.quoteStr(v)
 	e.quoteStr(v)
 }
 }
 
 
+func (e *jsonEncDriver) EncodeStringEnc(c charEncoding, v string) {
+	e.quoteStr(v)
+}
+
 func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 	// if encoding raw bytes and RawBytesExt is configured, use it to encode
 	// if encoding raw bytes and RawBytesExt is configured, use it to encode
 	if v == nil {
 	if v == nil {
@@ -475,21 +484,44 @@ func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 			return
 			return
 		}
 		}
 
 
-		slen := base64.StdEncoding.EncodedLen(len(v))
-		if cap(e.bs) >= slen+2 {
-			e.bs = e.bs[:slen+2]
+		slen := base64.StdEncoding.EncodedLen(len(v)) + 2
+		if cap(e.bs) >= slen {
+			e.bs = e.bs[:slen]
 		} else {
 		} else {
-			e.bs = make([]byte, slen+2)
+			e.bs = make([]byte, slen)
 		}
 		}
 		e.bs[0] = '"'
 		e.bs[0] = '"'
 		base64.StdEncoding.Encode(e.bs[1:], v)
 		base64.StdEncoding.Encode(e.bs[1:], v)
-		e.bs[slen+1] = '"'
+		e.bs[slen-1] = '"'
 		e.ew.writeb(e.bs)
 		e.ew.writeb(e.bs)
 	} else {
 	} else {
 		e.quoteStr(stringView(v))
 		e.quoteStr(stringView(v))
 	}
 	}
 }
 }
 
 
+func (e *jsonEncDriver) EncodeStringBytesRaw(v []byte) {
+	// if encoding raw bytes and RawBytesExt is configured, use it to encode
+	if v == nil {
+		e.EncodeNil()
+		return
+	}
+	if e.se.InterfaceExt != nil {
+		e.EncodeExt(v, 0, &e.se, e.e)
+		return
+	}
+
+	slen := base64.StdEncoding.EncodedLen(len(v)) + 2
+	if cap(e.bs) >= slen {
+		e.bs = e.bs[:slen]
+	} else {
+		e.bs = make([]byte, slen)
+	}
+	e.bs[0] = '"'
+	base64.StdEncoding.Encode(e.bs[1:], v)
+	e.bs[slen-1] = '"'
+	e.ew.writeb(e.bs)
+}
+
 func (e *jsonEncDriver) EncodeAsis(v []byte) {
 func (e *jsonEncDriver) EncodeAsis(v []byte) {
 	e.ew.writeb(v)
 	e.ew.writeb(v)
 }
 }
@@ -569,7 +601,7 @@ type jsonDecDriver struct {
 	noBuiltInTypes
 	noBuiltInTypes
 	d  *Decoder
 	d  *Decoder
 	h  *JsonHandle
 	h  *JsonHandle
-	r  decReader // *decReaderSwitch // decReader
+	r  *decReaderSwitch
 	se extWrapper
 	se extWrapper
 
 
 	// ---- writable fields during execution --- *try* to keep in sep cache line
 	// ---- writable fields during execution --- *try* to keep in sep cache line
@@ -584,7 +616,7 @@ type jsonDecDriver struct {
 	b  [jsonScratchArrayLen]byte // scratch 1, used for parsing strings or numbers or time.Time
 	b  [jsonScratchArrayLen]byte // scratch 1, used for parsing strings or numbers or time.Time
 	b2 [jsonScratchArrayLen]byte // scratch 2, used only for readUntil, decNumBytes
 	b2 [jsonScratchArrayLen]byte // scratch 2, used only for readUntil, decNumBytes
 
 
-	_ [3]uint64 // padding
+	// _ [3]uint64 // padding
 	// n jsonNum
 	// n jsonNum
 }
 }
 
 
@@ -707,12 +739,36 @@ func (d *jsonDecDriver) ReadMapEnd() {
 	d.c = containerMapEnd
 	d.c = containerMapEnd
 }
 }
 
 
-func (d *jsonDecDriver) readLit(length, fromIdx uint8) {
-	bs := d.r.readx(int(length))
+// func (d *jsonDecDriver) readLit(length, fromIdx uint8) {
+// 	// length here is always less than 8 (literals are: null, true, false)
+// 	bs := d.r.readx(int(length))
+// 	d.tok = 0
+// 	if jsonValidateSymbols && !bytes.Equal(bs, jsonLiterals[fromIdx:fromIdx+length]) {
+// 		d.d.errorf("expecting %s: got %s", jsonLiterals[fromIdx:fromIdx+length], bs)
+// 	}
+// }
+
+func (d *jsonDecDriver) readLit4True() {
+	bs := d.r.readx(3)
 	d.tok = 0
 	d.tok = 0
-	if jsonValidateSymbols && !bytes.Equal(bs, jsonLiterals[fromIdx:fromIdx+length]) {
-		d.d.errorf("expecting %s: got %s", jsonLiterals[fromIdx:fromIdx+length], bs)
-		return
+	if jsonValidateSymbols && !bytes.Equal(bs, jsonLiteral4True) {
+		d.d.errorf("expecting %s: got %s", jsonLiteral4True, bs)
+	}
+}
+
+func (d *jsonDecDriver) readLit4False() {
+	bs := d.r.readx(4)
+	d.tok = 0
+	if jsonValidateSymbols && !bytes.Equal(bs, jsonLiteral4False) {
+		d.d.errorf("expecting %s: got %s", jsonLiteral4False, bs)
+	}
+}
+
+func (d *jsonDecDriver) readLit4Null() {
+	bs := d.r.readx(3)
+	d.tok = 0
+	if jsonValidateSymbols && !bytes.Equal(bs, jsonLiteral4Null) {
+		d.d.errorf("expecting %s: got %s", jsonLiteral4Null, bs)
 	}
 	}
 }
 }
 
 
@@ -723,7 +779,7 @@ func (d *jsonDecDriver) TryDecodeAsNil() bool {
 	// we shouldn't try to see if "null" was here, right?
 	// we shouldn't try to see if "null" was here, right?
 	// only the plain string: `null` denotes a nil (ie not quotes)
 	// only the plain string: `null` denotes a nil (ie not quotes)
 	if d.tok == 'n' {
 	if d.tok == 'n' {
-		d.readLit(3, jsonLitNull+1) // (n)ull
+		d.readLit4Null()
 		return true
 		return true
 	}
 	}
 	return false
 	return false
@@ -739,10 +795,10 @@ func (d *jsonDecDriver) DecodeBool() (v bool) {
 	}
 	}
 	switch d.tok {
 	switch d.tok {
 	case 'f':
 	case 'f':
-		d.readLit(4, jsonLitFalse+1) // (f)alse
+		d.readLit4False()
 		// v = false
 		// v = false
 	case 't':
 	case 't':
-		d.readLit(3, jsonLitTrue+1) // (t)rue
+		d.readLit4True()
 		v = true
 		v = true
 	default:
 	default:
 		d.d.errorf("decode bool: got first char %c", d.tok)
 		d.d.errorf("decode bool: got first char %c", d.tok)
@@ -808,6 +864,9 @@ func (d *jsonDecDriver) decNumBytes() (bs []byte) {
 
 
 func (d *jsonDecDriver) DecodeUint64() (u uint64) {
 func (d *jsonDecDriver) DecodeUint64() (u uint64) {
 	bs := d.decNumBytes()
 	bs := d.decNumBytes()
+	if len(bs) == 0 {
+		return
+	}
 	n, neg, badsyntax, overflow := jsonParseInteger(bs)
 	n, neg, badsyntax, overflow := jsonParseInteger(bs)
 	if overflow {
 	if overflow {
 		d.d.errorf("overflow parsing unsigned integer: %s", bs)
 		d.d.errorf("overflow parsing unsigned integer: %s", bs)
@@ -823,6 +882,9 @@ func (d *jsonDecDriver) DecodeUint64() (u uint64) {
 func (d *jsonDecDriver) DecodeInt64() (i int64) {
 func (d *jsonDecDriver) DecodeInt64() (i int64) {
 	const cutoff = uint64(1 << uint(64-1))
 	const cutoff = uint64(1 << uint(64-1))
 	bs := d.decNumBytes()
 	bs := d.decNumBytes()
+	if len(bs) == 0 {
+		return
+	}
 	n, neg, badsyntax, overflow := jsonParseInteger(bs)
 	n, neg, badsyntax, overflow := jsonParseInteger(bs)
 	if overflow {
 	if overflow {
 		d.d.errorf("overflow parsing integer: %s", bs)
 		d.d.errorf("overflow parsing integer: %s", bs)
@@ -850,6 +912,9 @@ func (d *jsonDecDriver) DecodeInt64() (i int64) {
 }
 }
 
 
 func (d *jsonDecDriver) decUint64ViaFloat(s string) (u uint64) {
 func (d *jsonDecDriver) decUint64ViaFloat(s string) (u uint64) {
+	if len(s) == 0 {
+		return
+	}
 	f, err := strconv.ParseFloat(s, 64)
 	f, err := strconv.ParseFloat(s, 64)
 	if err != nil {
 	if err != nil {
 		d.d.errorf("invalid syntax for integer: %s", s)
 		d.d.errorf("invalid syntax for integer: %s", s)
@@ -866,6 +931,9 @@ func (d *jsonDecDriver) decUint64ViaFloat(s string) (u uint64) {
 
 
 func (d *jsonDecDriver) DecodeFloat64() (f float64) {
 func (d *jsonDecDriver) DecodeFloat64() (f float64) {
 	bs := d.decNumBytes()
 	bs := d.decNumBytes()
+	if len(bs) == 0 {
+		return
+	}
 	f, err := strconv.ParseFloat(stringView(bs), 64)
 	f, err := strconv.ParseFloat(stringView(bs), 64)
 	if err != nil {
 	if err != nil {
 		d.d.errorv(err)
 		d.d.errorv(err)
@@ -953,15 +1021,15 @@ func (d *jsonDecDriver) appendStringAsBytes() {
 		// handle non-string scalar: null, true, false or a number
 		// handle non-string scalar: null, true, false or a number
 		switch d.tok {
 		switch d.tok {
 		case 'n':
 		case 'n':
-			d.readLit(3, jsonLitNull+1) // (n)ull
+			d.readLit4Null()
 			d.bs = d.bs[:0]
 			d.bs = d.bs[:0]
 			d.fnull = true
 			d.fnull = true
 		case 'f':
 		case 'f':
-			d.readLit(4, jsonLitFalse+1) // (f)alse
+			d.readLit4False()
 			d.bs = d.bs[:5]
 			d.bs = d.bs[:5]
 			copy(d.bs, "false")
 			copy(d.bs, "false")
 		case 't':
 		case 't':
-			d.readLit(3, jsonLitTrue+1) // (t)rue
+			d.readLit4True()
 			d.bs = d.bs[:4]
 			d.bs = d.bs[:4]
 			copy(d.bs, "true")
 			copy(d.bs, "true")
 		default:
 		default:
@@ -980,7 +1048,7 @@ func (d *jsonDecDriver) appendStringAsBytes() {
 	d.tok = 0
 	d.tok = 0
 	r := d.r
 	r := d.r
 	var cs = r.readUntil(d.b2[:0], '"')
 	var cs = r.readUntil(d.b2[:0], '"')
-	var cslen = len(cs)
+	var cslen = uint(len(cs))
 	var c uint8
 	var c uint8
 	v := d.bs[:0]
 	v := d.bs[:0]
 	// append on each byte seen can be expensive, so we just
 	// append on each byte seen can be expensive, so we just
@@ -989,11 +1057,12 @@ func (d *jsonDecDriver) appendStringAsBytes() {
 	// and when we see a special byte
 	// and when we see a special byte
 	// e.g. end-of-slice, " or \,
 	// e.g. end-of-slice, " or \,
 	// we will append the full range into the v slice before proceeding
 	// we will append the full range into the v slice before proceeding
-	for i, cursor := 0, 0; ; {
+	var i, cursor uint
+	for {
 		if i == cslen {
 		if i == cslen {
 			v = append(v, cs[cursor:]...)
 			v = append(v, cs[cursor:]...)
 			cs = r.readUntil(d.b2[:0], '"')
 			cs = r.readUntil(d.b2[:0], '"')
-			cslen = len(cs)
+			cslen = uint(len(cs))
 			i, cursor = 0, 0
 			i, cursor = 0, 0
 		}
 		}
 		c = cs[i]
 		c = cs[i]
@@ -1024,14 +1093,13 @@ func (d *jsonDecDriver) appendStringAsBytes() {
 		case 'u':
 		case 'u':
 			var r rune
 			var r rune
 			var rr uint32
 			var rr uint32
-			if len(cs) < i+4 { // may help reduce bounds-checking
+			if cslen < i+4 {
 				d.d.errorf("need at least 4 more bytes for unicode sequence")
 				d.d.errorf("need at least 4 more bytes for unicode sequence")
 			}
 			}
-			// c = cs[i+4] // may help reduce bounds-checking
-			for j := 1; j < 5; j++ {
+			var j uint
+			for _, c = range cs[i+1 : i+5] { // bounds-check-elimination
 				// best to use explicit if-else
 				// best to use explicit if-else
 				// - not a table, etc which involve memory loads, array lookup with bounds checks, etc
 				// - not a table, etc which involve memory loads, array lookup with bounds checks, etc
-				c = cs[i+j]
 				if c >= '0' && c <= '9' {
 				if c >= '0' && c <= '9' {
 					rr = rr*16 + uint32(c-jsonU4Chk2)
 					rr = rr*16 + uint32(c-jsonU4Chk2)
 				} else if c >= 'a' && c <= 'f' {
 				} else if c >= 'a' && c <= 'f' {
@@ -1047,30 +1115,31 @@ func (d *jsonDecDriver) appendStringAsBytes() {
 			r = rune(rr)
 			r = rune(rr)
 			i += 4
 			i += 4
 			if utf16.IsSurrogate(r) {
 			if utf16.IsSurrogate(r) {
-				if len(cs) >= i+6 && cs[i+2] == 'u' && cs[i+1] == '\\' {
-					i += 2
-					// c = cs[i+4] // may help reduce bounds-checking
-					var rr1 uint32
-					for j := 1; j < 5; j++ {
-						c = cs[i+j]
-						if c >= '0' && c <= '9' {
-							rr = rr*16 + uint32(c-jsonU4Chk2)
-						} else if c >= 'a' && c <= 'f' {
-							rr = rr*16 + uint32(c-jsonU4Chk1)
-						} else if c >= 'A' && c <= 'F' {
-							rr = rr*16 + uint32(c-jsonU4Chk0)
-						} else {
-							r = unicode.ReplacementChar
-							i += 4
-							goto encode_rune
+				if len(cs) >= int(i+6) {
+					var cx = cs[i+1:][:6:6] // [:6] affords bounds-check-elimination
+					if cx[0] == '\\' && cx[1] == 'u' {
+						i += 2
+						var rr1 uint32
+						for j = 2; j < 6; j++ {
+							c = cx[j]
+							if c >= '0' && c <= '9' {
+								rr = rr*16 + uint32(c-jsonU4Chk2)
+							} else if c >= 'a' && c <= 'f' {
+								rr = rr*16 + uint32(c-jsonU4Chk1)
+							} else if c >= 'A' && c <= 'F' {
+								rr = rr*16 + uint32(c-jsonU4Chk0)
+							} else {
+								r = unicode.ReplacementChar
+								i += 4
+								goto encode_rune
+							}
 						}
 						}
+						r = utf16.DecodeRune(r, rune(rr1))
+						i += 4
+						goto encode_rune
 					}
 					}
-					r = utf16.DecodeRune(r, rune(rr1))
-					i += 4
-				} else {
-					r = unicode.ReplacementChar
-					goto encode_rune
 				}
 				}
+				r = unicode.ReplacementChar
 			}
 			}
 		encode_rune:
 		encode_rune:
 			w2 := utf8.EncodeRune(d.bstr[:], r)
 			w2 := utf8.EncodeRune(d.bstr[:], r)
@@ -1086,9 +1155,23 @@ func (d *jsonDecDriver) appendStringAsBytes() {
 
 
 func (d *jsonDecDriver) nakedNum(z *decNaked, bs []byte) (err error) {
 func (d *jsonDecDriver) nakedNum(z *decNaked, bs []byte) (err error) {
 	const cutoff = uint64(1 << uint(64-1))
 	const cutoff = uint64(1 << uint(64-1))
+
 	var n uint64
 	var n uint64
 	var neg, badsyntax, overflow bool
 	var neg, badsyntax, overflow bool
 
 
+	if len(bs) == 0 {
+		if d.h.PreferFloat {
+			z.v = valueTypeFloat
+			z.f = 0
+		} else if d.h.SignedInteger {
+			z.v = valueTypeInt
+			z.i = 0
+		} else {
+			z.v = valueTypeUint
+			z.u = 0
+		}
+		return
+	}
 	if d.h.PreferFloat {
 	if d.h.PreferFloat {
 		goto F
 		goto F
 	}
 	}
@@ -1128,7 +1211,7 @@ func (d *jsonDecDriver) bsToString() string {
 }
 }
 
 
 func (d *jsonDecDriver) DecodeNaked() {
 func (d *jsonDecDriver) DecodeNaked() {
-	z := d.d.n
+	z := d.d.naked()
 	// var decodeFurther bool
 	// var decodeFurther bool
 
 
 	if d.tok == 0 {
 	if d.tok == 0 {
@@ -1136,14 +1219,14 @@ func (d *jsonDecDriver) DecodeNaked() {
 	}
 	}
 	switch d.tok {
 	switch d.tok {
 	case 'n':
 	case 'n':
-		d.readLit(3, jsonLitNull+1) // (n)ull
+		d.readLit4Null()
 		z.v = valueTypeNil
 		z.v = valueTypeNil
 	case 'f':
 	case 'f':
-		d.readLit(4, jsonLitFalse+1) // (f)alse
+		d.readLit4False()
 		z.v = valueTypeBool
 		z.v = valueTypeBool
 		z.b = false
 		z.b = false
 	case 't':
 	case 't':
-		d.readLit(3, jsonLitTrue+1) // (t)rue
+		d.readLit4True()
 		z.v = valueTypeBool
 		z.v = valueTypeBool
 		z.b = true
 		z.b = true
 	case '{':
 	case '{':
@@ -1188,7 +1271,6 @@ func (d *jsonDecDriver) DecodeNaked() {
 	// if decodeFurther {
 	// if decodeFurther {
 	// 	d.s.sc.retryRead()
 	// 	d.s.sc.retryRead()
 	// }
 	// }
-	return
 }
 }
 
 
 //----------------------
 //----------------------
@@ -1306,6 +1388,7 @@ func (x *jsonEncDriverTypicalImpl) reset() {
 type jsonEncDriverGenericImpl struct {
 type jsonEncDriverGenericImpl struct {
 	jsonEncDriver
 	jsonEncDriver
 	jsonEncDriverGeneric
 	jsonEncDriverGeneric
+	// _ [2]uint64 // padding
 }
 }
 
 
 func (x *jsonEncDriverGenericImpl) reset() {
 func (x *jsonEncDriverGenericImpl) reset() {
@@ -1340,7 +1423,7 @@ func (h *JsonHandle) newDecDriver(d *Decoder) decDriver {
 }
 }
 
 
 func (e *jsonEncDriver) reset() {
 func (e *jsonEncDriver) reset() {
-	e.ew = e.e.w // e.e.w // &e.e.encWriterSwitch
+	e.ew = e.e.w
 	e.se.InterfaceExt = e.h.RawBytesExt
 	e.se.InterfaceExt = e.h.RawBytesExt
 	if e.bs != nil {
 	if e.bs != nil {
 		e.bs = e.bs[:0]
 		e.bs = e.bs[:0]
@@ -1348,7 +1431,7 @@ func (e *jsonEncDriver) reset() {
 }
 }
 
 
 func (d *jsonDecDriver) reset() {
 func (d *jsonDecDriver) reset() {
-	d.r = d.d.r // &d.d.decReaderSwitch // d.d.r
+	d.r = d.d.r
 	d.se.InterfaceExt = d.h.RawBytesExt
 	d.se.InterfaceExt = d.h.RawBytesExt
 	if d.bs != nil {
 	if d.bs != nil {
 		d.bs = d.bs[:0]
 		d.bs = d.bs[:0]
@@ -1380,12 +1463,14 @@ func jsonFloatStrconvFmtPrec(f float64) (fmt byte, prec int) {
 
 
 // custom-fitted version of strconv.Parse(Ui|I)nt.
 // custom-fitted version of strconv.Parse(Ui|I)nt.
 // Also ensures we don't have to search for .eE to determine if a float or not.
 // Also ensures we don't have to search for .eE to determine if a float or not.
+// Note: s CANNOT be a zero-length slice.
 func jsonParseInteger(s []byte) (n uint64, neg, badSyntax, overflow bool) {
 func jsonParseInteger(s []byte) (n uint64, neg, badSyntax, overflow bool) {
 	const maxUint64 = (1<<64 - 1)
 	const maxUint64 = (1<<64 - 1)
 	const cutoff = maxUint64/10 + 1
 	const cutoff = maxUint64/10 + 1
 
 
-	if len(s) == 0 {
-		badSyntax = true
+	if len(s) == 0 { // bounds-check-elimination
+		// treat empty string as zero value
+		// badSyntax = true
 		return
 		return
 	}
 	}
 	switch s[0] {
 	switch s[0] {

+ 91 - 60
vendor/github.com/ugorji/go/codec/msgpack.go

@@ -30,53 +30,53 @@ import (
 
 
 const (
 const (
 	mpPosFixNumMin byte = 0x00
 	mpPosFixNumMin byte = 0x00
-	mpPosFixNumMax      = 0x7f
-	mpFixMapMin         = 0x80
-	mpFixMapMax         = 0x8f
-	mpFixArrayMin       = 0x90
-	mpFixArrayMax       = 0x9f
-	mpFixStrMin         = 0xa0
-	mpFixStrMax         = 0xbf
-	mpNil               = 0xc0
-	_                   = 0xc1
-	mpFalse             = 0xc2
-	mpTrue              = 0xc3
-	mpFloat             = 0xca
-	mpDouble            = 0xcb
-	mpUint8             = 0xcc
-	mpUint16            = 0xcd
-	mpUint32            = 0xce
-	mpUint64            = 0xcf
-	mpInt8              = 0xd0
-	mpInt16             = 0xd1
-	mpInt32             = 0xd2
-	mpInt64             = 0xd3
+	mpPosFixNumMax byte = 0x7f
+	mpFixMapMin    byte = 0x80
+	mpFixMapMax    byte = 0x8f
+	mpFixArrayMin  byte = 0x90
+	mpFixArrayMax  byte = 0x9f
+	mpFixStrMin    byte = 0xa0
+	mpFixStrMax    byte = 0xbf
+	mpNil          byte = 0xc0
+	_              byte = 0xc1
+	mpFalse        byte = 0xc2
+	mpTrue         byte = 0xc3
+	mpFloat        byte = 0xca
+	mpDouble       byte = 0xcb
+	mpUint8        byte = 0xcc
+	mpUint16       byte = 0xcd
+	mpUint32       byte = 0xce
+	mpUint64       byte = 0xcf
+	mpInt8         byte = 0xd0
+	mpInt16        byte = 0xd1
+	mpInt32        byte = 0xd2
+	mpInt64        byte = 0xd3
 
 
 	// extensions below
 	// extensions below
-	mpBin8     = 0xc4
-	mpBin16    = 0xc5
-	mpBin32    = 0xc6
-	mpExt8     = 0xc7
-	mpExt16    = 0xc8
-	mpExt32    = 0xc9
-	mpFixExt1  = 0xd4
-	mpFixExt2  = 0xd5
-	mpFixExt4  = 0xd6
-	mpFixExt8  = 0xd7
-	mpFixExt16 = 0xd8
-
-	mpStr8  = 0xd9 // new
-	mpStr16 = 0xda
-	mpStr32 = 0xdb
-
-	mpArray16 = 0xdc
-	mpArray32 = 0xdd
-
-	mpMap16 = 0xde
-	mpMap32 = 0xdf
-
-	mpNegFixNumMin = 0xe0
-	mpNegFixNumMax = 0xff
+	mpBin8     byte = 0xc4
+	mpBin16    byte = 0xc5
+	mpBin32    byte = 0xc6
+	mpExt8     byte = 0xc7
+	mpExt16    byte = 0xc8
+	mpExt32    byte = 0xc9
+	mpFixExt1  byte = 0xd4
+	mpFixExt2  byte = 0xd5
+	mpFixExt4  byte = 0xd6
+	mpFixExt8  byte = 0xd7
+	mpFixExt16 byte = 0xd8
+
+	mpStr8  byte = 0xd9 // new
+	mpStr16 byte = 0xda
+	mpStr32 byte = 0xdb
+
+	mpArray16 byte = 0xdc
+	mpArray32 byte = 0xdd
+
+	mpMap16 byte = 0xde
+	mpMap32 byte = 0xdf
+
+	mpNegFixNumMin byte = 0xe0
+	mpNegFixNumMax byte = 0xff
 )
 )
 
 
 var mpTimeExtTag int8 = -1
 var mpTimeExtTag int8 = -1
@@ -199,10 +199,10 @@ type msgpackEncDriver struct {
 	encDriverNoopContainerWriter
 	encDriverNoopContainerWriter
 	// encNoSeparator
 	// encNoSeparator
 	e *Encoder
 	e *Encoder
-	w encWriter
+	w *encWriterSwitch
 	h *MsgpackHandle
 	h *MsgpackHandle
 	x [8]byte
 	x [8]byte
-	_ [3]uint64 // padding
+	// _ [3]uint64 // padding
 }
 }
 
 
 func (e *msgpackEncDriver) EncodeNil() {
 func (e *msgpackEncDriver) EncodeNil() {
@@ -210,10 +210,9 @@ func (e *msgpackEncDriver) EncodeNil() {
 }
 }
 
 
 func (e *msgpackEncDriver) EncodeInt(i int64) {
 func (e *msgpackEncDriver) EncodeInt(i int64) {
-	// if i >= 0 {
-	// 	e.EncodeUint(uint64(i))
-	// } else if false &&
-	if i > math.MaxInt8 {
+	if e.h.PositiveIntUnsigned && i >= 0 {
+		e.EncodeUint(uint64(i))
+	} else if i > math.MaxInt8 {
 		if i <= math.MaxInt16 {
 		if i <= math.MaxInt16 {
 			e.w.writen1(mpInt16)
 			e.w.writen1(mpInt16)
 			bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
 			bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
@@ -326,7 +325,7 @@ func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Enc
 		e.encodeExtPreamble(uint8(xtag), len(bs))
 		e.encodeExtPreamble(uint8(xtag), len(bs))
 		e.w.writeb(bs)
 		e.w.writeb(bs)
 	} else {
 	} else {
-		e.EncodeStringBytes(cRAW, bs)
+		e.EncodeStringBytesRaw(bs)
 	}
 	}
 }
 }
 
 
@@ -380,6 +379,14 @@ func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
 	}
 	}
 }
 }
 
 
+func (e *msgpackEncDriver) EncodeStringEnc(c charEncoding, s string) {
+	slen := len(s)
+	e.writeContainerLen(msgpackContainerStr, slen)
+	if slen > 0 {
+		e.w.writestr(s)
+	}
+}
+
 func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
 func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
 	if bs == nil {
 	if bs == nil {
 		e.EncodeNil()
 		e.EncodeNil()
@@ -396,6 +403,22 @@ func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
 	}
 	}
 }
 }
 
 
+func (e *msgpackEncDriver) EncodeStringBytesRaw(bs []byte) {
+	if bs == nil {
+		e.EncodeNil()
+		return
+	}
+	slen := len(bs)
+	if e.h.WriteExt {
+		e.writeContainerLen(msgpackContainerBin, slen)
+	} else {
+		e.writeContainerLen(msgpackContainerStr, slen)
+	}
+	if slen > 0 {
+		e.w.writeb(bs)
+	}
+}
+
 func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) {
 func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) {
 	if ct.hasFixMin && l < ct.fixCutoff {
 	if ct.hasFixMin && l < ct.fixCutoff {
 		e.w.writen1(ct.bFixMin | byte(l))
 		e.w.writen1(ct.bFixMin | byte(l))
@@ -414,7 +437,7 @@ func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) {
 
 
 type msgpackDecDriver struct {
 type msgpackDecDriver struct {
 	d *Decoder
 	d *Decoder
-	r decReader // *Decoder decReader decReaderT
+	r *decReaderSwitch
 	h *MsgpackHandle
 	h *MsgpackHandle
 	// b      [scratchByteArrayLen]byte
 	// b      [scratchByteArrayLen]byte
 	bd     byte
 	bd     byte
@@ -424,7 +447,7 @@ type msgpackDecDriver struct {
 	// noStreamingCodec
 	// noStreamingCodec
 	// decNoSeparator
 	// decNoSeparator
 	decDriverNoopContainerReader
 	decDriverNoopContainerReader
-	_ [3]uint64 // padding
+	// _ [3]uint64 // padding
 }
 }
 
 
 // Note: This returns either a primitive (int, bool, etc) for non-containers,
 // Note: This returns either a primitive (int, bool, etc) for non-containers,
@@ -437,7 +460,7 @@ func (d *msgpackDecDriver) DecodeNaked() {
 		d.readNextBd()
 		d.readNextBd()
 	}
 	}
 	bd := d.bd
 	bd := d.bd
-	n := d.d.n
+	n := d.d.naked()
 	var decodeFurther bool
 	var decodeFurther bool
 
 
 	switch bd {
 	switch bd {
@@ -518,8 +541,10 @@ func (d *msgpackDecDriver) DecodeNaked() {
 			if n.u == uint64(mpTimeExtTagU) {
 			if n.u == uint64(mpTimeExtTagU) {
 				n.v = valueTypeTime
 				n.v = valueTypeTime
 				n.t = d.decodeTime(clen)
 				n.t = d.decodeTime(clen)
+			} else if d.br {
+				n.l = d.r.readx(uint(clen))
 			} else {
 			} else {
-				n.l = d.r.readx(clen)
+				n.l = decByteSlice(d.r, clen, d.d.h.MaxInitLen, d.d.b[:])
 			}
 			}
 		default:
 		default:
 			d.d.errorf("cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd))
 			d.d.errorf("cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd))
@@ -532,7 +557,6 @@ func (d *msgpackDecDriver) DecodeNaked() {
 		n.v = valueTypeInt
 		n.v = valueTypeInt
 		n.i = int64(n.u)
 		n.i = int64(n.u)
 	}
 	}
-	return
 }
 }
 
 
 // int can be decoded from msgpack type: intXXX or uintXXX
 // int can be decoded from msgpack type: intXXX or uintXXX
@@ -702,7 +726,7 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
 	}
 	}
 	if zerocopy {
 	if zerocopy {
 		if d.br {
 		if d.br {
-			return d.r.readx(clen)
+			return d.r.readx(uint(clen))
 		} else if len(bs) == 0 {
 		} else if len(bs) == 0 {
 			bs = d.d.b[:]
 			bs = d.d.b[:]
 		}
 		}
@@ -912,7 +936,11 @@ func (d *msgpackDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs
 			d.d.errorf("wrong extension tag - got %b, expecting %v", xtag, tag)
 			d.d.errorf("wrong extension tag - got %b, expecting %v", xtag, tag)
 			return
 			return
 		}
 		}
-		xbs = d.r.readx(clen)
+		if d.br {
+			xbs = d.r.readx(uint(clen))
+		} else {
+			xbs = decByteSlice(d.r, clen, d.d.h.MaxInitLen, d.d.b[:])
+		}
 	}
 	}
 	d.bdRead = false
 	d.bdRead = false
 	return
 	return
@@ -942,6 +970,9 @@ type MsgpackHandle struct {
 	// a []byte or string based on the setting of RawToString.
 	// a []byte or string based on the setting of RawToString.
 	WriteExt bool
 	WriteExt bool
 
 
+	// PositiveIntUnsigned says to encode positive integers as unsigned.
+	PositiveIntUnsigned bool
+
 	binaryEncodingType
 	binaryEncodingType
 	noElemSeparators
 	noElemSeparators
 
 
@@ -1023,7 +1054,7 @@ func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error {
 }
 }
 
 
 func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
 func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
-	if c.isClosed() {
+	if cls := c.cls.load(); cls.closed {
 		return io.EOF
 		return io.EOF
 	}
 	}
 
 

+ 26 - 33
vendor/github.com/ugorji/go/codec/rpc.go

@@ -8,9 +8,10 @@ import (
 	"errors"
 	"errors"
 	"io"
 	"io"
 	"net/rpc"
 	"net/rpc"
-	"sync"
 )
 )
 
 
+var errRpcJsonNeedsTermWhitespace = errors.New("rpc requires JsonHandle with TermWhitespace=true")
+
 // Rpc provides a rpc Server or Client Codec for rpc communication.
 // Rpc provides a rpc Server or Client Codec for rpc communication.
 type Rpc interface {
 type Rpc interface {
 	ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec
 	ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec
@@ -38,12 +39,9 @@ type rpcCodec struct {
 	enc *Encoder
 	enc *Encoder
 	// bw  *bufio.Writer
 	// bw  *bufio.Writer
 	// br  *bufio.Reader
 	// br  *bufio.Reader
-	mu sync.Mutex
-	h  Handle
+	h Handle
 
 
-	cls    bool
-	clsmu  sync.RWMutex
-	clsErr error
+	cls atomicClsErr
 }
 }
 
 
 func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
 func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
@@ -54,12 +52,12 @@ func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
 func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
 func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
 	// defensive: ensure that jsonH has TermWhitespace turned on.
 	// defensive: ensure that jsonH has TermWhitespace turned on.
 	if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
 	if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
-		panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true"))
+		panic(errRpcJsonNeedsTermWhitespace)
 	}
 	}
 	// always ensure that we use a flusher, and always flush what was written to the connection.
 	// always ensure that we use a flusher, and always flush what was written to the connection.
 	// we lose nothing by using a buffered writer internally.
 	// we lose nothing by using a buffered writer internally.
 	f, ok := w.(ioFlusher)
 	f, ok := w.(ioFlusher)
-	bh := h.getBasicHandle()
+	bh := basicHandle(h)
 	if !bh.RPCNoBuffer {
 	if !bh.RPCNoBuffer {
 		if bh.WriterBufferSize <= 0 {
 		if bh.WriterBufferSize <= 0 {
 			if !ok {
 			if !ok {
@@ -88,8 +86,11 @@ func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
 }
 }
 
 
 func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
 func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
-	if c.isClosed() {
-		return c.clsErr
+	if c.c != nil {
+		cls := c.cls.load()
+		if cls.closed {
+			return cls.errClosed
+		}
 	}
 	}
 	err = c.enc.Encode(obj1)
 	err = c.enc.Encode(obj1)
 	if err == nil {
 	if err == nil {
@@ -116,8 +117,11 @@ func (c *rpcCodec) swallow(err *error) {
 }
 }
 
 
 func (c *rpcCodec) read(obj interface{}) (err error) {
 func (c *rpcCodec) read(obj interface{}) (err error) {
-	if c.isClosed() {
-		return c.clsErr
+	if c.c != nil {
+		cls := c.cls.load()
+		if cls.closed {
+			return cls.errClosed
+		}
 	}
 	}
 	//If nil is passed in, we should read and discard
 	//If nil is passed in, we should read and discard
 	if obj == nil {
 	if obj == nil {
@@ -129,24 +133,18 @@ func (c *rpcCodec) read(obj interface{}) (err error) {
 	return c.dec.Decode(obj)
 	return c.dec.Decode(obj)
 }
 }
 
 
-func (c *rpcCodec) isClosed() (b bool) {
-	if c.c != nil {
-		c.clsmu.RLock()
-		b = c.cls
-		c.clsmu.RUnlock()
-	}
-	return
-}
-
 func (c *rpcCodec) Close() error {
 func (c *rpcCodec) Close() error {
-	if c.c == nil || c.isClosed() {
-		return c.clsErr
+	if c.c == nil {
+		return nil
+	}
+	cls := c.cls.load()
+	if cls.closed {
+		return cls.errClosed
 	}
 	}
-	c.clsmu.Lock()
-	c.cls = true
-	c.clsErr = c.c.Close()
-	c.clsmu.Unlock()
-	return c.clsErr
+	cls.errClosed = c.c.Close()
+	cls.closed = true
+	c.cls.store(cls)
+	return cls.errClosed
 }
 }
 
 
 func (c *rpcCodec) ReadResponseBody(body interface{}) error {
 func (c *rpcCodec) ReadResponseBody(body interface{}) error {
@@ -160,15 +158,10 @@ type goRpcCodec struct {
 }
 }
 
 
 func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
 func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
-	// Must protect for concurrent access as per API
-	c.mu.Lock()
-	defer c.mu.Unlock()
 	return c.write(r, body, true)
 	return c.write(r, body, true)
 }
 }
 
 
 func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
 func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
-	c.mu.Lock()
-	defer c.mu.Unlock()
 	return c.write(r, body, true)
 	return c.write(r, body, true)
 }
 }
 
 

+ 29 - 14
vendor/github.com/ugorji/go/codec/simple.go

@@ -36,12 +36,12 @@ type simpleEncDriver struct {
 	// encNoSeparator
 	// encNoSeparator
 	e *Encoder
 	e *Encoder
 	h *SimpleHandle
 	h *SimpleHandle
-	w encWriter
+	w *encWriterSwitch
 	b [8]byte
 	b [8]byte
 	// c containerState
 	// c containerState
 	encDriverTrackContainerWriter
 	encDriverTrackContainerWriter
 	// encDriverNoopContainerWriter
 	// encDriverNoopContainerWriter
-	_ [2]uint64 // padding
+	_ [3]uint64 // padding
 }
 }
 
 
 func (e *simpleEncDriver) EncodeNil() {
 func (e *simpleEncDriver) EncodeNil() {
@@ -157,7 +157,11 @@ func (e *simpleEncDriver) WriteMapStart(length int) {
 	e.encLen(simpleVdMap, length)
 	e.encLen(simpleVdMap, length)
 }
 }
 
 
-func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
+// func (e *simpleEncDriver) EncodeSymbol(v string) {
+// 	e.EncodeString(cUTF8, v)
+// }
+
+func (e *simpleEncDriver) EncodeStringEnc(c charEncoding, v string) {
 	if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" {
 	if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" {
 		e.EncodeNil()
 		e.EncodeNil()
 		return
 		return
@@ -166,11 +170,15 @@ func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
 	e.w.writestr(v)
 	e.w.writestr(v)
 }
 }
 
 
-// func (e *simpleEncDriver) EncodeSymbol(v string) {
-// 	e.EncodeString(cUTF8, v)
-// }
+func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
+	e.EncodeStringEnc(c, v)
+}
 
 
 func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
 func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
+	e.EncodeStringBytesRaw(v)
+}
+
+func (e *simpleEncDriver) EncodeStringBytesRaw(v []byte) {
 	// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
 	// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
 	if v == nil {
 	if v == nil {
 		e.EncodeNil()
 		e.EncodeNil()
@@ -201,7 +209,7 @@ func (e *simpleEncDriver) EncodeTime(t time.Time) {
 type simpleDecDriver struct {
 type simpleDecDriver struct {
 	d      *Decoder
 	d      *Decoder
 	h      *SimpleHandle
 	h      *SimpleHandle
-	r      decReader
+	r      *decReaderSwitch
 	bdRead bool
 	bdRead bool
 	bd     byte
 	bd     byte
 	br     bool // a bytes reader?
 	br     bool // a bytes reader?
@@ -210,7 +218,7 @@ type simpleDecDriver struct {
 	noBuiltInTypes
 	noBuiltInTypes
 	// noStreamingCodec
 	// noStreamingCodec
 	decDriverNoopContainerReader
 	decDriverNoopContainerReader
-	_ [3]uint64 // padding
+	// _ [3]uint64 // padding
 }
 }
 
 
 func (d *simpleDecDriver) readNextBd() {
 func (d *simpleDecDriver) readNextBd() {
@@ -451,7 +459,7 @@ func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
 	d.bdRead = false
 	d.bdRead = false
 	if zerocopy {
 	if zerocopy {
 		if d.br {
 		if d.br {
-			return d.r.readx(clen)
+			return d.r.readx(uint(clen))
 		} else if len(bs) == 0 {
 		} else if len(bs) == 0 {
 			bs = d.d.b[:]
 			bs = d.d.b[:]
 		}
 		}
@@ -473,7 +481,7 @@ func (d *simpleDecDriver) DecodeTime() (t time.Time) {
 	}
 	}
 	d.bdRead = false
 	d.bdRead = false
 	clen := int(d.r.readn1())
 	clen := int(d.r.readn1())
-	b := d.r.readx(clen)
+	b := d.r.readx(uint(clen))
 	if err := (&t).UnmarshalBinary(b); err != nil {
 	if err := (&t).UnmarshalBinary(b); err != nil {
 		d.d.errorv(err)
 		d.d.errorv(err)
 	}
 	}
@@ -509,7 +517,11 @@ func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs [
 			d.d.errorf("wrong extension tag. Got %b. Expecting: %v", xtag, tag)
 			d.d.errorf("wrong extension tag. Got %b. Expecting: %v", xtag, tag)
 			return
 			return
 		}
 		}
-		xbs = d.r.readx(l)
+		if d.br {
+			xbs = d.r.readx(uint(l))
+		} else {
+			xbs = decByteSlice(d.r, l, d.d.h.MaxInitLen, d.d.b[:])
+		}
 	case simpleVdByteArray, simpleVdByteArray + 1,
 	case simpleVdByteArray, simpleVdByteArray + 1,
 		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
 		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
 		xbs = d.DecodeBytes(nil, true)
 		xbs = d.DecodeBytes(nil, true)
@@ -526,7 +538,7 @@ func (d *simpleDecDriver) DecodeNaked() {
 		d.readNextBd()
 		d.readNextBd()
 	}
 	}
 
 
-	n := d.d.n
+	n := d.d.naked()
 	var decodeFurther bool
 	var decodeFurther bool
 
 
 	switch d.bd {
 	switch d.bd {
@@ -570,7 +582,11 @@ func (d *simpleDecDriver) DecodeNaked() {
 		n.v = valueTypeExt
 		n.v = valueTypeExt
 		l := d.decLen()
 		l := d.decLen()
 		n.u = uint64(d.r.readn1())
 		n.u = uint64(d.r.readn1())
-		n.l = d.r.readx(l)
+		if d.br {
+			n.l = d.r.readx(uint(l))
+		} else {
+			n.l = decByteSlice(d.r, l, d.d.h.MaxInitLen, d.d.b[:])
+		}
 	case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
 	case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
 		simpleVdArray + 3, simpleVdArray + 4:
 		simpleVdArray + 3, simpleVdArray + 4:
 		n.v = valueTypeArray
 		n.v = valueTypeArray
@@ -585,7 +601,6 @@ func (d *simpleDecDriver) DecodeNaked() {
 	if !decodeFurther {
 	if !decodeFurther {
 		d.bdRead = false
 		d.bdRead = false
 	}
 	}
-	return
 }
 }
 
 
 //------------------------------------
 //------------------------------------

+ 63 - 65
vendor/github.com/urfave/cli/app.go

@@ -6,9 +6,7 @@ import (
 	"io/ioutil"
 	"io/ioutil"
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
-	"reflect"
 	"sort"
 	"sort"
-	"strings"
 	"time"
 	"time"
 )
 )
 
 
@@ -19,11 +17,8 @@ var (
 
 
 	contactSysadmin = "This is an error in the application.  Please contact the distributor of this application if this is not you."
 	contactSysadmin = "This is an error in the application.  Please contact the distributor of this application if this is not you."
 
 
-	errNonFuncAction = NewExitError("ERROR invalid Action type.  "+
-		fmt.Sprintf("Must be a func of type `cli.ActionFunc`.  %s", contactSysadmin)+
-		fmt.Sprintf("See %s", appActionDeprecationURL), 2)
-	errInvalidActionSignature = NewExitError("ERROR invalid Action signature.  "+
-		fmt.Sprintf("Must be `cli.ActionFunc`.  %s", contactSysadmin)+
+	errInvalidActionType = NewExitError("ERROR invalid Action type. "+
+		fmt.Sprintf("Must be `func(*Context`)` or `func(*Context) error).  %s", contactSysadmin)+
 		fmt.Sprintf("See %s", appActionDeprecationURL), 2)
 		fmt.Sprintf("See %s", appActionDeprecationURL), 2)
 )
 )
 
 
@@ -42,6 +37,8 @@ type App struct {
 	ArgsUsage string
 	ArgsUsage string
 	// Version of the program
 	// Version of the program
 	Version string
 	Version string
+	// Description of the program
+	Description string
 	// List of commands to execute
 	// List of commands to execute
 	Commands []Command
 	Commands []Command
 	// List of flags to parse
 	// List of flags to parse
@@ -62,10 +59,11 @@ type App struct {
 	// An action to execute after any subcommands are run, but after the subcommand has finished
 	// An action to execute after any subcommands are run, but after the subcommand has finished
 	// It is run even if Action() panics
 	// It is run even if Action() panics
 	After AfterFunc
 	After AfterFunc
+
 	// The action to execute when no subcommands are specified
 	// The action to execute when no subcommands are specified
+	// Expects a `cli.ActionFunc` but will accept the *deprecated* signature of `func(*cli.Context) {}`
+	// *Note*: support for the deprecated `Action` signature will be removed in a future version
 	Action interface{}
 	Action interface{}
-	// TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind
-	// of deprecation period has passed, maybe?
 
 
 	// Execute this function if the proper command cannot be found
 	// Execute this function if the proper command cannot be found
 	CommandNotFound CommandNotFoundFunc
 	CommandNotFound CommandNotFoundFunc
@@ -87,6 +85,12 @@ type App struct {
 	ErrWriter io.Writer
 	ErrWriter io.Writer
 	// Other custom info
 	// Other custom info
 	Metadata map[string]interface{}
 	Metadata map[string]interface{}
+	// Carries a function which returns app specific info.
+	ExtraInfo func() map[string]string
+	// CustomAppHelpTemplate the text template for app help topic.
+	// cli.go uses text/template to render templates. You can
+	// render custom help text by setting this variable.
+	CustomAppHelpTemplate string
 
 
 	didSetup bool
 	didSetup bool
 }
 }
@@ -147,10 +151,6 @@ func (a *App) Setup() {
 		}
 		}
 	}
 	}
 
 
-	if a.EnableBashCompletion {
-		a.appendFlag(BashCompletionFlag)
-	}
-
 	if !a.HideVersion {
 	if !a.HideVersion {
 		a.appendFlag(VersionFlag)
 		a.appendFlag(VersionFlag)
 	}
 	}
@@ -160,6 +160,14 @@ func (a *App) Setup() {
 		a.categories = a.categories.AddCommand(command.Category, command)
 		a.categories = a.categories.AddCommand(command.Category, command)
 	}
 	}
 	sort.Sort(a.categories)
 	sort.Sort(a.categories)
+
+	if a.Metadata == nil {
+		a.Metadata = make(map[string]interface{})
+	}
+
+	if a.Writer == nil {
+		a.Writer = os.Stdout
+	}
 }
 }
 
 
 // Run is the entry point to the cli app. Parses the arguments slice and routes
 // Run is the entry point to the cli app. Parses the arguments slice and routes
@@ -167,8 +175,20 @@ func (a *App) Setup() {
 func (a *App) Run(arguments []string) (err error) {
 func (a *App) Run(arguments []string) (err error) {
 	a.Setup()
 	a.Setup()
 
 
+	// handle the completion flag separately from the flagset since
+	// completion could be attempted after a flag, but before its value was put
+	// on the command line. this causes the flagset to interpret the completion
+	// flag name as the value of the flag before it which is undesirable
+	// note that we can only do this because the shell autocomplete function
+	// always appends the completion flag at the end of the command
+	shellComplete, arguments := checkShellCompleteFlag(a, arguments)
+
 	// parse flags
 	// parse flags
-	set := flagSet(a.Name, a.Flags)
+	set, err := flagSet(a.Name, a.Flags)
+	if err != nil {
+		return err
+	}
+
 	set.SetOutput(ioutil.Discard)
 	set.SetOutput(ioutil.Discard)
 	err = set.Parse(arguments[1:])
 	err = set.Parse(arguments[1:])
 	nerr := normalizeFlags(a.Flags, set)
 	nerr := normalizeFlags(a.Flags, set)
@@ -178,6 +198,7 @@ func (a *App) Run(arguments []string) (err error) {
 		ShowAppHelp(context)
 		ShowAppHelp(context)
 		return nerr
 		return nerr
 	}
 	}
+	context.shellComplete = shellComplete
 
 
 	if checkCompletions(context) {
 	if checkCompletions(context) {
 		return nil
 		return nil
@@ -189,7 +210,7 @@ func (a *App) Run(arguments []string) (err error) {
 			HandleExitCoder(err)
 			HandleExitCoder(err)
 			return err
 			return err
 		}
 		}
-		fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.")
+		fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
 		ShowAppHelp(context)
 		ShowAppHelp(context)
 		return err
 		return err
 	}
 	}
@@ -219,7 +240,6 @@ func (a *App) Run(arguments []string) (err error) {
 	if a.Before != nil {
 	if a.Before != nil {
 		beforeErr := a.Before(context)
 		beforeErr := a.Before(context)
 		if beforeErr != nil {
 		if beforeErr != nil {
-			fmt.Fprintf(a.Writer, "%v\n\n", beforeErr)
 			ShowAppHelp(context)
 			ShowAppHelp(context)
 			HandleExitCoder(beforeErr)
 			HandleExitCoder(beforeErr)
 			err = beforeErr
 			err = beforeErr
@@ -236,6 +256,10 @@ func (a *App) Run(arguments []string) (err error) {
 		}
 		}
 	}
 	}
 
 
+	if a.Action == nil {
+		a.Action = helpCommand.Action
+	}
+
 	// Run default Action
 	// Run default Action
 	err = HandleAction(a.Action, context)
 	err = HandleAction(a.Action, context)
 
 
@@ -243,11 +267,12 @@ func (a *App) Run(arguments []string) (err error) {
 	return err
 	return err
 }
 }
 
 
-// DEPRECATED: Another entry point to the cli app, takes care of passing arguments and error handling
+// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
+//
+// Deprecated: instead you should return an error that fulfills cli.ExitCoder
+// to cli.App.Run. This will cause the application to exit with the given eror
+// code in the cli.ExitCoder
 func (a *App) RunAndExitOnError() {
 func (a *App) RunAndExitOnError() {
-	fmt.Fprintf(a.errWriter(),
-		"DEPRECATED cli.App.RunAndExitOnError.  %s  See %s\n",
-		contactSysadmin, runAndExitOnErrorDeprecationURL)
 	if err := a.Run(os.Args); err != nil {
 	if err := a.Run(os.Args); err != nil {
 		fmt.Fprintln(a.errWriter(), err)
 		fmt.Fprintln(a.errWriter(), err)
 		OsExiter(1)
 		OsExiter(1)
@@ -276,13 +301,12 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
 	}
 	}
 	a.Commands = newCmds
 	a.Commands = newCmds
 
 
-	// append flags
-	if a.EnableBashCompletion {
-		a.appendFlag(BashCompletionFlag)
+	// parse flags
+	set, err := flagSet(a.Name, a.Flags)
+	if err != nil {
+		return err
 	}
 	}
 
 
-	// parse flags
-	set := flagSet(a.Name, a.Flags)
 	set.SetOutput(ioutil.Discard)
 	set.SetOutput(ioutil.Discard)
 	err = set.Parse(ctx.Args().Tail())
 	err = set.Parse(ctx.Args().Tail())
 	nerr := normalizeFlags(a.Flags, set)
 	nerr := normalizeFlags(a.Flags, set)
@@ -309,7 +333,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
 			HandleExitCoder(err)
 			HandleExitCoder(err)
 			return err
 			return err
 		}
 		}
-		fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.")
+		fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
 		ShowSubcommandHelp(context)
 		ShowSubcommandHelp(context)
 		return err
 		return err
 	}
 	}
@@ -450,50 +474,24 @@ type Author struct {
 func (a Author) String() string {
 func (a Author) String() string {
 	e := ""
 	e := ""
 	if a.Email != "" {
 	if a.Email != "" {
-		e = "<" + a.Email + "> "
+		e = " <" + a.Email + ">"
 	}
 	}
 
 
-	return fmt.Sprintf("%v %v", a.Name, e)
+	return fmt.Sprintf("%v%v", a.Name, e)
 }
 }
 
 
-// HandleAction uses ✧✧✧reflection✧✧✧ to figure out if the given Action is an
-// ActionFunc, a func with the legacy signature for Action, or some other
-// invalid thing.  If it's an ActionFunc or a func with the legacy signature for
-// Action, the func is run!
+// HandleAction attempts to figure out which Action signature was used.  If
+// it's an ActionFunc or a func with the legacy signature for Action, the func
+// is run!
 func HandleAction(action interface{}, context *Context) (err error) {
 func HandleAction(action interface{}, context *Context) (err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			// Try to detect a known reflection error from *this scope*, rather than
-			// swallowing all panics that may happen when calling an Action func.
-			s := fmt.Sprintf("%v", r)
-			if strings.HasPrefix(s, "reflect: ") && strings.Contains(s, "too many input arguments") {
-				err = NewExitError(fmt.Sprintf("ERROR unknown Action error: %v.  See %s", r, appActionDeprecationURL), 2)
-			} else {
-				panic(r)
-			}
-		}
-	}()
-
-	if reflect.TypeOf(action).Kind() != reflect.Func {
-		return errNonFuncAction
-	}
-
-	vals := reflect.ValueOf(action).Call([]reflect.Value{reflect.ValueOf(context)})
-
-	if len(vals) == 0 {
-		fmt.Fprintf(ErrWriter,
-			"DEPRECATED Action signature.  Must be `cli.ActionFunc`.  %s  See %s\n",
-			contactSysadmin, appActionDeprecationURL)
+	if a, ok := action.(ActionFunc); ok {
+		return a(context)
+	} else if a, ok := action.(func(*Context) error); ok {
+		return a(context)
+	} else if a, ok := action.(func(*Context)); ok { // deprecated function signature
+		a(context)
 		return nil
 		return nil
+	} else {
+		return errInvalidActionType
 	}
 	}
-
-	if len(vals) > 1 {
-		return errInvalidActionSignature
-	}
-
-	if retErr, ok := vals[0].Interface().(error); vals[0].IsValid() && ok {
-		return retErr
-	}
-
-	return err
 }
 }

+ 3 - 0
vendor/github.com/urfave/cli/cli.go

@@ -12,8 +12,11 @@
 //     app.Usage = "say a greeting"
 //     app.Usage = "say a greeting"
 //     app.Action = func(c *cli.Context) error {
 //     app.Action = func(c *cli.Context) error {
 //       println("Greetings")
 //       println("Greetings")
+//       return nil
 //     }
 //     }
 //
 //
 //     app.Run(os.Args)
 //     app.Run(os.Args)
 //   }
 //   }
 package cli
 package cli
+
+//go:generate python ./generate-flag-types cli -i flag-types.json -o flag_generated.go

+ 55 - 30
vendor/github.com/urfave/cli/command.go

@@ -46,6 +46,11 @@ type Command struct {
 	Flags []Flag
 	Flags []Flag
 	// Treat all flags as normal arguments if true
 	// Treat all flags as normal arguments if true
 	SkipFlagParsing bool
 	SkipFlagParsing bool
+	// Skip argument reordering which attempts to move flags before arguments,
+	// but only works if all flags appear after all arguments. This behavior was
+	// removed n version 2 since it only works under specific conditions so we
+	// backport here by exposing it as an option for compatibility.
+	SkipArgReorder bool
 	// Boolean to hide built-in help command
 	// Boolean to hide built-in help command
 	HideHelp bool
 	HideHelp bool
 	// Boolean to hide this command from help or completion
 	// Boolean to hide this command from help or completion
@@ -54,6 +59,25 @@ type Command struct {
 	// Full name of command for help, defaults to full command name, including parent commands.
 	// Full name of command for help, defaults to full command name, including parent commands.
 	HelpName        string
 	HelpName        string
 	commandNamePath []string
 	commandNamePath []string
+
+	// CustomHelpTemplate the text template for the command help topic.
+	// cli.go uses text/template to render templates. You can
+	// render custom help text by setting this variable.
+	CustomHelpTemplate string
+}
+
+type CommandsByName []Command
+
+func (c CommandsByName) Len() int {
+	return len(c)
+}
+
+func (c CommandsByName) Less(i, j int) bool {
+	return c[i].Name < c[j].Name
+}
+
+func (c CommandsByName) Swap(i, j int) {
+	c[i], c[j] = c[j], c[i]
 }
 }
 
 
 // FullName returns the full name of the command.
 // FullName returns the full name of the command.
@@ -82,14 +106,15 @@ func (c Command) Run(ctx *Context) (err error) {
 		)
 		)
 	}
 	}
 
 
-	if ctx.App.EnableBashCompletion {
-		c.Flags = append(c.Flags, BashCompletionFlag)
+	set, err := flagSet(c.Name, c.Flags)
+	if err != nil {
+		return err
 	}
 	}
-
-	set := flagSet(c.Name, c.Flags)
 	set.SetOutput(ioutil.Discard)
 	set.SetOutput(ioutil.Discard)
 
 
-	if !c.SkipFlagParsing {
+	if c.SkipFlagParsing {
+		err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
+	} else if !c.SkipArgReorder {
 		firstFlagIndex := -1
 		firstFlagIndex := -1
 		terminatorIndex := -1
 		terminatorIndex := -1
 		for index, arg := range ctx.Args() {
 		for index, arg := range ctx.Args() {
@@ -122,21 +147,7 @@ func (c Command) Run(ctx *Context) (err error) {
 			err = set.Parse(ctx.Args().Tail())
 			err = set.Parse(ctx.Args().Tail())
 		}
 		}
 	} else {
 	} else {
-		if c.SkipFlagParsing {
-			err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
-		}
-	}
-
-	if err != nil {
-		if c.OnUsageError != nil {
-			err := c.OnUsageError(ctx, err, false)
-			HandleExitCoder(err)
-			return err
-		}
-		fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.")
-		fmt.Fprintln(ctx.App.Writer)
-		ShowCommandHelp(ctx, c.Name)
-		return err
+		err = set.Parse(ctx.Args().Tail())
 	}
 	}
 
 
 	nerr := normalizeFlags(c.Flags, set)
 	nerr := normalizeFlags(c.Flags, set)
@@ -148,11 +159,23 @@ func (c Command) Run(ctx *Context) (err error) {
 	}
 	}
 
 
 	context := NewContext(ctx.App, set, ctx)
 	context := NewContext(ctx.App, set, ctx)
-
+	context.Command = c
 	if checkCommandCompletions(context, c.Name) {
 	if checkCommandCompletions(context, c.Name) {
 		return nil
 		return nil
 	}
 	}
 
 
+	if err != nil {
+		if c.OnUsageError != nil {
+			err := c.OnUsageError(context, err, false)
+			HandleExitCoder(err)
+			return err
+		}
+		fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
+		fmt.Fprintln(context.App.Writer)
+		ShowCommandHelp(context, c.Name)
+		return err
+	}
+
 	if checkCommandHelp(context, c.Name) {
 	if checkCommandHelp(context, c.Name) {
 		return nil
 		return nil
 	}
 	}
@@ -174,15 +197,16 @@ func (c Command) Run(ctx *Context) (err error) {
 	if c.Before != nil {
 	if c.Before != nil {
 		err = c.Before(context)
 		err = c.Before(context)
 		if err != nil {
 		if err != nil {
-			fmt.Fprintln(ctx.App.Writer, err)
-			fmt.Fprintln(ctx.App.Writer)
-			ShowCommandHelp(ctx, c.Name)
+			ShowCommandHelp(context, c.Name)
 			HandleExitCoder(err)
 			HandleExitCoder(err)
 			return err
 			return err
 		}
 		}
 	}
 	}
 
 
-	context.Command = c
+	if c.Action == nil {
+		c.Action = helpSubcommand.Action
+	}
+
 	err = HandleAction(c.Action, context)
 	err = HandleAction(c.Action, context)
 
 
 	if err != nil {
 	if err != nil {
@@ -223,14 +247,13 @@ func (c Command) startApp(ctx *Context) error {
 		app.HelpName = app.Name
 		app.HelpName = app.Name
 	}
 	}
 
 
-	if c.Description != "" {
-		app.Usage = c.Description
-	} else {
-		app.Usage = c.Usage
-	}
+	app.Usage = c.Usage
+	app.Description = c.Description
+	app.ArgsUsage = c.ArgsUsage
 
 
 	// set CommandNotFound
 	// set CommandNotFound
 	app.CommandNotFound = ctx.App.CommandNotFound
 	app.CommandNotFound = ctx.App.CommandNotFound
+	app.CustomAppHelpTemplate = c.CustomHelpTemplate
 
 
 	// set the flags and commands
 	// set the flags and commands
 	app.Commands = c.Subcommands
 	app.Commands = c.Subcommands
@@ -243,6 +266,7 @@ func (c Command) startApp(ctx *Context) error {
 	app.Author = ctx.App.Author
 	app.Author = ctx.App.Author
 	app.Email = ctx.App.Email
 	app.Email = ctx.App.Email
 	app.Writer = ctx.App.Writer
 	app.Writer = ctx.App.Writer
+	app.ErrWriter = ctx.App.ErrWriter
 
 
 	app.categories = CommandCategories{}
 	app.categories = CommandCategories{}
 	for _, command := range c.Subcommands {
 	for _, command := range c.Subcommands {
@@ -265,6 +289,7 @@ func (c Command) startApp(ctx *Context) error {
 	} else {
 	} else {
 		app.Action = helpSubcommand.Action
 		app.Action = helpSubcommand.Action
 	}
 	}
+	app.OnUsageError = c.OnUsageError
 
 
 	for index, cc := range app.Commands {
 	for index, cc := range app.Commands {
 		app.Commands[index].commandNamePath = []string{c.Name, cc.Name}
 		app.Commands[index].commandNamePath = []string{c.Name, cc.Name}

+ 81 - 352
vendor/github.com/urfave/cli/context.go

@@ -3,9 +3,9 @@ package cli
 import (
 import (
 	"errors"
 	"errors"
 	"flag"
 	"flag"
-	"strconv"
+	"reflect"
 	"strings"
 	"strings"
-	"time"
+	"syscall"
 )
 )
 
 
 // Context is a type that is passed through to
 // Context is a type that is passed through to
@@ -13,201 +13,23 @@ import (
 // can be used to retrieve context-specific Args and
 // can be used to retrieve context-specific Args and
 // parsed command-line options.
 // parsed command-line options.
 type Context struct {
 type Context struct {
-	App            *App
-	Command        Command
-	flagSet        *flag.FlagSet
-	setFlags       map[string]bool
-	globalSetFlags map[string]bool
-	parentContext  *Context
+	App           *App
+	Command       Command
+	shellComplete bool
+	flagSet       *flag.FlagSet
+	setFlags      map[string]bool
+	parentContext *Context
 }
 }
 
 
 // NewContext creates a new context. For use in when invoking an App or Command action.
 // NewContext creates a new context. For use in when invoking an App or Command action.
 func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
 func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
-	return &Context{App: app, flagSet: set, parentContext: parentCtx}
-}
-
-// Int looks up the value of a local int flag, returns 0 if no int flag exists
-func (c *Context) Int(name string) int {
-	return lookupInt(name, c.flagSet)
-}
-
-// Int64 looks up the value of a local int flag, returns 0 if no int flag exists
-func (c *Context) Int64(name string) int64 {
-	return lookupInt64(name, c.flagSet)
-}
-
-// Uint looks up the value of a local int flag, returns 0 if no int flag exists
-func (c *Context) Uint(name string) uint {
-	return lookupUint(name, c.flagSet)
-}
-
-// Uint64 looks up the value of a local int flag, returns 0 if no int flag exists
-func (c *Context) Uint64(name string) uint64 {
-	return lookupUint64(name, c.flagSet)
-}
-
-// Duration looks up the value of a local time.Duration flag, returns 0 if no
-// time.Duration flag exists
-func (c *Context) Duration(name string) time.Duration {
-	return lookupDuration(name, c.flagSet)
-}
-
-// Float64 looks up the value of a local float64 flag, returns 0 if no float64
-// flag exists
-func (c *Context) Float64(name string) float64 {
-	return lookupFloat64(name, c.flagSet)
-}
-
-// Bool looks up the value of a local bool flag, returns false if no bool flag exists
-func (c *Context) Bool(name string) bool {
-	return lookupBool(name, c.flagSet)
-}
-
-// BoolT looks up the value of a local boolT flag, returns false if no bool flag exists
-func (c *Context) BoolT(name string) bool {
-	return lookupBoolT(name, c.flagSet)
-}
-
-// String looks up the value of a local string flag, returns "" if no string flag exists
-func (c *Context) String(name string) string {
-	return lookupString(name, c.flagSet)
-}
-
-// StringSlice looks up the value of a local string slice flag, returns nil if no
-// string slice flag exists
-func (c *Context) StringSlice(name string) []string {
-	return lookupStringSlice(name, c.flagSet)
-}
+	c := &Context{App: app, flagSet: set, parentContext: parentCtx}
 
 
-// IntSlice looks up the value of a local int slice flag, returns nil if no int
-// slice flag exists
-func (c *Context) IntSlice(name string) []int {
-	return lookupIntSlice(name, c.flagSet)
-}
-
-// Int64Slice looks up the value of a local int slice flag, returns nil if no int
-// slice flag exists
-func (c *Context) Int64Slice(name string) []int64 {
-	return lookupInt64Slice(name, c.flagSet)
-}
-
-// Generic looks up the value of a local generic flag, returns nil if no generic
-// flag exists
-func (c *Context) Generic(name string) interface{} {
-	return lookupGeneric(name, c.flagSet)
-}
-
-// GlobalInt looks up the value of a global int flag, returns 0 if no int flag exists
-func (c *Context) GlobalInt(name string) int {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupInt(name, fs)
+	if parentCtx != nil {
+		c.shellComplete = parentCtx.shellComplete
 	}
 	}
-	return 0
-}
 
 
-// GlobalInt64 looks up the value of a global int flag, returns 0 if no int flag exists
-func (c *Context) GlobalInt64(name string) int64 {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupInt64(name, fs)
-	}
-	return 0
-}
-
-// GlobalUint looks up the value of a global int flag, returns 0 if no int flag exists
-func (c *Context) GlobalUint(name string) uint {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupUint(name, fs)
-	}
-	return 0
-}
-
-// GlobalUint64 looks up the value of a global int flag, returns 0 if no int flag exists
-func (c *Context) GlobalUint64(name string) uint64 {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupUint64(name, fs)
-	}
-	return 0
-}
-
-// GlobalFloat64 looks up the value of a global float64 flag, returns float64(0)
-// if no float64 flag exists
-func (c *Context) GlobalFloat64(name string) float64 {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupFloat64(name, fs)
-	}
-	return float64(0)
-}
-
-// GlobalDuration looks up the value of a global time.Duration flag, returns 0
-// if no time.Duration flag exists
-func (c *Context) GlobalDuration(name string) time.Duration {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupDuration(name, fs)
-	}
-	return 0
-}
-
-// GlobalBool looks up the value of a global bool flag, returns false if no bool
-// flag exists
-func (c *Context) GlobalBool(name string) bool {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupBool(name, fs)
-	}
-	return false
-}
-
-// GlobalBoolT looks up the value of a global bool flag, returns true if no bool
-// flag exists
-func (c *Context) GlobalBoolT(name string) bool {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupBoolT(name, fs)
-	}
-	return false
-}
-
-// GlobalString looks up the value of a global string flag, returns "" if no
-// string flag exists
-func (c *Context) GlobalString(name string) string {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupString(name, fs)
-	}
-	return ""
-}
-
-// GlobalStringSlice looks up the value of a global string slice flag, returns
-// nil if no string slice flag exists
-func (c *Context) GlobalStringSlice(name string) []string {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupStringSlice(name, fs)
-	}
-	return nil
-}
-
-// GlobalIntSlice looks up the value of a global int slice flag, returns nil if
-// no int slice flag exists
-func (c *Context) GlobalIntSlice(name string) []int {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupIntSlice(name, fs)
-	}
-	return nil
-}
-
-// GlobalInt64Slice looks up the value of a global int slice flag, returns nil if
-// no int slice flag exists
-func (c *Context) GlobalInt64Slice(name string) []int64 {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupInt64Slice(name, fs)
-	}
-	return nil
-}
-
-// GlobalGeneric looks up the value of a global generic flag, returns nil if no
-// generic flag exists
-func (c *Context) GlobalGeneric(name string) interface{} {
-	if fs := lookupGlobalFlagSet(name, c); fs != nil {
-		return lookupGeneric(name, fs)
-	}
-	return nil
+	return c
 }
 }
 
 
 // NumFlags returns the number of flags set
 // NumFlags returns the number of flags set
@@ -217,11 +39,13 @@ func (c *Context) NumFlags() int {
 
 
 // Set sets a context flag to a value.
 // Set sets a context flag to a value.
 func (c *Context) Set(name, value string) error {
 func (c *Context) Set(name, value string) error {
+	c.setFlags = nil
 	return c.flagSet.Set(name, value)
 	return c.flagSet.Set(name, value)
 }
 }
 
 
 // GlobalSet sets a context flag to a value on the global flagset
 // GlobalSet sets a context flag to a value on the global flagset
 func (c *Context) GlobalSet(name, value string) error {
 func (c *Context) GlobalSet(name, value string) error {
+	globalContext(c).setFlags = nil
 	return globalContext(c).flagSet.Set(name, value)
 	return globalContext(c).flagSet.Set(name, value)
 }
 }
 
 
@@ -229,28 +53,78 @@ func (c *Context) GlobalSet(name, value string) error {
 func (c *Context) IsSet(name string) bool {
 func (c *Context) IsSet(name string) bool {
 	if c.setFlags == nil {
 	if c.setFlags == nil {
 		c.setFlags = make(map[string]bool)
 		c.setFlags = make(map[string]bool)
+
 		c.flagSet.Visit(func(f *flag.Flag) {
 		c.flagSet.Visit(func(f *flag.Flag) {
 			c.setFlags[f.Name] = true
 			c.setFlags[f.Name] = true
 		})
 		})
+
+		c.flagSet.VisitAll(func(f *flag.Flag) {
+			if _, ok := c.setFlags[f.Name]; ok {
+				return
+			}
+			c.setFlags[f.Name] = false
+		})
+
+		// XXX hack to support IsSet for flags with EnvVar
+		//
+		// There isn't an easy way to do this with the current implementation since
+		// whether a flag was set via an environment variable is very difficult to
+		// determine here. Instead, we intend to introduce a backwards incompatible
+		// change in version 2 to add `IsSet` to the Flag interface to push the
+		// responsibility closer to where the information required to determine
+		// whether a flag is set by non-standard means such as environment
+		// variables is avaliable.
+		//
+		// See https://github.com/urfave/cli/issues/294 for additional discussion
+		flags := c.Command.Flags
+		if c.Command.Name == "" { // cannot == Command{} since it contains slice types
+			if c.App != nil {
+				flags = c.App.Flags
+			}
+		}
+		for _, f := range flags {
+			eachName(f.GetName(), func(name string) {
+				if isSet, ok := c.setFlags[name]; isSet || !ok {
+					return
+				}
+
+				val := reflect.ValueOf(f)
+				if val.Kind() == reflect.Ptr {
+					val = val.Elem()
+				}
+
+				envVarValue := val.FieldByName("EnvVar")
+				if !envVarValue.IsValid() {
+					return
+				}
+
+				eachName(envVarValue.String(), func(envVar string) {
+					envVar = strings.TrimSpace(envVar)
+					if _, ok := syscall.Getenv(envVar); ok {
+						c.setFlags[name] = true
+						return
+					}
+				})
+			})
+		}
 	}
 	}
-	return c.setFlags[name] == true
+
+	return c.setFlags[name]
 }
 }
 
 
 // GlobalIsSet determines if the global flag was actually set
 // GlobalIsSet determines if the global flag was actually set
 func (c *Context) GlobalIsSet(name string) bool {
 func (c *Context) GlobalIsSet(name string) bool {
-	if c.globalSetFlags == nil {
-		c.globalSetFlags = make(map[string]bool)
-		ctx := c
-		if ctx.parentContext != nil {
-			ctx = ctx.parentContext
-		}
-		for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext {
-			ctx.flagSet.Visit(func(f *flag.Flag) {
-				c.globalSetFlags[f.Name] = true
-			})
+	ctx := c
+	if ctx.parentContext != nil {
+		ctx = ctx.parentContext
+	}
+
+	for ; ctx != nil; ctx = ctx.parentContext {
+		if ctx.IsSet(name) {
+			return true
 		}
 		}
 	}
 	}
-	return c.globalSetFlags[name]
+	return false
 }
 }
 
 
 // FlagNames returns a slice of flag names used in this context.
 // FlagNames returns a slice of flag names used in this context.
@@ -282,6 +156,11 @@ func (c *Context) Parent() *Context {
 	return c.parentContext
 	return c.parentContext
 }
 }
 
 
+// value returns the value of the flag coressponding to `name`
+func (c *Context) value(name string) interface{} {
+	return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
+}
+
 // Args contains apps console arguments
 // Args contains apps console arguments
 type Args []string
 type Args []string
 
 
@@ -357,156 +236,6 @@ func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
 	return nil
 	return nil
 }
 }
 
 
-func lookupInt(name string, set *flag.FlagSet) int {
-	f := set.Lookup(name)
-	if f != nil {
-		val, err := strconv.ParseInt(f.Value.String(), 0, 64)
-		if err != nil {
-			return 0
-		}
-		return int(val)
-	}
-
-	return 0
-}
-
-func lookupInt64(name string, set *flag.FlagSet) int64 {
-	f := set.Lookup(name)
-	if f != nil {
-		val, err := strconv.ParseInt(f.Value.String(), 0, 64)
-		if err != nil {
-			return 0
-		}
-		return val
-	}
-
-	return 0
-}
-
-func lookupUint(name string, set *flag.FlagSet) uint {
-	f := set.Lookup(name)
-	if f != nil {
-		val, err := strconv.ParseUint(f.Value.String(), 0, 64)
-		if err != nil {
-			return 0
-		}
-		return uint(val)
-	}
-
-	return 0
-}
-
-func lookupUint64(name string, set *flag.FlagSet) uint64 {
-	f := set.Lookup(name)
-	if f != nil {
-		val, err := strconv.ParseUint(f.Value.String(), 0, 64)
-		if err != nil {
-			return 0
-		}
-		return val
-	}
-
-	return 0
-}
-
-func lookupDuration(name string, set *flag.FlagSet) time.Duration {
-	f := set.Lookup(name)
-	if f != nil {
-		val, err := time.ParseDuration(f.Value.String())
-		if err == nil {
-			return val
-		}
-	}
-
-	return 0
-}
-
-func lookupFloat64(name string, set *flag.FlagSet) float64 {
-	f := set.Lookup(name)
-	if f != nil {
-		val, err := strconv.ParseFloat(f.Value.String(), 64)
-		if err != nil {
-			return 0
-		}
-		return val
-	}
-
-	return 0
-}
-
-func lookupString(name string, set *flag.FlagSet) string {
-	f := set.Lookup(name)
-	if f != nil {
-		return f.Value.String()
-	}
-
-	return ""
-}
-
-func lookupStringSlice(name string, set *flag.FlagSet) []string {
-	f := set.Lookup(name)
-	if f != nil {
-		return (f.Value.(*StringSlice)).Value()
-
-	}
-
-	return nil
-}
-
-func lookupIntSlice(name string, set *flag.FlagSet) []int {
-	f := set.Lookup(name)
-	if f != nil {
-		return (f.Value.(*IntSlice)).Value()
-
-	}
-
-	return nil
-}
-
-func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
-	f := set.Lookup(name)
-	if f != nil {
-		return (f.Value.(*Int64Slice)).Value()
-
-	}
-
-	return nil
-}
-
-func lookupGeneric(name string, set *flag.FlagSet) interface{} {
-	f := set.Lookup(name)
-	if f != nil {
-		return f.Value
-	}
-	return nil
-}
-
-func lookupBool(name string, set *flag.FlagSet) bool {
-	f := set.Lookup(name)
-	if f != nil {
-		val, err := strconv.ParseBool(f.Value.String())
-		if err != nil {
-			return false
-		}
-		return val
-	}
-
-	return false
-}
-
-func lookupBoolT(name string, set *flag.FlagSet) bool {
-	f := set.Lookup(name)
-	if f != nil {
-		val, err := strconv.ParseBool(f.Value.String())
-		if err != nil {
-			return true
-		}
-		return val
-	}
-
-	return false
-}
-
 func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
 func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
 	switch ff.Value.(type) {
 	switch ff.Value.(type) {
 	case *StringSlice:
 	case *StringSlice:

+ 31 - 8
vendor/github.com/urfave/cli/errors.go

@@ -24,7 +24,7 @@ func NewMultiError(err ...error) MultiError {
 	return MultiError{Errors: err}
 	return MultiError{Errors: err}
 }
 }
 
 
-// Error implents the error interface.
+// Error implements the error interface.
 func (m MultiError) Error() string {
 func (m MultiError) Error() string {
 	errs := make([]string, len(m.Errors))
 	errs := make([]string, len(m.Errors))
 	for i, err := range m.Errors {
 	for i, err := range m.Errors {
@@ -34,6 +34,10 @@ func (m MultiError) Error() string {
 	return strings.Join(errs, "\n")
 	return strings.Join(errs, "\n")
 }
 }
 
 
+type ErrorFormatter interface {
+	Format(s fmt.State, verb rune)
+}
+
 // ExitCoder is the interface checked by `App` and `Command` for a custom exit
 // ExitCoder is the interface checked by `App` and `Command` for a custom exit
 // code
 // code
 type ExitCoder interface {
 type ExitCoder interface {
@@ -44,11 +48,11 @@ type ExitCoder interface {
 // ExitError fulfills both the builtin `error` interface and `ExitCoder`
 // ExitError fulfills both the builtin `error` interface and `ExitCoder`
 type ExitError struct {
 type ExitError struct {
 	exitCode int
 	exitCode int
-	message  string
+	message  interface{}
 }
 }
 
 
 // NewExitError makes a new *ExitError
 // NewExitError makes a new *ExitError
-func NewExitError(message string, exitCode int) *ExitError {
+func NewExitError(message interface{}, exitCode int) *ExitError {
 	return &ExitError{
 	return &ExitError{
 		exitCode: exitCode,
 		exitCode: exitCode,
 		message:  message,
 		message:  message,
@@ -58,7 +62,7 @@ func NewExitError(message string, exitCode int) *ExitError {
 // Error returns the string message, fulfilling the interface required by
 // Error returns the string message, fulfilling the interface required by
 // `error`
 // `error`
 func (ee *ExitError) Error() string {
 func (ee *ExitError) Error() string {
-	return ee.message
+	return fmt.Sprintf("%v", ee.message)
 }
 }
 
 
 // ExitCode returns the exit code, fulfilling the interface required by
 // ExitCode returns the exit code, fulfilling the interface required by
@@ -70,7 +74,7 @@ func (ee *ExitError) ExitCode() int {
 // HandleExitCoder checks if the error fulfills the ExitCoder interface, and if
 // HandleExitCoder checks if the error fulfills the ExitCoder interface, and if
 // so prints the error to stderr (if it is non-empty) and calls OsExiter with the
 // so prints the error to stderr (if it is non-empty) and calls OsExiter with the
 // given exit code.  If the given error is a MultiError, then this func is
 // given exit code.  If the given error is a MultiError, then this func is
-// called on all members of the Errors slice.
+// called on all members of the Errors slice and calls OsExiter with the last exit code.
 func HandleExitCoder(err error) {
 func HandleExitCoder(err error) {
 	if err == nil {
 	if err == nil {
 		return
 		return
@@ -78,15 +82,34 @@ func HandleExitCoder(err error) {
 
 
 	if exitErr, ok := err.(ExitCoder); ok {
 	if exitErr, ok := err.(ExitCoder); ok {
 		if err.Error() != "" {
 		if err.Error() != "" {
-			fmt.Fprintln(ErrWriter, err)
+			if _, ok := exitErr.(ErrorFormatter); ok {
+				fmt.Fprintf(ErrWriter, "%+v\n", err)
+			} else {
+				fmt.Fprintln(ErrWriter, err)
+			}
 		}
 		}
 		OsExiter(exitErr.ExitCode())
 		OsExiter(exitErr.ExitCode())
 		return
 		return
 	}
 	}
 
 
 	if multiErr, ok := err.(MultiError); ok {
 	if multiErr, ok := err.(MultiError); ok {
-		for _, merr := range multiErr.Errors {
-			HandleExitCoder(merr)
+		code := handleMultiError(multiErr)
+		OsExiter(code)
+		return
+	}
+}
+
+func handleMultiError(multiErr MultiError) int {
+	code := 1
+	for _, merr := range multiErr.Errors {
+		if multiErr2, ok := merr.(MultiError); ok {
+			code = handleMultiError(multiErr2)
+		} else {
+			fmt.Fprintln(ErrWriter, merr)
+			if exitErr, ok := merr.(ExitCoder); ok {
+				code = exitErr.ExitCode()
+			}
 		}
 		}
 	}
 	}
+	return code
 }
 }

+ 216 - 299
vendor/github.com/urfave/cli/flag.go

@@ -3,24 +3,24 @@ package cli
 import (
 import (
 	"flag"
 	"flag"
 	"fmt"
 	"fmt"
-	"os"
 	"reflect"
 	"reflect"
 	"runtime"
 	"runtime"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
+	"syscall"
 	"time"
 	"time"
 )
 )
 
 
 const defaultPlaceholder = "value"
 const defaultPlaceholder = "value"
 
 
 // BashCompletionFlag enables bash-completion for all commands and subcommands
 // BashCompletionFlag enables bash-completion for all commands and subcommands
-var BashCompletionFlag = BoolFlag{
+var BashCompletionFlag Flag = BoolFlag{
 	Name:   "generate-bash-completion",
 	Name:   "generate-bash-completion",
 	Hidden: true,
 	Hidden: true,
 }
 }
 
 
 // VersionFlag prints the version for the application
 // VersionFlag prints the version for the application
-var VersionFlag = BoolFlag{
+var VersionFlag Flag = BoolFlag{
 	Name:  "version, v",
 	Name:  "version, v",
 	Usage: "print the version",
 	Usage: "print the version",
 }
 }
@@ -28,7 +28,7 @@ var VersionFlag = BoolFlag{
 // HelpFlag prints the help for all commands and subcommands
 // HelpFlag prints the help for all commands and subcommands
 // Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
 // Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
 // unless HideHelp is set to true)
 // unless HideHelp is set to true)
-var HelpFlag = BoolFlag{
+var HelpFlag Flag = BoolFlag{
 	Name:  "help, h",
 	Name:  "help, h",
 	Usage: "show help",
 	Usage: "show help",
 }
 }
@@ -37,6 +37,21 @@ var HelpFlag = BoolFlag{
 // to display a flag.
 // to display a flag.
 var FlagStringer FlagStringFunc = stringifyFlag
 var FlagStringer FlagStringFunc = stringifyFlag
 
 
+// FlagsByName is a slice of Flag.
+type FlagsByName []Flag
+
+func (f FlagsByName) Len() int {
+	return len(f)
+}
+
+func (f FlagsByName) Less(i, j int) bool {
+	return f[i].GetName() < f[j].GetName()
+}
+
+func (f FlagsByName) Swap(i, j int) {
+	f[i], f[j] = f[j], f[i]
+}
+
 // Flag is a common interface related to parsing flags in cli.
 // Flag is a common interface related to parsing flags in cli.
 // For more advanced flag parsing techniques, it is recommended that
 // For more advanced flag parsing techniques, it is recommended that
 // this interface be implemented.
 // this interface be implemented.
@@ -47,13 +62,29 @@ type Flag interface {
 	GetName() string
 	GetName() string
 }
 }
 
 
-func flagSet(name string, flags []Flag) *flag.FlagSet {
+// errorableFlag is an interface that allows us to return errors during apply
+// it allows flags defined in this library to return errors in a fashion backwards compatible
+// TODO remove in v2 and modify the existing Flag interface to return errors
+type errorableFlag interface {
+	Flag
+
+	ApplyWithError(*flag.FlagSet) error
+}
+
+func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
 	set := flag.NewFlagSet(name, flag.ContinueOnError)
 	set := flag.NewFlagSet(name, flag.ContinueOnError)
 
 
 	for _, f := range flags {
 	for _, f := range flags {
-		f.Apply(set)
+		//TODO remove in v2 when errorableFlag is removed
+		if ef, ok := f.(errorableFlag); ok {
+			if err := ef.ApplyWithError(set); err != nil {
+				return nil, err
+			}
+		} else {
+			f.Apply(set)
+		}
 	}
 	}
-	return set
+	return set, nil
 }
 }
 
 
 func eachName(longName string, fn func(string)) {
 func eachName(longName string, fn func(string)) {
@@ -70,31 +101,24 @@ type Generic interface {
 	String() string
 	String() string
 }
 }
 
 
-// GenericFlag is the flag type for types implementing Generic
-type GenericFlag struct {
-	Name   string
-	Value  Generic
-	Usage  string
-	EnvVar string
-	Hidden bool
-}
-
-// String returns the string representation of the generic flag to display the
-// help text to the user (uses the String() method of the generic flag to show
-// the value)
-func (f GenericFlag) String() string {
-	return FlagStringer(f)
-}
-
 // Apply takes the flagset and calls Set on the generic flag with the value
 // Apply takes the flagset and calls Set on the generic flag with the value
 // provided by the user for parsing by the flag
 // provided by the user for parsing by the flag
+// Ignores parsing errors
 func (f GenericFlag) Apply(set *flag.FlagSet) {
 func (f GenericFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError takes the flagset and calls Set on the generic flag with the value
+// provided by the user for parsing by the flag
+func (f GenericFlag) ApplyWithError(set *flag.FlagSet) error {
 	val := f.Value
 	val := f.Value
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
-				val.Set(envVal)
+			if envVal, ok := syscall.Getenv(envVar); ok {
+				if err := val.Set(envVal); err != nil {
+					return fmt.Errorf("could not parse %s as value for flag %s: %s", envVal, f.Name, err)
+				}
 				break
 				break
 			}
 			}
 		}
 		}
@@ -103,14 +127,11 @@ func (f GenericFlag) Apply(set *flag.FlagSet) {
 	eachName(f.Name, func(name string) {
 	eachName(f.Name, func(name string) {
 		set.Var(f.Value, name, f.Usage)
 		set.Var(f.Value, name, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of a flag.
-func (f GenericFlag) GetName() string {
-	return f.Name
+	return nil
 }
 }
 
 
-// StringSlice is an opaque type for []string to satisfy flag.Value
+// StringSlice is an opaque type for []string to satisfy flag.Value and flag.Getter
 type StringSlice []string
 type StringSlice []string
 
 
 // Set appends the string value to the list of values
 // Set appends the string value to the list of values
@@ -129,31 +150,29 @@ func (f *StringSlice) Value() []string {
 	return *f
 	return *f
 }
 }
 
 
-// StringSliceFlag is a string flag that can be specified multiple times on the
-// command-line
-type StringSliceFlag struct {
-	Name   string
-	Value  *StringSlice
-	Usage  string
-	EnvVar string
-	Hidden bool
-}
-
-// String returns the usage
-func (f StringSliceFlag) String() string {
-	return FlagStringer(f)
+// Get returns the slice of strings set by this flag
+func (f *StringSlice) Get() interface{} {
+	return *f
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f StringSliceFlag) Apply(set *flag.FlagSet) {
 func (f StringSliceFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f StringSliceFlag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				newVal := &StringSlice{}
 				newVal := &StringSlice{}
 				for _, s := range strings.Split(envVal, ",") {
 				for _, s := range strings.Split(envVal, ",") {
 					s = strings.TrimSpace(s)
 					s = strings.TrimSpace(s)
-					newVal.Set(s)
+					if err := newVal.Set(s); err != nil {
+						return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err)
+					}
 				}
 				}
 				f.Value = newVal
 				f.Value = newVal
 				break
 				break
@@ -167,14 +186,11 @@ func (f StringSliceFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Var(f.Value, name, f.Usage)
 		set.Var(f.Value, name, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of a flag.
-func (f StringSliceFlag) GetName() string {
-	return f.Name
+	return nil
 }
 }
 
 
-// IntSlice is an opaque type for []int to satisfy flag.Value
+// IntSlice is an opaque type for []int to satisfy flag.Value and flag.Getter
 type IntSlice []int
 type IntSlice []int
 
 
 // Set parses the value into an integer and appends it to the list of values
 // Set parses the value into an integer and appends it to the list of values
@@ -197,33 +213,28 @@ func (f *IntSlice) Value() []int {
 	return *f
 	return *f
 }
 }
 
 
-// IntSliceFlag is an int flag that can be specified multiple times on the
-// command-line
-type IntSliceFlag struct {
-	Name   string
-	Value  *IntSlice
-	Usage  string
-	EnvVar string
-	Hidden bool
-}
-
-// String returns the usage
-func (f IntSliceFlag) String() string {
-	return FlagStringer(f)
+// Get returns the slice of ints set by this flag
+func (f *IntSlice) Get() interface{} {
+	return *f
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f IntSliceFlag) Apply(set *flag.FlagSet) {
 func (f IntSliceFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f IntSliceFlag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				newVal := &IntSlice{}
 				newVal := &IntSlice{}
 				for _, s := range strings.Split(envVal, ",") {
 				for _, s := range strings.Split(envVal, ",") {
 					s = strings.TrimSpace(s)
 					s = strings.TrimSpace(s)
-					err := newVal.Set(s)
-					if err != nil {
-						fmt.Fprintf(ErrWriter, err.Error())
+					if err := newVal.Set(s); err != nil {
+						return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err)
 					}
 					}
 				}
 				}
 				f.Value = newVal
 				f.Value = newVal
@@ -238,14 +249,11 @@ func (f IntSliceFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Var(f.Value, name, f.Usage)
 		set.Var(f.Value, name, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of the flag.
-func (f IntSliceFlag) GetName() string {
-	return f.Name
+	return nil
 }
 }
 
 
-// Int64Slice is an opaque type for []int to satisfy flag.Value
+// Int64Slice is an opaque type for []int to satisfy flag.Value and flag.Getter
 type Int64Slice []int64
 type Int64Slice []int64
 
 
 // Set parses the value into an integer and appends it to the list of values
 // Set parses the value into an integer and appends it to the list of values
@@ -268,33 +276,28 @@ func (f *Int64Slice) Value() []int64 {
 	return *f
 	return *f
 }
 }
 
 
-// Int64SliceFlag is an int flag that can be specified multiple times on the
-// command-line
-type Int64SliceFlag struct {
-	Name   string
-	Value  *Int64Slice
-	Usage  string
-	EnvVar string
-	Hidden bool
-}
-
-// String returns the usage
-func (f Int64SliceFlag) String() string {
-	return FlagStringer(f)
+// Get returns the slice of ints set by this flag
+func (f *Int64Slice) Get() interface{} {
+	return *f
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f Int64SliceFlag) Apply(set *flag.FlagSet) {
 func (f Int64SliceFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				newVal := &Int64Slice{}
 				newVal := &Int64Slice{}
 				for _, s := range strings.Split(envVal, ",") {
 				for _, s := range strings.Split(envVal, ",") {
 					s = strings.TrimSpace(s)
 					s = strings.TrimSpace(s)
-					err := newVal.Set(s)
-					if err != nil {
-						fmt.Fprintf(ErrWriter, err.Error())
+					if err := newVal.Set(s); err != nil {
+						return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err)
 					}
 					}
 				}
 				}
 				f.Value = newVal
 				f.Value = newVal
@@ -309,38 +312,33 @@ func (f Int64SliceFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Var(f.Value, name, f.Usage)
 		set.Var(f.Value, name, f.Usage)
 	})
 	})
-}
-
-// GetName returns the name of the flag.
-func (f Int64SliceFlag) GetName() string {
-	return f.Name
-}
-
-// BoolFlag is a switch that defaults to false
-type BoolFlag struct {
-	Name        string
-	Usage       string
-	EnvVar      string
-	Destination *bool
-	Hidden      bool
-}
-
-// String returns a readable representation of this value (for usage defaults)
-func (f BoolFlag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f BoolFlag) Apply(set *flag.FlagSet) {
 func (f BoolFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error {
 	val := false
 	val := false
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
+				if envVal == "" {
+					val = false
+					break
+				}
+
 				envValBool, err := strconv.ParseBool(envVal)
 				envValBool, err := strconv.ParseBool(envVal)
-				if err == nil {
-					val = envValBool
+				if err != nil {
+					return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err)
 				}
 				}
+
+				val = envValBool
 				break
 				break
 			}
 			}
 		}
 		}
@@ -353,40 +351,35 @@ func (f BoolFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Bool(name, val, f.Usage)
 		set.Bool(name, val, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of the flag.
-func (f BoolFlag) GetName() string {
-	return f.Name
-}
-
-// BoolTFlag this represents a boolean flag that is true by default, but can
-// still be set to false by --some-flag=false
-type BoolTFlag struct {
-	Name        string
-	Usage       string
-	EnvVar      string
-	Destination *bool
-	Hidden      bool
-}
-
-// String returns a readable representation of this value (for usage defaults)
-func (f BoolTFlag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f BoolTFlag) Apply(set *flag.FlagSet) {
 func (f BoolTFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error {
 	val := true
 	val := true
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
-				envValBool, err := strconv.ParseBool(envVal)
-				if err == nil {
-					val = envValBool
+			if envVal, ok := syscall.Getenv(envVar); ok {
+				if envVal == "" {
+					val = false
 					break
 					break
 				}
 				}
+
+				envValBool, err := strconv.ParseBool(envVal)
+				if err != nil {
+					return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err)
+				}
+
+				val = envValBool
+				break
 			}
 			}
 		}
 		}
 	}
 	}
@@ -398,34 +391,22 @@ func (f BoolTFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Bool(name, val, f.Usage)
 		set.Bool(name, val, f.Usage)
 	})
 	})
-}
-
-// GetName returns the name of the flag.
-func (f BoolTFlag) GetName() string {
-	return f.Name
-}
-
-// StringFlag represents a flag that takes as string value
-type StringFlag struct {
-	Name        string
-	Value       string
-	Usage       string
-	EnvVar      string
-	Destination *string
-	Hidden      bool
-}
 
 
-// String returns the usage
-func (f StringFlag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f StringFlag) Apply(set *flag.FlagSet) {
 func (f StringFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f StringFlag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				f.Value = envVal
 				f.Value = envVal
 				break
 				break
 			}
 			}
@@ -439,39 +420,28 @@ func (f StringFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.String(name, f.Value, f.Usage)
 		set.String(name, f.Value, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of the flag.
-func (f StringFlag) GetName() string {
-	return f.Name
-}
-
-// IntFlag is a flag that takes an integer
-type IntFlag struct {
-	Name        string
-	Value       int
-	Usage       string
-	EnvVar      string
-	Destination *int
-	Hidden      bool
-}
-
-// String returns the usage
-func (f IntFlag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f IntFlag) Apply(set *flag.FlagSet) {
 func (f IntFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f IntFlag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				envValInt, err := strconv.ParseInt(envVal, 0, 64)
 				envValInt, err := strconv.ParseInt(envVal, 0, 64)
-				if err == nil {
-					f.Value = int(envValInt)
-					break
+				if err != nil {
+					return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
 				}
 				}
+				f.Value = int(envValInt)
+				break
 			}
 			}
 		}
 		}
 	}
 	}
@@ -483,39 +453,29 @@ func (f IntFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Int(name, f.Value, f.Usage)
 		set.Int(name, f.Value, f.Usage)
 	})
 	})
-}
-
-// GetName returns the name of the flag.
-func (f IntFlag) GetName() string {
-	return f.Name
-}
 
 
-// Int64Flag is a flag that takes a 64-bit integer
-type Int64Flag struct {
-	Name        string
-	Value       int64
-	Usage       string
-	EnvVar      string
-	Destination *int64
-	Hidden      bool
-}
-
-// String returns the usage
-func (f Int64Flag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f Int64Flag) Apply(set *flag.FlagSet) {
 func (f Int64Flag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				envValInt, err := strconv.ParseInt(envVal, 0, 64)
 				envValInt, err := strconv.ParseInt(envVal, 0, 64)
-				if err == nil {
-					f.Value = envValInt
-					break
+				if err != nil {
+					return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
 				}
 				}
+
+				f.Value = envValInt
+				break
 			}
 			}
 		}
 		}
 	}
 	}
@@ -527,39 +487,29 @@ func (f Int64Flag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Int64(name, f.Value, f.Usage)
 		set.Int64(name, f.Value, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of the flag.
-func (f Int64Flag) GetName() string {
-	return f.Name
-}
-
-// UintFlag is a flag that takes an unsigned integer
-type UintFlag struct {
-	Name        string
-	Value       uint
-	Usage       string
-	EnvVar      string
-	Destination *uint
-	Hidden      bool
-}
-
-// String returns the usage
-func (f UintFlag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f UintFlag) Apply(set *flag.FlagSet) {
 func (f UintFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f UintFlag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				envValInt, err := strconv.ParseUint(envVal, 0, 64)
 				envValInt, err := strconv.ParseUint(envVal, 0, 64)
-				if err == nil {
-					f.Value = uint(envValInt)
-					break
+				if err != nil {
+					return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err)
 				}
 				}
+
+				f.Value = uint(envValInt)
+				break
 			}
 			}
 		}
 		}
 	}
 	}
@@ -571,39 +521,29 @@ func (f UintFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Uint(name, f.Value, f.Usage)
 		set.Uint(name, f.Value, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of the flag.
-func (f UintFlag) GetName() string {
-	return f.Name
-}
-
-// Uint64Flag is a flag that takes an unsigned 64-bit integer
-type Uint64Flag struct {
-	Name        string
-	Value       uint64
-	Usage       string
-	EnvVar      string
-	Destination *uint64
-	Hidden      bool
-}
-
-// String returns the usage
-func (f Uint64Flag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f Uint64Flag) Apply(set *flag.FlagSet) {
 func (f Uint64Flag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				envValInt, err := strconv.ParseUint(envVal, 0, 64)
 				envValInt, err := strconv.ParseUint(envVal, 0, 64)
-				if err == nil {
-					f.Value = uint64(envValInt)
-					break
+				if err != nil {
+					return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err)
 				}
 				}
+
+				f.Value = uint64(envValInt)
+				break
 			}
 			}
 		}
 		}
 	}
 	}
@@ -615,40 +555,29 @@ func (f Uint64Flag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Uint64(name, f.Value, f.Usage)
 		set.Uint64(name, f.Value, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of the flag.
-func (f Uint64Flag) GetName() string {
-	return f.Name
-}
-
-// DurationFlag is a flag that takes a duration specified in Go's duration
-// format: https://golang.org/pkg/time/#ParseDuration
-type DurationFlag struct {
-	Name        string
-	Value       time.Duration
-	Usage       string
-	EnvVar      string
-	Destination *time.Duration
-	Hidden      bool
-}
-
-// String returns a readable representation of this value (for usage defaults)
-func (f DurationFlag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f DurationFlag) Apply(set *flag.FlagSet) {
 func (f DurationFlag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				envValDuration, err := time.ParseDuration(envVal)
 				envValDuration, err := time.ParseDuration(envVal)
-				if err == nil {
-					f.Value = envValDuration
-					break
+				if err != nil {
+					return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err)
 				}
 				}
+
+				f.Value = envValDuration
+				break
 			}
 			}
 		}
 		}
 	}
 	}
@@ -660,38 +589,29 @@ func (f DurationFlag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Duration(name, f.Value, f.Usage)
 		set.Duration(name, f.Value, f.Usage)
 	})
 	})
-}
-
-// GetName returns the name of the flag.
-func (f DurationFlag) GetName() string {
-	return f.Name
-}
 
 
-// Float64Flag is a flag that takes an float value
-type Float64Flag struct {
-	Name        string
-	Value       float64
-	Usage       string
-	EnvVar      string
-	Destination *float64
-	Hidden      bool
-}
-
-// String returns the usage
-func (f Float64Flag) String() string {
-	return FlagStringer(f)
+	return nil
 }
 }
 
 
 // Apply populates the flag given the flag set and environment
 // Apply populates the flag given the flag set and environment
+// Ignores errors
 func (f Float64Flag) Apply(set *flag.FlagSet) {
 func (f Float64Flag) Apply(set *flag.FlagSet) {
+	f.ApplyWithError(set)
+}
+
+// ApplyWithError populates the flag given the flag set and environment
+func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error {
 	if f.EnvVar != "" {
 	if f.EnvVar != "" {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 		for _, envVar := range strings.Split(f.EnvVar, ",") {
 			envVar = strings.TrimSpace(envVar)
 			envVar = strings.TrimSpace(envVar)
-			if envVal := os.Getenv(envVar); envVal != "" {
+			if envVal, ok := syscall.Getenv(envVar); ok {
 				envValFloat, err := strconv.ParseFloat(envVal, 10)
 				envValFloat, err := strconv.ParseFloat(envVal, 10)
-				if err == nil {
-					f.Value = float64(envValFloat)
+				if err != nil {
+					return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err)
 				}
 				}
+
+				f.Value = float64(envValFloat)
+				break
 			}
 			}
 		}
 		}
 	}
 	}
@@ -703,17 +623,15 @@ func (f Float64Flag) Apply(set *flag.FlagSet) {
 		}
 		}
 		set.Float64(name, f.Value, f.Usage)
 		set.Float64(name, f.Value, f.Usage)
 	})
 	})
-}
 
 
-// GetName returns the name of the flag.
-func (f Float64Flag) GetName() string {
-	return f.Name
+	return nil
 }
 }
 
 
 func visibleFlags(fl []Flag) []Flag {
 func visibleFlags(fl []Flag) []Flag {
 	visible := []Flag{}
 	visible := []Flag{}
 	for _, flag := range fl {
 	for _, flag := range fl {
-		if !flagValue(flag).FieldByName("Hidden").Bool() {
+		field := flagValue(flag).FieldByName("Hidden")
+		if !field.IsValid() || !field.Bool() {
 			visible = append(visible, flag)
 			visible = append(visible, flag)
 		}
 		}
 	}
 	}
@@ -806,9 +724,8 @@ func stringifyFlag(f Flag) string {
 
 
 	needsPlaceholder := false
 	needsPlaceholder := false
 	defaultValueString := ""
 	defaultValueString := ""
-	val := fv.FieldByName("Value")
 
 
-	if val.IsValid() {
+	if val := fv.FieldByName("Value"); val.IsValid() {
 		needsPlaceholder = true
 		needsPlaceholder = true
 		defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface())
 		defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface())
 
 

+ 627 - 0
vendor/github.com/urfave/cli/flag_generated.go

@@ -0,0 +1,627 @@
+package cli
+
+import (
+	"flag"
+	"strconv"
+	"time"
+)
+
+// WARNING: This file is generated!
+
+// BoolFlag is a flag with type bool
+type BoolFlag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Destination *bool
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f BoolFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f BoolFlag) GetName() string {
+	return f.Name
+}
+
+// Bool looks up the value of a local BoolFlag, returns
+// false if not found
+func (c *Context) Bool(name string) bool {
+	return lookupBool(name, c.flagSet)
+}
+
+// GlobalBool looks up the value of a global BoolFlag, returns
+// false if not found
+func (c *Context) GlobalBool(name string) bool {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupBool(name, fs)
+	}
+	return false
+}
+
+func lookupBool(name string, set *flag.FlagSet) bool {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := strconv.ParseBool(f.Value.String())
+		if err != nil {
+			return false
+		}
+		return parsed
+	}
+	return false
+}
+
+// BoolTFlag is a flag with type bool that is true by default
+type BoolTFlag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Destination *bool
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f BoolTFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f BoolTFlag) GetName() string {
+	return f.Name
+}
+
+// BoolT looks up the value of a local BoolTFlag, returns
+// false if not found
+func (c *Context) BoolT(name string) bool {
+	return lookupBoolT(name, c.flagSet)
+}
+
+// GlobalBoolT looks up the value of a global BoolTFlag, returns
+// false if not found
+func (c *Context) GlobalBoolT(name string) bool {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupBoolT(name, fs)
+	}
+	return false
+}
+
+func lookupBoolT(name string, set *flag.FlagSet) bool {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := strconv.ParseBool(f.Value.String())
+		if err != nil {
+			return false
+		}
+		return parsed
+	}
+	return false
+}
+
+// DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration)
+type DurationFlag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Value       time.Duration
+	Destination *time.Duration
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f DurationFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f DurationFlag) GetName() string {
+	return f.Name
+}
+
+// Duration looks up the value of a local DurationFlag, returns
+// 0 if not found
+func (c *Context) Duration(name string) time.Duration {
+	return lookupDuration(name, c.flagSet)
+}
+
+// GlobalDuration looks up the value of a global DurationFlag, returns
+// 0 if not found
+func (c *Context) GlobalDuration(name string) time.Duration {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupDuration(name, fs)
+	}
+	return 0
+}
+
+func lookupDuration(name string, set *flag.FlagSet) time.Duration {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := time.ParseDuration(f.Value.String())
+		if err != nil {
+			return 0
+		}
+		return parsed
+	}
+	return 0
+}
+
+// Float64Flag is a flag with type float64
+type Float64Flag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Value       float64
+	Destination *float64
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f Float64Flag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f Float64Flag) GetName() string {
+	return f.Name
+}
+
+// Float64 looks up the value of a local Float64Flag, returns
+// 0 if not found
+func (c *Context) Float64(name string) float64 {
+	return lookupFloat64(name, c.flagSet)
+}
+
+// GlobalFloat64 looks up the value of a global Float64Flag, returns
+// 0 if not found
+func (c *Context) GlobalFloat64(name string) float64 {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupFloat64(name, fs)
+	}
+	return 0
+}
+
+func lookupFloat64(name string, set *flag.FlagSet) float64 {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := strconv.ParseFloat(f.Value.String(), 64)
+		if err != nil {
+			return 0
+		}
+		return parsed
+	}
+	return 0
+}
+
+// GenericFlag is a flag with type Generic
+type GenericFlag struct {
+	Name   string
+	Usage  string
+	EnvVar string
+	Hidden bool
+	Value  Generic
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f GenericFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f GenericFlag) GetName() string {
+	return f.Name
+}
+
+// Generic looks up the value of a local GenericFlag, returns
+// nil if not found
+func (c *Context) Generic(name string) interface{} {
+	return lookupGeneric(name, c.flagSet)
+}
+
+// GlobalGeneric looks up the value of a global GenericFlag, returns
+// nil if not found
+func (c *Context) GlobalGeneric(name string) interface{} {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupGeneric(name, fs)
+	}
+	return nil
+}
+
+func lookupGeneric(name string, set *flag.FlagSet) interface{} {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := f.Value, error(nil)
+		if err != nil {
+			return nil
+		}
+		return parsed
+	}
+	return nil
+}
+
+// Int64Flag is a flag with type int64
+type Int64Flag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Value       int64
+	Destination *int64
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f Int64Flag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f Int64Flag) GetName() string {
+	return f.Name
+}
+
+// Int64 looks up the value of a local Int64Flag, returns
+// 0 if not found
+func (c *Context) Int64(name string) int64 {
+	return lookupInt64(name, c.flagSet)
+}
+
+// GlobalInt64 looks up the value of a global Int64Flag, returns
+// 0 if not found
+func (c *Context) GlobalInt64(name string) int64 {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupInt64(name, fs)
+	}
+	return 0
+}
+
+func lookupInt64(name string, set *flag.FlagSet) int64 {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
+		if err != nil {
+			return 0
+		}
+		return parsed
+	}
+	return 0
+}
+
+// IntFlag is a flag with type int
+type IntFlag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Value       int
+	Destination *int
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f IntFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f IntFlag) GetName() string {
+	return f.Name
+}
+
+// Int looks up the value of a local IntFlag, returns
+// 0 if not found
+func (c *Context) Int(name string) int {
+	return lookupInt(name, c.flagSet)
+}
+
+// GlobalInt looks up the value of a global IntFlag, returns
+// 0 if not found
+func (c *Context) GlobalInt(name string) int {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupInt(name, fs)
+	}
+	return 0
+}
+
+func lookupInt(name string, set *flag.FlagSet) int {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
+		if err != nil {
+			return 0
+		}
+		return int(parsed)
+	}
+	return 0
+}
+
+// IntSliceFlag is a flag with type *IntSlice
+type IntSliceFlag struct {
+	Name   string
+	Usage  string
+	EnvVar string
+	Hidden bool
+	Value  *IntSlice
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f IntSliceFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f IntSliceFlag) GetName() string {
+	return f.Name
+}
+
+// IntSlice looks up the value of a local IntSliceFlag, returns
+// nil if not found
+func (c *Context) IntSlice(name string) []int {
+	return lookupIntSlice(name, c.flagSet)
+}
+
+// GlobalIntSlice looks up the value of a global IntSliceFlag, returns
+// nil if not found
+func (c *Context) GlobalIntSlice(name string) []int {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupIntSlice(name, fs)
+	}
+	return nil
+}
+
+func lookupIntSlice(name string, set *flag.FlagSet) []int {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := (f.Value.(*IntSlice)).Value(), error(nil)
+		if err != nil {
+			return nil
+		}
+		return parsed
+	}
+	return nil
+}
+
+// Int64SliceFlag is a flag with type *Int64Slice
+type Int64SliceFlag struct {
+	Name   string
+	Usage  string
+	EnvVar string
+	Hidden bool
+	Value  *Int64Slice
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f Int64SliceFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f Int64SliceFlag) GetName() string {
+	return f.Name
+}
+
+// Int64Slice looks up the value of a local Int64SliceFlag, returns
+// nil if not found
+func (c *Context) Int64Slice(name string) []int64 {
+	return lookupInt64Slice(name, c.flagSet)
+}
+
+// GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns
+// nil if not found
+func (c *Context) GlobalInt64Slice(name string) []int64 {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupInt64Slice(name, fs)
+	}
+	return nil
+}
+
+func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := (f.Value.(*Int64Slice)).Value(), error(nil)
+		if err != nil {
+			return nil
+		}
+		return parsed
+	}
+	return nil
+}
+
+// StringFlag is a flag with type string
+type StringFlag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Value       string
+	Destination *string
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f StringFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f StringFlag) GetName() string {
+	return f.Name
+}
+
+// String looks up the value of a local StringFlag, returns
+// "" if not found
+func (c *Context) String(name string) string {
+	return lookupString(name, c.flagSet)
+}
+
+// GlobalString looks up the value of a global StringFlag, returns
+// "" if not found
+func (c *Context) GlobalString(name string) string {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupString(name, fs)
+	}
+	return ""
+}
+
+func lookupString(name string, set *flag.FlagSet) string {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := f.Value.String(), error(nil)
+		if err != nil {
+			return ""
+		}
+		return parsed
+	}
+	return ""
+}
+
+// StringSliceFlag is a flag with type *StringSlice
+type StringSliceFlag struct {
+	Name   string
+	Usage  string
+	EnvVar string
+	Hidden bool
+	Value  *StringSlice
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f StringSliceFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f StringSliceFlag) GetName() string {
+	return f.Name
+}
+
+// StringSlice looks up the value of a local StringSliceFlag, returns
+// nil if not found
+func (c *Context) StringSlice(name string) []string {
+	return lookupStringSlice(name, c.flagSet)
+}
+
+// GlobalStringSlice looks up the value of a global StringSliceFlag, returns
+// nil if not found
+func (c *Context) GlobalStringSlice(name string) []string {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupStringSlice(name, fs)
+	}
+	return nil
+}
+
+func lookupStringSlice(name string, set *flag.FlagSet) []string {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := (f.Value.(*StringSlice)).Value(), error(nil)
+		if err != nil {
+			return nil
+		}
+		return parsed
+	}
+	return nil
+}
+
+// Uint64Flag is a flag with type uint64
+type Uint64Flag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Value       uint64
+	Destination *uint64
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f Uint64Flag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f Uint64Flag) GetName() string {
+	return f.Name
+}
+
+// Uint64 looks up the value of a local Uint64Flag, returns
+// 0 if not found
+func (c *Context) Uint64(name string) uint64 {
+	return lookupUint64(name, c.flagSet)
+}
+
+// GlobalUint64 looks up the value of a global Uint64Flag, returns
+// 0 if not found
+func (c *Context) GlobalUint64(name string) uint64 {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupUint64(name, fs)
+	}
+	return 0
+}
+
+func lookupUint64(name string, set *flag.FlagSet) uint64 {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
+		if err != nil {
+			return 0
+		}
+		return parsed
+	}
+	return 0
+}
+
+// UintFlag is a flag with type uint
+type UintFlag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Hidden      bool
+	Value       uint
+	Destination *uint
+}
+
+// String returns a readable representation of this value
+// (for usage defaults)
+func (f UintFlag) String() string {
+	return FlagStringer(f)
+}
+
+// GetName returns the name of the flag
+func (f UintFlag) GetName() string {
+	return f.Name
+}
+
+// Uint looks up the value of a local UintFlag, returns
+// 0 if not found
+func (c *Context) Uint(name string) uint {
+	return lookupUint(name, c.flagSet)
+}
+
+// GlobalUint looks up the value of a global UintFlag, returns
+// 0 if not found
+func (c *Context) GlobalUint(name string) uint {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupUint(name, fs)
+	}
+	return 0
+}
+
+func lookupUint(name string, set *flag.FlagSet) uint {
+	f := set.Lookup(name)
+	if f != nil {
+		parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
+		if err != nil {
+			return 0
+		}
+		return uint(parsed)
+	}
+	return 0
+}

+ 105 - 34
vendor/github.com/urfave/cli/help.go

@@ -13,27 +13,31 @@ import (
 // cli.go uses text/template to render templates. You can
 // cli.go uses text/template to render templates. You can
 // render custom help text by setting this variable.
 // render custom help text by setting this variable.
 var AppHelpTemplate = `NAME:
 var AppHelpTemplate = `NAME:
-   {{.Name}} - {{.Usage}}
+   {{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
 
 
 USAGE:
 USAGE:
-   {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
-   {{if .Version}}{{if not .HideVersion}}
+   {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
+
 VERSION:
 VERSION:
-   {{.Version}}
-   {{end}}{{end}}{{if len .Authors}}
-AUTHOR(S):
-   {{range .Authors}}{{.}}{{end}}
-   {{end}}{{if .VisibleCommands}}
+   {{.Version}}{{end}}{{end}}{{if .Description}}
+
+DESCRIPTION:
+   {{.Description}}{{end}}{{if len .Authors}}
+
+AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
+   {{range $index, $author := .Authors}}{{if $index}}
+   {{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
+
 COMMANDS:{{range .VisibleCategories}}{{if .Name}}
 COMMANDS:{{range .VisibleCategories}}{{if .Name}}
    {{.Name}}:{{end}}{{range .VisibleCommands}}
    {{.Name}}:{{end}}{{range .VisibleCommands}}
-     {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}
-{{end}}{{end}}{{if .VisibleFlags}}
+     {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
+
 GLOBAL OPTIONS:
 GLOBAL OPTIONS:
-   {{range .VisibleFlags}}{{.}}
-   {{end}}{{end}}{{if .Copyright}}
+   {{range $index, $option := .VisibleFlags}}{{if $index}}
+   {{end}}{{$option}}{{end}}{{end}}{{if .Copyright}}
+
 COPYRIGHT:
 COPYRIGHT:
-   {{.Copyright}}
-   {{end}}
+   {{.Copyright}}{{end}}
 `
 `
 
 
 // CommandHelpTemplate is the text template for the command help topic.
 // CommandHelpTemplate is the text template for the command help topic.
@@ -43,7 +47,7 @@ var CommandHelpTemplate = `NAME:
    {{.HelpName}} - {{.Usage}}
    {{.HelpName}} - {{.Usage}}
 
 
 USAGE:
 USAGE:
-   {{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}}
+   {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
 
 
 CATEGORY:
 CATEGORY:
    {{.Category}}{{end}}{{if .Description}}
    {{.Category}}{{end}}{{if .Description}}
@@ -60,10 +64,10 @@ OPTIONS:
 // cli.go uses text/template to render templates. You can
 // cli.go uses text/template to render templates. You can
 // render custom help text by setting this variable.
 // render custom help text by setting this variable.
 var SubcommandHelpTemplate = `NAME:
 var SubcommandHelpTemplate = `NAME:
-   {{.HelpName}} - {{.Usage}}
+   {{.HelpName}} - {{if .Description}}{{.Description}}{{else}}{{.Usage}}{{end}}
 
 
 USAGE:
 USAGE:
-   {{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
+   {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
 
 
 COMMANDS:{{range .VisibleCategories}}{{if .Name}}
 COMMANDS:{{range .VisibleCategories}}{{if .Name}}
    {{.Name}}:{{end}}{{range .VisibleCommands}}
    {{.Name}}:{{end}}{{range .VisibleCommands}}
@@ -108,17 +112,42 @@ var helpSubcommand = Command{
 // Prints help for the App or Command
 // Prints help for the App or Command
 type helpPrinter func(w io.Writer, templ string, data interface{})
 type helpPrinter func(w io.Writer, templ string, data interface{})
 
 
+// Prints help for the App or Command with custom template function.
+type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{})
+
 // HelpPrinter is a function that writes the help output. If not set a default
 // HelpPrinter is a function that writes the help output. If not set a default
 // is used. The function signature is:
 // is used. The function signature is:
 // func(w io.Writer, templ string, data interface{})
 // func(w io.Writer, templ string, data interface{})
 var HelpPrinter helpPrinter = printHelp
 var HelpPrinter helpPrinter = printHelp
 
 
+// HelpPrinterCustom is same as HelpPrinter but
+// takes a custom function for template function map.
+var HelpPrinterCustom helpPrinterCustom = printHelpCustom
+
 // VersionPrinter prints the version for the App
 // VersionPrinter prints the version for the App
 var VersionPrinter = printVersion
 var VersionPrinter = printVersion
 
 
+// ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code.
+func ShowAppHelpAndExit(c *Context, exitCode int) {
+	ShowAppHelp(c)
+	os.Exit(exitCode)
+}
+
 // ShowAppHelp is an action that displays the help.
 // ShowAppHelp is an action that displays the help.
-func ShowAppHelp(c *Context) error {
-	HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
+func ShowAppHelp(c *Context) (err error) {
+	if c.App.CustomAppHelpTemplate == "" {
+		HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
+		return
+	}
+	customAppData := func() map[string]interface{} {
+		if c.App.ExtraInfo == nil {
+			return nil
+		}
+		return map[string]interface{}{
+			"ExtraInfo": c.App.ExtraInfo,
+		}
+	}
+	HelpPrinterCustom(c.App.Writer, c.App.CustomAppHelpTemplate, c.App, customAppData())
 	return nil
 	return nil
 }
 }
 
 
@@ -134,6 +163,12 @@ func DefaultAppComplete(c *Context) {
 	}
 	}
 }
 }
 
 
+// ShowCommandHelpAndExit - exits with code after showing help
+func ShowCommandHelpAndExit(c *Context, command string, code int) {
+	ShowCommandHelp(c, command)
+	os.Exit(code)
+}
+
 // ShowCommandHelp prints help for the given command
 // ShowCommandHelp prints help for the given command
 func ShowCommandHelp(ctx *Context, command string) error {
 func ShowCommandHelp(ctx *Context, command string) error {
 	// show the subcommand help for a command with subcommands
 	// show the subcommand help for a command with subcommands
@@ -144,7 +179,11 @@ func ShowCommandHelp(ctx *Context, command string) error {
 
 
 	for _, c := range ctx.App.Commands {
 	for _, c := range ctx.App.Commands {
 		if c.HasName(command) {
 		if c.HasName(command) {
-			HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
+			if c.CustomHelpTemplate != "" {
+				HelpPrinterCustom(ctx.App.Writer, c.CustomHelpTemplate, c, nil)
+			} else {
+				HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
+			}
 			return nil
 			return nil
 		}
 		}
 	}
 	}
@@ -187,10 +226,15 @@ func ShowCommandCompletions(ctx *Context, command string) {
 	}
 	}
 }
 }
 
 
-func printHelp(out io.Writer, templ string, data interface{}) {
+func printHelpCustom(out io.Writer, templ string, data interface{}, customFunc map[string]interface{}) {
 	funcMap := template.FuncMap{
 	funcMap := template.FuncMap{
 		"join": strings.Join,
 		"join": strings.Join,
 	}
 	}
+	if customFunc != nil {
+		for key, value := range customFunc {
+			funcMap[key] = value
+		}
+	}
 
 
 	w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
 	w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
 	t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
 	t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
@@ -206,10 +250,14 @@ func printHelp(out io.Writer, templ string, data interface{}) {
 	w.Flush()
 	w.Flush()
 }
 }
 
 
+func printHelp(out io.Writer, templ string, data interface{}) {
+	printHelpCustom(out, templ, data, nil)
+}
+
 func checkVersion(c *Context) bool {
 func checkVersion(c *Context) bool {
 	found := false
 	found := false
-	if VersionFlag.Name != "" {
-		eachName(VersionFlag.Name, func(name string) {
+	if VersionFlag.GetName() != "" {
+		eachName(VersionFlag.GetName(), func(name string) {
 			if c.GlobalBool(name) || c.Bool(name) {
 			if c.GlobalBool(name) || c.Bool(name) {
 				found = true
 				found = true
 			}
 			}
@@ -220,8 +268,8 @@ func checkVersion(c *Context) bool {
 
 
 func checkHelp(c *Context) bool {
 func checkHelp(c *Context) bool {
 	found := false
 	found := false
-	if HelpFlag.Name != "" {
-		eachName(HelpFlag.Name, func(name string) {
+	if HelpFlag.GetName() != "" {
+		eachName(HelpFlag.GetName(), func(name string) {
 			if c.GlobalBool(name) || c.Bool(name) {
 			if c.GlobalBool(name) || c.Bool(name) {
 				found = true
 				found = true
 			}
 			}
@@ -240,7 +288,7 @@ func checkCommandHelp(c *Context, name string) bool {
 }
 }
 
 
 func checkSubcommandHelp(c *Context) bool {
 func checkSubcommandHelp(c *Context) bool {
-	if c.GlobalBool("h") || c.GlobalBool("help") {
+	if c.Bool("h") || c.Bool("help") {
 		ShowSubcommandHelp(c)
 		ShowSubcommandHelp(c)
 		return true
 		return true
 	}
 	}
@@ -248,20 +296,43 @@ func checkSubcommandHelp(c *Context) bool {
 	return false
 	return false
 }
 }
 
 
+func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
+	if !a.EnableBashCompletion {
+		return false, arguments
+	}
+
+	pos := len(arguments) - 1
+	lastArg := arguments[pos]
+
+	if lastArg != "--"+BashCompletionFlag.GetName() {
+		return false, arguments
+	}
+
+	return true, arguments[:pos]
+}
+
 func checkCompletions(c *Context) bool {
 func checkCompletions(c *Context) bool {
-	if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion {
-		ShowCompletions(c)
-		return true
+	if !c.shellComplete {
+		return false
 	}
 	}
 
 
-	return false
+	if args := c.Args(); args.Present() {
+		name := args.First()
+		if cmd := c.App.Command(name); cmd != nil {
+			// let the command handle the completion
+			return false
+		}
+	}
+
+	ShowCompletions(c)
+	return true
 }
 }
 
 
 func checkCommandCompletions(c *Context, name string) bool {
 func checkCommandCompletions(c *Context, name string) bool {
-	if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
-		ShowCommandCompletions(c, name)
-		return true
+	if !c.shellComplete {
+		return false
 	}
 	}
 
 
-	return false
+	ShowCommandCompletions(c, name)
+	return true
 }
 }

Some files were not shown because too many files changed in this diff