summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/text/message
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2018-04-16 05:37:14 -0700
committerJoram Wilander <jwawilander@gmail.com>2018-04-16 08:37:14 -0400
commit6e2cb00008cbf09e556b00f87603797fcaa47e09 (patch)
tree3c0eb55ff4226a3f024aad373140d1fb860a6404 /vendor/golang.org/x/text/message
parentbf24f51c4e1cc6286885460672f7f449e8c6f5ef (diff)
downloadchat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.gz
chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.bz2
chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.zip
Depenancy upgrades and movign to dep. (#8630)
Diffstat (limited to 'vendor/golang.org/x/text/message')
-rw-r--r--vendor/golang.org/x/text/message/catalog.go36
-rw-r--r--vendor/golang.org/x/text/message/catalog/catalog.go369
-rw-r--r--vendor/golang.org/x/text/message/catalog/catalog_test.go296
-rw-r--r--vendor/golang.org/x/text/message/catalog/dict.go129
-rw-r--r--vendor/golang.org/x/text/message/catalog/go19.go15
-rw-r--r--vendor/golang.org/x/text/message/catalog/gopre19.go23
-rw-r--r--vendor/golang.org/x/text/message/catalog_test.go43
-rw-r--r--vendor/golang.org/x/text/message/doc.go100
-rw-r--r--vendor/golang.org/x/text/message/examples_test.go42
-rw-r--r--vendor/golang.org/x/text/message/fmt_test.go1871
-rw-r--r--vendor/golang.org/x/text/message/format.go510
-rw-r--r--vendor/golang.org/x/text/message/message.go186
-rw-r--r--vendor/golang.org/x/text/message/message_test.go181
-rw-r--r--vendor/golang.org/x/text/message/pipeline/extract.go314
-rw-r--r--vendor/golang.org/x/text/message/pipeline/generate.go314
-rw-r--r--vendor/golang.org/x/text/message/pipeline/go19_test.go13
-rw-r--r--vendor/golang.org/x/text/message/pipeline/message.go241
-rw-r--r--vendor/golang.org/x/text/message/pipeline/pipeline.go422
-rw-r--r--vendor/golang.org/x/text/message/pipeline/pipeline_test.go126
-rw-r--r--vendor/golang.org/x/text/message/pipeline/rewrite.go268
-rw-r--r--vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go85
-rw-r--r--vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go.want85
-rw-r--r--vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_test.go49
-rw-r--r--vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json188
-rw-r--r--vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json.want188
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/messages.gotext.json123
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/out.gotext.json137
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/out.gotext.json.want137
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/messages.gotext.json91
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/out.gotext.json154
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/out.gotext.json.want154
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/messages.gotext.json135
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/out.gotext.json137
-rwxr-xr-xvendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/out.gotext.json.want137
-rw-r--r--vendor/golang.org/x/text/message/pipeline/testdata/test1/test1.go75
-rw-r--r--vendor/golang.org/x/text/message/print.go979
36 files changed, 0 insertions, 8353 deletions
diff --git a/vendor/golang.org/x/text/message/catalog.go b/vendor/golang.org/x/text/message/catalog.go
deleted file mode 100644
index 068271def..000000000
--- a/vendor/golang.org/x/text/message/catalog.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package message
-
-// TODO: some types in this file will need to be made public at some time.
-// Documentation and method names will reflect this by using the exported name.
-
-import (
- "golang.org/x/text/language"
- "golang.org/x/text/message/catalog"
-)
-
-// MatchLanguage reports the matched tag obtained from language.MatchStrings for
-// the Matcher of the DefaultCatalog.
-func MatchLanguage(preferred ...string) language.Tag {
- c := DefaultCatalog
- tag, _ := language.MatchStrings(c.Matcher(), preferred...)
- return tag
-}
-
-// DefaultCatalog is used by SetString.
-var DefaultCatalog catalog.Catalog = defaultCatalog
-
-var defaultCatalog = catalog.NewBuilder()
-
-// SetString calls SetString on the initial default Catalog.
-func SetString(tag language.Tag, key string, msg string) error {
- return defaultCatalog.SetString(tag, key, msg)
-}
-
-// Set calls Set on the initial default Catalog.
-func Set(tag language.Tag, key string, msg ...catalog.Message) error {
- return defaultCatalog.Set(tag, key, msg...)
-}
diff --git a/vendor/golang.org/x/text/message/catalog/catalog.go b/vendor/golang.org/x/text/message/catalog/catalog.go
deleted file mode 100644
index 34a30d3c8..000000000
--- a/vendor/golang.org/x/text/message/catalog/catalog.go
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package catalog defines collections of translated format strings.
-//
-// This package mostly defines types for populating catalogs with messages. The
-// catmsg package contains further definitions for creating custom message and
-// dictionary types as well as packages that use Catalogs.
-//
-// Package catalog defines various interfaces: Dictionary, Loader, and Message.
-// A Dictionary maintains a set of translations of format strings for a single
-// language. The Loader interface defines a source of dictionaries. A
-// translation of a format string is represented by a Message.
-//
-//
-// Catalogs
-//
-// A Catalog defines a programmatic interface for setting message translations.
-// It maintains a set of per-language dictionaries with translations for a set
-// of keys. For message translation to function properly, a translation should
-// be defined for each key for each supported language. A dictionary may be
-// underspecified, though, if there is a parent language that already defines
-// the key. For example, a Dictionary for "en-GB" could leave out entries that
-// are identical to those in a dictionary for "en".
-//
-//
-// Messages
-//
-// A Message is a format string which varies on the value of substitution
-// variables. For instance, to indicate the number of results one could want "no
-// results" if there are none, "1 result" if there is 1, and "%d results" for
-// any other number. Catalog is agnostic to the kind of format strings that are
-// used: for instance, messages can follow either the printf-style substitution
-// from package fmt or use templates.
-//
-// A Message does not substitute arguments in the format string. This job is
-// reserved for packages that render strings, such as message, that use Catalogs
-// to selected string. This separation of concerns allows Catalog to be used to
-// store any kind of formatting strings.
-//
-//
-// Selecting messages based on linguistic features of substitution arguments
-//
-// Messages may vary based on any linguistic features of the argument values.
-// The most common one is plural form, but others exist.
-//
-// Selection messages are provided in packages that provide support for a
-// specific linguistic feature. The following snippet uses plural.Select:
-//
-// catalog.Set(language.English, "You are %d minute(s) late.",
-// plural.Select(1,
-// "one", "You are 1 minute late.",
-// "other", "You are %d minutes late."))
-//
-// In this example, a message is stored in the Catalog where one of two messages
-// is selected based on the first argument, a number. The first message is
-// selected if the argument is singular (identified by the selector "one") and
-// the second message is selected in all other cases. The selectors are defined
-// by the plural rules defined in CLDR. The selector "other" is special and will
-// always match. Each language always defines one of the linguistic categories
-// to be "other." For English, singular is "one" and plural is "other".
-//
-// Selects can be nested. This allows selecting sentences based on features of
-// multiple arguments or multiple linguistic properties of a single argument.
-//
-//
-// String interpolation
-//
-// There is often a lot of commonality between the possible variants of a
-// message. For instance, in the example above the word "minute" varies based on
-// the plural catogory of the argument, but the rest of the sentence is
-// identical. Using interpolation the above message can be rewritten as:
-//
-// catalog.Set(language.English, "You are %d minute(s) late.",
-// catalog.Var("minutes",
-// plural.Select(1, "one", "minute", "other", "minutes")),
-// catalog.String("You are %[1]d ${minutes} late."))
-//
-// Var is defined to return the variable name if the message does not yield a
-// match. This allows us to further simplify this snippet to
-//
-// catalog.Set(language.English, "You are %d minute(s) late.",
-// catalog.Var("minutes", plural.Select(1, "one", "minute")),
-// catalog.String("You are %d ${minutes} late."))
-//
-// Overall this is still only a minor improvement, but things can get a lot more
-// unwieldy if more than one linguistic feature is used to determine a message
-// variant. Consider the following example:
-//
-// // argument 1: list of hosts, argument 2: list of guests
-// catalog.Set(language.English, "%[1]v invite(s) %[2]v to their party.",
-// catalog.Var("their",
-// plural.Select(1,
-// "one", gender.Select(1, "female", "her", "other", "his"))),
-// catalog.Var("invites", plural.Select(1, "one", "invite"))
-// catalog.String("%[1]v ${invites} %[2]v to ${their} party.")),
-//
-// Without variable substitution, this would have to be written as
-//
-// // argument 1: list of hosts, argument 2: list of guests
-// catalog.Set(language.English, "%[1]v invite(s) %[2]v to their party.",
-// plural.Select(1,
-// "one", gender.Select(1,
-// "female", "%[1]v invites %[2]v to her party."
-// "other", "%[1]v invites %[2]v to his party."),
-// "other", "%[1]v invites %[2]v to their party.")
-//
-// Not necessarily shorter, but using variables there is less duplication and
-// the messages are more maintenance friendly. Moreover, languages may have up
-// to six plural forms. This makes the use of variables more welcome.
-//
-// Different messages using the same inflections can reuse variables by moving
-// them to macros. Using macros we can rewrite the message as:
-//
-// // argument 1: list of hosts, argument 2: list of guests
-// catalog.SetString(language.English, "%[1]v invite(s) %[2]v to their party.",
-// "%[1]v ${invites(1)} %[2]v to ${their(1)} party.")
-//
-// Where the following macros were defined separately.
-//
-// catalog.SetMacro(language.English, "invites", plural.Select(1, "one", "invite"))
-// catalog.SetMacro(language.English, "their", plural.Select(1,
-// "one", gender.Select(1, "female", "her", "other", "his"))),
-//
-// Placeholders use parentheses and the arguments to invoke a macro.
-//
-//
-// Looking up messages
-//
-// Message lookup using Catalogs is typically only done by specialized packages
-// and is not something the user should be concerned with. For instance, to
-// express the tardiness of a user using the related message we defined earlier,
-// the user may use the package message like so:
-//
-// p := message.NewPrinter(language.English)
-// p.Printf("You are %d minute(s) late.", 5)
-//
-// Which would print:
-// You are 5 minutes late.
-//
-//
-// This package is UNDER CONSTRUCTION and its API may change.
-package catalog // import "golang.org/x/text/message/catalog"
-
-// TODO:
-// Some way to freeze a catalog.
-// - Locking on each lockup turns out to be about 50% of the total running time
-// for some of the benchmarks in the message package.
-// Consider these:
-// - Sequence type to support sequences in user-defined messages.
-// - Garbage collection: Remove dictionaries that can no longer be reached
-// as other dictionaries have been added that cover all possible keys.
-
-import (
- "errors"
- "fmt"
-
- "golang.org/x/text/internal"
-
- "golang.org/x/text/internal/catmsg"
- "golang.org/x/text/language"
-)
-
-// A Catalog allows lookup of translated messages.
-type Catalog interface {
- // Languages returns all languages for which the Catalog contains variants.
- Languages() []language.Tag
-
- // Matcher returns a Matcher for languages from this Catalog.
- Matcher() language.Matcher
-
- // A Context is used for evaluating Messages.
- Context(tag language.Tag, r catmsg.Renderer) *Context
-
- // This method also makes Catalog a private interface.
- lookup(tag language.Tag, key string) (data string, ok bool)
-}
-
-// NewFromMap creates a Catalog from the given map. If a Dictionary is
-// underspecified the entry is retrieved from a parent language.
-func NewFromMap(dictionaries map[string]Dictionary, opts ...Option) (Catalog, error) {
- options := options{}
- for _, o := range opts {
- o(&options)
- }
- c := &catalog{
- dicts: map[language.Tag]Dictionary{},
- }
- _, hasFallback := dictionaries[options.fallback.String()]
- if hasFallback {
- // TODO: Should it be okay to not have a fallback language?
- // Catalog generators could enforce there is always a fallback.
- c.langs = append(c.langs, options.fallback)
- }
- for lang, dict := range dictionaries {
- tag, err := language.Parse(lang)
- if err != nil {
- return nil, fmt.Errorf("catalog: invalid language tag %q", lang)
- }
- if _, ok := c.dicts[tag]; ok {
- return nil, fmt.Errorf("catalog: duplicate entry for tag %q after normalization", tag)
- }
- c.dicts[tag] = dict
- if !hasFallback || tag != options.fallback {
- c.langs = append(c.langs, tag)
- }
- }
- if hasFallback {
- internal.SortTags(c.langs[1:])
- } else {
- internal.SortTags(c.langs)
- }
- c.matcher = language.NewMatcher(c.langs)
- return c, nil
-}
-
-// A Dictionary is a source of translations for a single language.
-type Dictionary interface {
- // Lookup returns a message compiled with catmsg.Compile for the given key.
- // It returns false for ok if such a message could not be found.
- Lookup(key string) (data string, ok bool)
-}
-
-type catalog struct {
- langs []language.Tag
- dicts map[language.Tag]Dictionary
- macros store
- matcher language.Matcher
-}
-
-func (c *catalog) Languages() []language.Tag { return c.langs }
-func (c *catalog) Matcher() language.Matcher { return c.matcher }
-
-func (c *catalog) lookup(tag language.Tag, key string) (data string, ok bool) {
- for ; ; tag = tag.Parent() {
- if dict, ok := c.dicts[tag]; ok {
- if data, ok := dict.Lookup(key); ok {
- return data, true
- }
- }
- if tag == language.Und {
- break
- }
- }
- return "", false
-}
-
-// Context returns a Context for formatting messages.
-// Only one Message may be formatted per context at any given time.
-func (c *catalog) Context(tag language.Tag, r catmsg.Renderer) *Context {
- return &Context{
- cat: c,
- tag: tag,
- dec: catmsg.NewDecoder(tag, r, &dict{&c.macros, tag}),
- }
-}
-
-// A Builder allows building a Catalog programmatically.
-type Builder struct {
- options
- matcher language.Matcher
-
- index store
- macros store
-}
-
-type options struct {
- fallback language.Tag
-}
-
-// An Option configures Catalog behavior.
-type Option func(*options)
-
-// Fallback specifies the default fallback language. The default is Und.
-func Fallback(tag language.Tag) Option {
- return func(o *options) { o.fallback = tag }
-}
-
-// TODO:
-// // Catalogs specifies one or more sources for a Catalog.
-// // Lookups are in order.
-// // This can be changed inserting a Catalog used for setting, which implements
-// // Loader, used for setting in the chain.
-// func Catalogs(d ...Loader) Option {
-// return nil
-// }
-//
-// func Delims(start, end string) Option {}
-//
-// func Dict(tag language.Tag, d ...Dictionary) Option
-
-// NewBuilder returns an empty mutable Catalog.
-func NewBuilder(opts ...Option) *Builder {
- c := &Builder{}
- for _, o := range opts {
- o(&c.options)
- }
- return c
-}
-
-// SetString is shorthand for Set(tag, key, String(msg)).
-func (c *Builder) SetString(tag language.Tag, key string, msg string) error {
- return c.set(tag, key, &c.index, String(msg))
-}
-
-// Set sets the translation for the given language and key.
-//
-// When evaluation this message, the first Message in the sequence to msgs to
-// evaluate to a string will be the message returned.
-func (c *Builder) Set(tag language.Tag, key string, msg ...Message) error {
- return c.set(tag, key, &c.index, msg...)
-}
-
-// SetMacro defines a Message that may be substituted in another message.
-// The arguments to a macro Message are passed as arguments in the
-// placeholder the form "${foo(arg1, arg2)}".
-func (c *Builder) SetMacro(tag language.Tag, name string, msg ...Message) error {
- return c.set(tag, name, &c.macros, msg...)
-}
-
-// ErrNotFound indicates there was no message for the given key.
-var ErrNotFound = errors.New("catalog: message not found")
-
-// String specifies a plain message string. It can be used as fallback if no
-// other strings match or as a simple standalone message.
-//
-// It is an error to pass more than one String in a message sequence.
-func String(name string) Message {
- return catmsg.String(name)
-}
-
-// Var sets a variable that may be substituted in formatting patterns using
-// named substitution of the form "${name}". The name argument is used as a
-// fallback if the statements do not produce a match. The statement sequence may
-// not contain any Var calls.
-//
-// The name passed to a Var must be unique within message sequence.
-func Var(name string, msg ...Message) Message {
- return &catmsg.Var{Name: name, Message: firstInSequence(msg)}
-}
-
-// Context returns a Context for formatting messages.
-// Only one Message may be formatted per context at any given time.
-func (b *Builder) Context(tag language.Tag, r catmsg.Renderer) *Context {
- return &Context{
- cat: b,
- tag: tag,
- dec: catmsg.NewDecoder(tag, r, &dict{&b.macros, tag}),
- }
-}
-
-// A Context is used for evaluating Messages.
-// Only one Message may be formatted per context at any given time.
-type Context struct {
- cat Catalog
- tag language.Tag // TODO: use compact index.
- dec *catmsg.Decoder
-}
-
-// Execute looks up and executes the message with the given key.
-// It returns ErrNotFound if no message could be found in the index.
-func (c *Context) Execute(key string) error {
- data, ok := c.cat.lookup(c.tag, key)
- if !ok {
- return ErrNotFound
- }
- return c.dec.Execute(data)
-}
diff --git a/vendor/golang.org/x/text/message/catalog/catalog_test.go b/vendor/golang.org/x/text/message/catalog/catalog_test.go
deleted file mode 100644
index 08bfdc7ce..000000000
--- a/vendor/golang.org/x/text/message/catalog/catalog_test.go
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package catalog
-
-import (
- "bytes"
- "path"
- "reflect"
- "strings"
- "testing"
-
- "golang.org/x/text/internal/catmsg"
- "golang.org/x/text/language"
-)
-
-type entry struct {
- tag, key string
- msg interface{}
-}
-
-func langs(s string) []language.Tag {
- t, _, _ := language.ParseAcceptLanguage(s)
- return t
-}
-
-type testCase struct {
- desc string
- cat []entry
- lookup []entry
- fallback string
- match []string
- tags []language.Tag
-}
-
-var testCases = []testCase{{
- desc: "empty catalog",
- lookup: []entry{
- {"en", "key", ""},
- {"en", "", ""},
- {"nl", "", ""},
- },
- match: []string{
- "gr -> und",
- "en-US -> und",
- "af -> und",
- },
- tags: nil, // not an empty list.
-}, {
- desc: "one entry",
- cat: []entry{
- {"en", "hello", "Hello!"},
- },
- lookup: []entry{
- {"und", "hello", ""},
- {"nl", "hello", ""},
- {"en", "hello", "Hello!"},
- {"en-US", "hello", "Hello!"},
- {"en-GB", "hello", "Hello!"},
- {"en-oxendict", "hello", "Hello!"},
- {"en-oxendict-u-ms-metric", "hello", "Hello!"},
- },
- match: []string{
- "gr -> en",
- "en-US -> en",
- },
- tags: langs("en"),
-}, {
- desc: "hierarchical languages",
- cat: []entry{
- {"en", "hello", "Hello!"},
- {"en-GB", "hello", "Hellø!"},
- {"en-US", "hello", "Howdy!"},
- {"en", "greetings", "Greetings!"},
- {"gsw", "hello", "Grüetzi!"},
- },
- lookup: []entry{
- {"und", "hello", ""},
- {"nl", "hello", ""},
- {"en", "hello", "Hello!"},
- {"en-US", "hello", "Howdy!"},
- {"en-GB", "hello", "Hellø!"},
- {"en-oxendict", "hello", "Hello!"},
- {"en-US-oxendict-u-ms-metric", "hello", "Howdy!"},
-
- {"und", "greetings", ""},
- {"nl", "greetings", ""},
- {"en", "greetings", "Greetings!"},
- {"en-US", "greetings", "Greetings!"},
- {"en-GB", "greetings", "Greetings!"},
- {"en-oxendict", "greetings", "Greetings!"},
- {"en-US-oxendict-u-ms-metric", "greetings", "Greetings!"},
- },
- fallback: "gsw",
- match: []string{
- "gr -> gsw",
- "en-US -> en-US",
- },
- tags: langs("gsw, en, en-GB, en-US"),
-}, {
- desc: "variables",
- cat: []entry{
- {"en", "hello %s", []Message{
- Var("person", String("Jane")),
- String("Hello ${person}!"),
- }},
- {"en", "hello error", []Message{
- Var("person", String("Jane")),
- noMatchMessage{}, // trigger sequence path.
- String("Hello ${person."),
- }},
- {"en", "fallback to var value", []Message{
- Var("you", noMatchMessage{}, noMatchMessage{}),
- String("Hello ${you}."),
- }},
- {"en", "scopes", []Message{
- Var("person1", String("Mark")),
- Var("person2", String("Jane")),
- Var("couple",
- Var("person1", String("Joe")),
- String("${person1} and ${person2}")),
- String("Hello ${couple}."),
- }},
- {"en", "missing var", String("Hello ${missing}.")},
- },
- lookup: []entry{
- {"en", "hello %s", "Hello Jane!"},
- {"en", "hello error", "Hello $!(MISSINGBRACE)"},
- {"en", "fallback to var value", "Hello you."},
- {"en", "scopes", "Hello Joe and Jane."},
- {"en", "missing var", "Hello missing."},
- },
- tags: langs("en"),
-}, {
- desc: "macros",
- cat: []entry{
- {"en", "macro1", String("Hello ${macro1(1)}.")},
- {"en", "macro2", String("Hello ${ macro1(2) }!")},
- {"en", "macroWS", String("Hello ${ macro1( 2 ) }!")},
- {"en", "missing", String("Hello ${ missing(1 }.")},
- {"en", "badnum", String("Hello ${ badnum(1b) }.")},
- {"en", "undefined", String("Hello ${ undefined(1) }.")},
- {"en", "macroU", String("Hello ${ macroU(2) }!")},
- },
- lookup: []entry{
- {"en", "macro1", "Hello Joe."},
- {"en", "macro2", "Hello Joe!"},
- {"en-US", "macroWS", "Hello Joe!"},
- {"en-NL", "missing", "Hello $!(MISSINGPAREN)."},
- {"en", "badnum", "Hello $!(BADNUM)."},
- {"en", "undefined", "Hello undefined."},
- {"en", "macroU", "Hello macroU!"},
- },
- tags: langs("en"),
-}}
-
-func setMacros(b *Builder) {
- b.SetMacro(language.English, "macro1", String("Joe"))
- b.SetMacro(language.Und, "macro2", String("${macro1(1)}"))
- b.SetMacro(language.English, "macroU", noMatchMessage{})
-}
-
-type buildFunc func(t *testing.T, tc testCase) Catalog
-
-func initBuilder(t *testing.T, tc testCase) Catalog {
- options := []Option{}
- if tc.fallback != "" {
- options = append(options, Fallback(language.MustParse(tc.fallback)))
- }
- cat := NewBuilder(options...)
- for _, e := range tc.cat {
- tag := language.MustParse(e.tag)
- switch msg := e.msg.(type) {
- case string:
-
- cat.SetString(tag, e.key, msg)
- case Message:
- cat.Set(tag, e.key, msg)
- case []Message:
- cat.Set(tag, e.key, msg...)
- }
- }
- setMacros(cat)
- return cat
-}
-
-type dictionary map[string]string
-
-func (d dictionary) Lookup(key string) (data string, ok bool) {
- data, ok = d[key]
- return data, ok
-}
-
-func initCatalog(t *testing.T, tc testCase) Catalog {
- m := map[string]Dictionary{}
- for _, e := range tc.cat {
- m[e.tag] = dictionary{}
- }
- for _, e := range tc.cat {
- var msg Message
- switch x := e.msg.(type) {
- case string:
- msg = String(x)
- case Message:
- msg = x
- case []Message:
- msg = firstInSequence(x)
- }
- data, _ := catmsg.Compile(language.MustParse(e.tag), nil, msg)
- m[e.tag].(dictionary)[e.key] = data
- }
- options := []Option{}
- if tc.fallback != "" {
- options = append(options, Fallback(language.MustParse(tc.fallback)))
- }
- c, err := NewFromMap(m, options...)
- if err != nil {
- t.Fatal(err)
- }
- // TODO: implement macros for fixed catalogs.
- b := NewBuilder()
- setMacros(b)
- c.(*catalog).macros.index = b.macros.index
- return c
-}
-
-func TestMatcher(t *testing.T) {
- test := func(t *testing.T, init buildFunc) {
- for _, tc := range testCases {
- for _, s := range tc.match {
- a := strings.Split(s, "->")
- t.Run(path.Join(tc.desc, a[0]), func(t *testing.T) {
- cat := init(t, tc)
- got, _ := language.MatchStrings(cat.Matcher(), a[0])
- want := language.MustParse(strings.TrimSpace(a[1]))
- if got != want {
- t.Errorf("got %q; want %q", got, want)
- }
- })
- }
- }
- }
- t.Run("Builder", func(t *testing.T) { test(t, initBuilder) })
- t.Run("Catalog", func(t *testing.T) { test(t, initCatalog) })
-}
-
-func TestCatalog(t *testing.T) {
- test := func(t *testing.T, init buildFunc) {
- for _, tc := range testCases {
- cat := init(t, tc)
- wantTags := tc.tags
- if got := cat.Languages(); !reflect.DeepEqual(got, wantTags) {
- t.Errorf("%s:Languages: got %v; want %v", tc.desc, got, wantTags)
- }
-
- for _, e := range tc.lookup {
- t.Run(path.Join(tc.desc, e.tag, e.key), func(t *testing.T) {
- tag := language.MustParse(e.tag)
- buf := testRenderer{}
- ctx := cat.Context(tag, &buf)
- want := e.msg.(string)
- err := ctx.Execute(e.key)
- gotFound := err != ErrNotFound
- wantFound := want != ""
- if gotFound != wantFound {
- t.Fatalf("err: got %v (%v); want %v", gotFound, err, wantFound)
- }
- if got := buf.buf.String(); got != want {
- t.Errorf("Lookup:\ngot %q\nwant %q", got, want)
- }
- })
- }
- }
- }
- t.Run("Builder", func(t *testing.T) { test(t, initBuilder) })
- t.Run("Catalog", func(t *testing.T) { test(t, initCatalog) })
-}
-
-type testRenderer struct {
- buf bytes.Buffer
-}
-
-func (f *testRenderer) Arg(i int) interface{} { return nil }
-func (f *testRenderer) Render(s string) { f.buf.WriteString(s) }
-
-var msgNoMatch = catmsg.Register("no match", func(d *catmsg.Decoder) bool {
- return false // no match
-})
-
-type noMatchMessage struct{}
-
-func (noMatchMessage) Compile(e *catmsg.Encoder) error {
- e.EncodeMessageType(msgNoMatch)
- return catmsg.ErrIncomplete
-}
diff --git a/vendor/golang.org/x/text/message/catalog/dict.go b/vendor/golang.org/x/text/message/catalog/dict.go
deleted file mode 100644
index a0eb81810..000000000
--- a/vendor/golang.org/x/text/message/catalog/dict.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package catalog
-
-import (
- "sync"
-
- "golang.org/x/text/internal"
- "golang.org/x/text/internal/catmsg"
- "golang.org/x/text/language"
-)
-
-// TODO:
-// Dictionary returns a Dictionary that returns the first Message, using the
-// given language tag, that matches:
-// 1. the last one registered by one of the Set methods
-// 2. returned by one of the Loaders
-// 3. repeat from 1. using the parent language
-// This approach allows messages to be underspecified.
-// func (c *Catalog) Dictionary(tag language.Tag) (Dictionary, error) {
-// // TODO: verify dictionary exists.
-// return &dict{&c.index, tag}, nil
-// }
-
-type dict struct {
- s *store
- tag language.Tag // TODO: make compact tag.
-}
-
-func (d *dict) Lookup(key string) (data string, ok bool) {
- return d.s.lookup(d.tag, key)
-}
-
-func (b *Builder) lookup(tag language.Tag, key string) (data string, ok bool) {
- return b.index.lookup(tag, key)
-}
-
-func (c *Builder) set(tag language.Tag, key string, s *store, msg ...Message) error {
- data, err := catmsg.Compile(tag, &dict{&c.macros, tag}, firstInSequence(msg))
-
- s.mutex.Lock()
- defer s.mutex.Unlock()
-
- m := s.index[tag]
- if m == nil {
- m = msgMap{}
- if s.index == nil {
- s.index = map[language.Tag]msgMap{}
- }
- c.matcher = nil
- s.index[tag] = m
- }
-
- m[key] = data
- return err
-}
-
-func (c *Builder) Matcher() language.Matcher {
- c.index.mutex.RLock()
- m := c.matcher
- c.index.mutex.RUnlock()
- if m != nil {
- return m
- }
-
- c.index.mutex.Lock()
- if c.matcher == nil {
- c.matcher = language.NewMatcher(c.unlockedLanguages())
- }
- m = c.matcher
- c.index.mutex.Unlock()
- return m
-}
-
-type store struct {
- mutex sync.RWMutex
- index map[language.Tag]msgMap
-}
-
-type msgMap map[string]string
-
-func (s *store) lookup(tag language.Tag, key string) (data string, ok bool) {
- s.mutex.RLock()
- defer s.mutex.RUnlock()
-
- for ; ; tag = tag.Parent() {
- if msgs, ok := s.index[tag]; ok {
- if msg, ok := msgs[key]; ok {
- return msg, true
- }
- }
- if tag == language.Und {
- break
- }
- }
- return "", false
-}
-
-// Languages returns all languages for which the Catalog contains variants.
-func (b *Builder) Languages() []language.Tag {
- s := &b.index
- s.mutex.RLock()
- defer s.mutex.RUnlock()
-
- return b.unlockedLanguages()
-}
-
-func (b *Builder) unlockedLanguages() []language.Tag {
- s := &b.index
- if len(s.index) == 0 {
- return nil
- }
- tags := make([]language.Tag, 0, len(s.index))
- _, hasFallback := s.index[b.options.fallback]
- offset := 0
- if hasFallback {
- tags = append(tags, b.options.fallback)
- offset = 1
- }
- for t := range s.index {
- if t != b.options.fallback {
- tags = append(tags, t)
- }
- }
- internal.SortTags(tags[offset:])
- return tags
-}
diff --git a/vendor/golang.org/x/text/message/catalog/go19.go b/vendor/golang.org/x/text/message/catalog/go19.go
deleted file mode 100644
index 147fc7cf5..000000000
--- a/vendor/golang.org/x/text/message/catalog/go19.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.9
-
-package catalog
-
-import "golang.org/x/text/internal/catmsg"
-
-// A Message holds a collection of translations for the same phrase that may
-// vary based on the values of substitution arguments.
-type Message = catmsg.Message
-
-type firstInSequence = catmsg.FirstOf
diff --git a/vendor/golang.org/x/text/message/catalog/gopre19.go b/vendor/golang.org/x/text/message/catalog/gopre19.go
deleted file mode 100644
index a9753b905..000000000
--- a/vendor/golang.org/x/text/message/catalog/gopre19.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.9
-
-package catalog
-
-import "golang.org/x/text/internal/catmsg"
-
-// A Message holds a collection of translations for the same phrase that may
-// vary based on the values of substitution arguments.
-type Message interface {
- catmsg.Message
-}
-
-func firstInSequence(m []Message) catmsg.Message {
- a := []catmsg.Message{}
- for _, m := range m {
- a = append(a, m)
- }
- return catmsg.FirstOf(a)
-}
diff --git a/vendor/golang.org/x/text/message/catalog_test.go b/vendor/golang.org/x/text/message/catalog_test.go
deleted file mode 100644
index 7a2301c0e..000000000
--- a/vendor/golang.org/x/text/message/catalog_test.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package message
-
-import (
- "strings"
- "testing"
-
- "golang.org/x/text/language"
- "golang.org/x/text/message/catalog"
-)
-
-func TestMatchLanguage(t *testing.T) {
- c := catalog.NewBuilder(catalog.Fallback(language.English))
- c.SetString(language.Bengali, "", "")
- c.SetString(language.English, "", "")
- c.SetString(language.German, "", "")
-
- testCases := []struct {
- args string // '|'-separated list
- want string
- }{{
- args: "de-CH",
- want: "de",
- }, {
- args: "bn-u-nu-latn|en-US,en;q=0.9,de;q=0.8,nl;q=0.7",
- want: "bn-u-nu-latn",
- }, {
- args: "gr",
- want: "en",
- }}
- for _, tc := range testCases {
- DefaultCatalog = c
- t.Run(tc.args, func(t *testing.T) {
- got := MatchLanguage(strings.Split(tc.args, "|")...)
- if got != language.Make(tc.want) {
- t.Errorf("got %q; want %q", got, tc.want)
- }
- })
- }
-}
diff --git a/vendor/golang.org/x/text/message/doc.go b/vendor/golang.org/x/text/message/doc.go
deleted file mode 100644
index 2f7effd25..000000000
--- a/vendor/golang.org/x/text/message/doc.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package message implements formatted I/O for localized strings with functions
-// analogous to the fmt's print functions. It is a drop-in replacement for fmt.
-//
-//
-// Localized Formatting
-//
-// A format string can be localized by replacing any of the print functions of
-// fmt with an equivalent call to a Printer.
-//
-// p := message.NewPrinter(message.MatchLanguage("en"))
-// p.Println(123456.78) // Prints 123,456.78
-//
-// p.Printf("%d ducks in a row", 4331) // Prints 4,331 ducks in a row
-//
-// p := message.NewPrinter(message.MatchLanguage("nl"))
-// p.Println("Hoogte: %f meter", 1244.9) // Prints Hoogte: 1.244,9 meter
-//
-// p := message.NewPrinter(message.MatchLanguage("bn"))
-// p.Println(123456.78) // Prints ১,২৩,৪৫৬.৭৮
-//
-// Printer currently supports numbers and specialized types for which packages
-// exist in x/text. Other builtin types such as time.Time and slices are
-// planned.
-//
-// Format strings largely have the same meaning as with fmt with the following
-// notable exceptions:
-// - flag # always resorts to fmt for printing
-// - verb 'f', 'e', 'g', 'd' use localized formatting unless the '#' flag is
-// specified.
-//
-// See package fmt for more options.
-//
-//
-// Translation
-//
-// The format strings that are passed to Printf, Sprintf, Fprintf, or Errorf
-// are used as keys to look up translations for the specified languages.
-// More on how these need to be specified below.
-//
-// One can use arbitrary keys to distinguish between otherwise ambiguous
-// strings:
-// p := message.NewPrinter(language.English)
-// p.Printf("archive(noun)") // Prints "archive"
-// p.Printf("archive(verb)") // Prints "archive"
-//
-// p := message.NewPrinter(language.German)
-// p.Printf("archive(noun)") // Prints "Archiv"
-// p.Printf("archive(verb)") // Prints "archivieren"
-//
-// To retain the fallback functionality, use Key:
-// p.Printf(message.Key("archive(noun)", "archive"))
-// p.Printf(message.Key("archive(verb)", "archive"))
-//
-//
-// Translation Pipeline
-//
-// Format strings that contain text need to be translated to support different
-// locales. The first step is to extract strings that need to be translated.
-//
-// 1. Install gotext
-// go get -u golang.org/x/text/cmd/gotext
-// gotext -help
-//
-// 2. Mark strings in your source to be translated by using message.Printer,
-// instead of the functions of the fmt package.
-//
-// 3. Extract the strings from your source
-//
-// gotext extract
-//
-// The output will be written to the textdata directory.
-//
-// 4. Send the files for translation
-//
-// It is planned to support multiple formats, but for now one will have to
-// rewrite the JSON output to the desired format.
-//
-// 5. Inject translations into program
-//
-// 6. Repeat from 2
-//
-// Right now this has to be done programmatically with calls to Set or
-// SetString. These functions as well as the methods defined in
-// see also package golang.org/x/text/message/catalog can be used to implement
-// either dynamic or static loading of messages.
-//
-//
-// Plural and Gender Forms
-//
-// Translated messages can vary based on the plural and gender forms of
-// substitution values. In general, it is up to the translators to provide
-// alternative translations for such forms. See the packages in
-// golang.org/x/text/feature and golang.org/x/text/message/catalog for more
-// information.
-//
-package message
diff --git a/vendor/golang.org/x/text/message/examples_test.go b/vendor/golang.org/x/text/message/examples_test.go
deleted file mode 100644
index c73eaf90b..000000000
--- a/vendor/golang.org/x/text/message/examples_test.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package message_test
-
-import (
- "net/http"
-
- "golang.org/x/text/language"
- "golang.org/x/text/message"
-)
-
-func Example_http() {
- // languages supported by this service:
- matcher := language.NewMatcher(message.DefaultCatalog.Languages())
-
- http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- lang, _ := r.Cookie("lang")
- accept := r.Header.Get("Accept-Language")
- fallback := "en"
- tag, _ := language.MatchStrings(matcher, lang.String(), accept, fallback)
-
- p := message.NewPrinter(tag)
-
- p.Fprintln(w, "User language is", tag)
- })
-}
-
-func ExamplePrinter_numbers() {
- for _, lang := range []string{"en", "de", "de-CH", "fr", "bn"} {
- p := message.NewPrinter(language.Make(lang))
- p.Printf("%-6s %g\n", lang, 123456.78)
- }
-
- // Output:
- // en 123,456.78
- // de 123.456,78
- // de-CH 123’456.78
- // fr 123 456,78
- // bn ১,২৩,৪৫৬.৭৮
-}
diff --git a/vendor/golang.org/x/text/message/fmt_test.go b/vendor/golang.org/x/text/message/fmt_test.go
deleted file mode 100644
index 2d6872bf8..000000000
--- a/vendor/golang.org/x/text/message/fmt_test.go
+++ /dev/null
@@ -1,1871 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package message
-
-import (
- "bytes"
- "fmt"
- "io"
- "math"
- "reflect"
- "runtime"
- "strings"
- "testing"
- "time"
-
- "golang.org/x/text/language"
-)
-
-type (
- renamedBool bool
- renamedInt int
- renamedInt8 int8
- renamedInt16 int16
- renamedInt32 int32
- renamedInt64 int64
- renamedUint uint
- renamedUint8 uint8
- renamedUint16 uint16
- renamedUint32 uint32
- renamedUint64 uint64
- renamedUintptr uintptr
- renamedString string
- renamedBytes []byte
- renamedFloat32 float32
- renamedFloat64 float64
- renamedComplex64 complex64
- renamedComplex128 complex128
-)
-
-func TestFmtInterface(t *testing.T) {
- p := NewPrinter(language.Und)
- var i1 interface{}
- i1 = "abc"
- s := p.Sprintf("%s", i1)
- if s != "abc" {
- t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
- }
-}
-
-var (
- NaN = math.NaN()
- posInf = math.Inf(1)
- negInf = math.Inf(-1)
-
- intVar = 0
-
- array = [5]int{1, 2, 3, 4, 5}
- iarray = [4]interface{}{1, "hello", 2.5, nil}
- slice = array[:]
- islice = iarray[:]
-)
-
-type A struct {
- i int
- j uint
- s string
- x []int
-}
-
-type I int
-
-func (i I) String() string {
- p := NewPrinter(language.Und)
- return p.Sprintf("<%d>", int(i))
-}
-
-type B struct {
- I I
- j int
-}
-
-type C struct {
- i int
- B
-}
-
-type F int
-
-func (f F) Format(s fmt.State, c rune) {
- p := NewPrinter(language.Und)
- p.Fprintf(s, "<%c=F(%d)>", c, int(f))
-}
-
-type G int
-
-func (g G) GoString() string {
- p := NewPrinter(language.Und)
- return p.Sprintf("GoString(%d)", int(g))
-}
-
-type S struct {
- F F // a struct field that Formats
- G G // a struct field that GoStrings
-}
-
-type SI struct {
- I interface{}
-}
-
-// P is a type with a String method with pointer receiver for testing %p.
-type P int
-
-var pValue P
-
-func (p *P) String() string {
- return "String(p)"
-}
-
-var barray = [5]renamedUint8{1, 2, 3, 4, 5}
-var bslice = barray[:]
-
-type byteStringer byte
-
-func (byteStringer) String() string {
- return "X"
-}
-
-var byteStringerSlice = []byteStringer{'h', 'e', 'l', 'l', 'o'}
-
-type byteFormatter byte
-
-func (byteFormatter) Format(f fmt.State, _ rune) {
- p := NewPrinter(language.Und)
- p.Fprint(f, "X")
-}
-
-var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
-
-var fmtTests = []struct {
- fmt string
- val interface{}
- out string
-}{
- // The behavior of the following tests differs from that of the fmt package.
-
- // Unlike with the fmt package, it is okay to have extra arguments for
- // strings without format parameters. This is because it is impossible to
- // distinguish between reordered or ordered format strings in this case.
- // (For reordered format strings it is okay to not use arguments.)
- {"", nil, ""},
- {"", 2, ""},
- {"no args", "hello", "no args"},
-
- {"%017091901790959340919092959340919017929593813360", 0, "%!(NOVERB)"},
- {"%184467440737095516170v", 0, "%!(NOVERB)"},
- // Extra argument errors should format without flags set.
- {"%010.2", "12345", "%!(NOVERB)"},
-
- // Some key other differences, asides from localized values:
- // - NaN values should not use affixes; so no signs (CLDR requirement)
- // - Infinity uses patterns, so signs may be different (CLDR requirement)
- // - The # flag is used to disable localization.
-
- // All following tests are analogous to those of the fmt package, but with
- // localized numbers when appropriate.
- {"%d", 12345, "12,345"},
- {"%v", 12345, "12,345"},
- {"%t", true, "true"},
-
- // basic string
- {"%s", "abc", "abc"},
- {"%q", "abc", `"abc"`},
- {"%x", "abc", "616263"},
- {"%x", "\xff\xf0\x0f\xff", "fff00fff"},
- {"%X", "\xff\xf0\x0f\xff", "FFF00FFF"},
- {"%x", "", ""},
- {"% x", "", ""},
- {"%#x", "", ""},
- {"%# x", "", ""},
- {"%x", "xyz", "78797a"},
- {"%X", "xyz", "78797A"},
- {"% x", "xyz", "78 79 7a"},
- {"% X", "xyz", "78 79 7A"},
- {"%#x", "xyz", "0x78797a"},
- {"%#X", "xyz", "0X78797A"},
- {"%# x", "xyz", "0x78 0x79 0x7a"},
- {"%# X", "xyz", "0X78 0X79 0X7A"},
-
- // basic bytes
- {"%s", []byte("abc"), "abc"},
- {"%s", [3]byte{'a', 'b', 'c'}, "abc"},
- {"%s", &[3]byte{'a', 'b', 'c'}, "&abc"},
- {"%q", []byte("abc"), `"abc"`},
- {"%x", []byte("abc"), "616263"},
- {"%x", []byte("\xff\xf0\x0f\xff"), "fff00fff"},
- {"%X", []byte("\xff\xf0\x0f\xff"), "FFF00FFF"},
- {"%x", []byte(""), ""},
- {"% x", []byte(""), ""},
- {"%#x", []byte(""), ""},
- {"%# x", []byte(""), ""},
- {"%x", []byte("xyz"), "78797a"},
- {"%X", []byte("xyz"), "78797A"},
- {"% x", []byte("xyz"), "78 79 7a"},
- {"% X", []byte("xyz"), "78 79 7A"},
- {"%#x", []byte("xyz"), "0x78797a"},
- {"%#X", []byte("xyz"), "0X78797A"},
- {"%# x", []byte("xyz"), "0x78 0x79 0x7a"},
- {"%# X", []byte("xyz"), "0X78 0X79 0X7A"},
-
- // escaped strings
- {"%q", "", `""`},
- {"%#q", "", "``"},
- {"%q", "\"", `"\""`},
- {"%#q", "\"", "`\"`"},
- {"%q", "`", `"` + "`" + `"`},
- {"%#q", "`", `"` + "`" + `"`},
- {"%q", "\n", `"\n"`},
- {"%#q", "\n", `"\n"`},
- {"%q", `\n`, `"\\n"`},
- {"%#q", `\n`, "`\\n`"},
- {"%q", "abc", `"abc"`},
- {"%#q", "abc", "`abc`"},
- {"%q", "日本語", `"日本語"`},
- {"%+q", "日本語", `"\u65e5\u672c\u8a9e"`},
- {"%#q", "日本語", "`日本語`"},
- {"%#+q", "日本語", "`日本語`"},
- {"%q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
- {"%+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
- {"%#q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
- {"%#+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
- {"%q", "☺", `"☺"`},
- {"% q", "☺", `"☺"`}, // The space modifier should have no effect.
- {"%+q", "☺", `"\u263a"`},
- {"%#q", "☺", "`☺`"},
- {"%#+q", "☺", "`☺`"},
- {"%10q", "⌘", ` "⌘"`},
- {"%+10q", "⌘", ` "\u2318"`},
- {"%-10q", "⌘", `"⌘" `},
- {"%+-10q", "⌘", `"\u2318" `},
- {"%010q", "⌘", `0000000"⌘"`},
- {"%+010q", "⌘", `00"\u2318"`},
- {"%-010q", "⌘", `"⌘" `}, // 0 has no effect when - is present.
- {"%+-010q", "⌘", `"\u2318" `},
- {"%#8q", "\n", ` "\n"`},
- {"%#+8q", "\r", ` "\r"`},
- {"%#-8q", "\t", "` ` "},
- {"%#+-8q", "\b", `"\b" `},
- {"%q", "abc\xffdef", `"abc\xffdef"`},
- {"%+q", "abc\xffdef", `"abc\xffdef"`},
- {"%#q", "abc\xffdef", `"abc\xffdef"`},
- {"%#+q", "abc\xffdef", `"abc\xffdef"`},
- // Runes that are not printable.
- {"%q", "\U0010ffff", `"\U0010ffff"`},
- {"%+q", "\U0010ffff", `"\U0010ffff"`},
- {"%#q", "\U0010ffff", "`􏿿`"},
- {"%#+q", "\U0010ffff", "`􏿿`"},
- // Runes that are not valid.
- {"%q", string(0x110000), `"�"`},
- {"%+q", string(0x110000), `"\ufffd"`},
- {"%#q", string(0x110000), "`�`"},
- {"%#+q", string(0x110000), "`�`"},
-
- // characters
- {"%c", uint('x'), "x"},
- {"%c", 0xe4, "ä"},
- {"%c", 0x672c, "本"},
- {"%c", '日', "日"},
- {"%.0c", '⌘', "⌘"}, // Specifying precision should have no effect.
- {"%3c", '⌘', " ⌘"},
- {"%-3c", '⌘', "⌘ "},
- // Runes that are not printable.
- {"%c", '\U00000e00', "\u0e00"},
- {"%c", '\U0010ffff', "\U0010ffff"},
- // Runes that are not valid.
- {"%c", -1, "�"},
- {"%c", 0xDC80, "�"},
- {"%c", rune(0x110000), "�"},
- {"%c", int64(0xFFFFFFFFF), "�"},
- {"%c", uint64(0xFFFFFFFFF), "�"},
-
- // escaped characters
- {"%q", uint(0), `'\x00'`},
- {"%+q", uint(0), `'\x00'`},
- {"%q", '"', `'"'`},
- {"%+q", '"', `'"'`},
- {"%q", '\'', `'\''`},
- {"%+q", '\'', `'\''`},
- {"%q", '`', "'`'"},
- {"%+q", '`', "'`'"},
- {"%q", 'x', `'x'`},
- {"%+q", 'x', `'x'`},
- {"%q", 'ÿ', `'ÿ'`},
- {"%+q", 'ÿ', `'\u00ff'`},
- {"%q", '\n', `'\n'`},
- {"%+q", '\n', `'\n'`},
- {"%q", '☺', `'☺'`},
- {"%+q", '☺', `'\u263a'`},
- {"% q", '☺', `'☺'`}, // The space modifier should have no effect.
- {"%.0q", '☺', `'☺'`}, // Specifying precision should have no effect.
- {"%10q", '⌘', ` '⌘'`},
- {"%+10q", '⌘', ` '\u2318'`},
- {"%-10q", '⌘', `'⌘' `},
- {"%+-10q", '⌘', `'\u2318' `},
- {"%010q", '⌘', `0000000'⌘'`},
- {"%+010q", '⌘', `00'\u2318'`},
- {"%-010q", '⌘', `'⌘' `}, // 0 has no effect when - is present.
- {"%+-010q", '⌘', `'\u2318' `},
- // Runes that are not printable.
- {"%q", '\U00000e00', `'\u0e00'`},
- {"%q", '\U0010ffff', `'\U0010ffff'`},
- // Runes that are not valid.
- {"%q", int32(-1), "%!q(int32=-1)"},
- {"%q", 0xDC80, `'�'`},
- {"%q", rune(0x110000), "%!q(int32=1,114,112)"},
- {"%q", int64(0xFFFFFFFFF), "%!q(int64=68,719,476,735)"},
- {"%q", uint64(0xFFFFFFFFF), "%!q(uint64=68,719,476,735)"},
-
- // width
- {"%5s", "abc", " abc"},
- {"%2s", "\u263a", " ☺"},
- {"%-5s", "abc", "abc "},
- {"%-8q", "abc", `"abc" `},
- {"%05s", "abc", "00abc"},
- {"%08q", "abc", `000"abc"`},
- {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
- {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
- {"%.0s", "日本語日本語", ""},
- {"%.5s", "日本語日本語", "日本語日本"},
- {"%.10s", "日本語日本語", "日本語日本語"},
- {"%.5s", []byte("日本語日本語"), "日本語日本"},
- {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
- {"%.5x", "abcdefghijklmnopqrstuvwxyz", "6162636465"},
- {"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`},
- {"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), "6162636465"},
- {"%.3q", "日本語日本語", `"日本語"`},
- {"%.3q", []byte("日本語日本語"), `"日本語"`},
- {"%.1q", "日本語", `"日"`},
- {"%.1q", []byte("日本語"), `"日"`},
- {"%.1x", "日本語", "e6"},
- {"%.1X", []byte("日本語"), "E6"},
- {"%10.1q", "日本語日本語", ` "日"`},
- {"%10v", nil, " <nil>"},
- {"%-10v", nil, "<nil> "},
-
- // integers
- {"%d", uint(12345), "12,345"},
- {"%d", int(-12345), "-12,345"},
- {"%d", ^uint8(0), "255"},
- {"%d", ^uint16(0), "65,535"},
- {"%d", ^uint32(0), "4,294,967,295"},
- {"%d", ^uint64(0), "18,446,744,073,709,551,615"},
- {"%d", int8(-1 << 7), "-128"},
- {"%d", int16(-1 << 15), "-32,768"},
- {"%d", int32(-1 << 31), "-2,147,483,648"},
- {"%d", int64(-1 << 63), "-9,223,372,036,854,775,808"},
- {"%.d", 0, ""},
- {"%.0d", 0, ""},
- {"%6.0d", 0, " "},
- {"%06.0d", 0, " "},
- {"% d", 12345, " 12,345"},
- {"%+d", 12345, "+12,345"},
- {"%+d", -12345, "-12,345"},
- {"%b", 7, "111"},
- {"%b", -6, "-110"},
- {"%b", ^uint32(0), "11111111111111111111111111111111"},
- {"%b", ^uint64(0), "1111111111111111111111111111111111111111111111111111111111111111"},
- {"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
- {"%o", 01234, "1234"},
- {"%#o", 01234, "01234"},
- {"%o", ^uint32(0), "37777777777"},
- {"%o", ^uint64(0), "1777777777777777777777"},
- {"%#X", 0, "0X0"},
- {"%x", 0x12abcdef, "12abcdef"},
- {"%X", 0x12abcdef, "12ABCDEF"},
- {"%x", ^uint32(0), "ffffffff"},
- {"%X", ^uint64(0), "FFFFFFFFFFFFFFFF"},
- {"%.20b", 7, "00000000000000000111"},
- {"%10d", 12345, " 12,345"},
- {"%10d", -12345, " -12,345"},
- {"%+10d", 12345, " +12,345"},
- {"%010d", 12345, "0,000,012,345"},
- {"%010d", -12345, "-0,000,012,345"},
- {"%20.8d", 1234, " 00,001,234"},
- {"%20.8d", -1234, " -00,001,234"},
- {"%020.8d", 1234, " 00,001,234"},
- {"%020.8d", -1234, " -00,001,234"},
- {"%-20.8d", 1234, "00,001,234 "},
- {"%-20.8d", -1234, "-00,001,234 "},
- {"%-#20.8x", 0x1234abc, "0x01234abc "},
- {"%-#20.8X", 0x1234abc, "0X01234ABC "},
- {"%-#20.8o", 01234, "00001234 "},
-
- // Test correct f.intbuf overflow checks.
- {"%068d", 1, "00," + strings.Repeat("000,", 21) + "001"},
- {"%068d", -1, "-00," + strings.Repeat("000,", 21) + "001"},
- {"%#.68x", 42, zeroFill("0x", 68, "2a")},
- {"%.68d", -42, "-00," + strings.Repeat("000,", 21) + "042"},
- {"%+.68d", 42, "+00," + strings.Repeat("000,", 21) + "042"},
- {"% .68d", 42, " 00," + strings.Repeat("000,", 21) + "042"},
- {"% +.68d", 42, "+00," + strings.Repeat("000,", 21) + "042"},
-
- // unicode format
- {"%U", 0, "U+0000"},
- {"%U", -1, "U+FFFFFFFFFFFFFFFF"},
- {"%U", '\n', `U+000A`},
- {"%#U", '\n', `U+000A`},
- {"%+U", 'x', `U+0078`}, // Plus flag should have no effect.
- {"%# U", 'x', `U+0078 'x'`}, // Space flag should have no effect.
- {"%#.2U", 'x', `U+0078 'x'`}, // Precisions below 4 should print 4 digits.
- {"%U", '\u263a', `U+263A`},
- {"%#U", '\u263a', `U+263A '☺'`},
- {"%U", '\U0001D6C2', `U+1D6C2`},
- {"%#U", '\U0001D6C2', `U+1D6C2 '𝛂'`},
- {"%#14.6U", '⌘', " U+002318 '⌘'"},
- {"%#-14.6U", '⌘', "U+002318 '⌘' "},
- {"%#014.6U", '⌘', " U+002318 '⌘'"},
- {"%#-014.6U", '⌘', "U+002318 '⌘' "},
- {"%.68U", uint(42), zeroFill("U+", 68, "2A")},
- {"%#.68U", '日', zeroFill("U+", 68, "65E5") + " '日'"},
-
- // floats
- {"%+.3e", 0.0, "+0.000\u202f×\u202f10⁰⁰"},
- {"%+.3e", 1.0, "+1.000\u202f×\u202f10⁰⁰"},
- {"%+.3f", -1.0, "-1.000"},
- {"%+.3F", -1.0, "-1.000"},
- {"%+.3F", float32(-1.0), "-1.000"},
- {"%+07.2f", 1.0, "+001.00"},
- {"%+07.2f", -1.0, "-001.00"},
- {"%-07.2f", 1.0, "1.00 "},
- {"%-07.2f", -1.0, "-1.00 "},
- {"%+-07.2f", 1.0, "+1.00 "},
- {"%+-07.2f", -1.0, "-1.00 "},
- {"%-+07.2f", 1.0, "+1.00 "},
- {"%-+07.2f", -1.0, "-1.00 "},
- {"%+10.2f", +1.0, " +1.00"},
- {"%+10.2f", -1.0, " -1.00"},
- {"% .3E", -1.0, "-1.000\u202f×\u202f10⁰⁰"},
- {"% .3e", 1.0, " 1.000\u202f×\u202f10⁰⁰"},
- {"%+.3g", 0.0, "+0"},
- {"%+.3g", 1.0, "+1"},
- {"%+.3g", -1.0, "-1"},
- {"% .3g", -1.0, "-1"},
- {"% .3g", 1.0, " 1"},
- {"%b", float32(1.0), "8388608p-23"},
- {"%b", 1.0, "4503599627370496p-52"},
- // Test sharp flag used with floats.
- {"%#g", 1e-323, "1.00000e-323"},
- {"%#g", -1.0, "-1.00000"},
- {"%#g", 1.1, "1.10000"},
- {"%#g", 123456.0, "123456."},
- {"%#g", 1234567.0, "1.234567e+06"},
- {"%#g", 1230000.0, "1.23000e+06"},
- {"%#g", 1000000.0, "1.00000e+06"},
- {"%#.0f", 1.0, "1."},
- {"%#.0e", 1.0, "1.e+00"},
- {"%#.0g", 1.0, "1."},
- {"%#.0g", 1100000.0, "1.e+06"},
- {"%#.4f", 1.0, "1.0000"},
- {"%#.4e", 1.0, "1.0000e+00"},
- {"%#.4g", 1.0, "1.000"},
- {"%#.4g", 100000.0, "1.000e+05"},
- {"%#.0f", 123.0, "123."},
- {"%#.0e", 123.0, "1.e+02"},
- {"%#.0g", 123.0, "1.e+02"},
- {"%#.4f", 123.0, "123.0000"},
- {"%#.4e", 123.0, "1.2300e+02"},
- {"%#.4g", 123.0, "123.0"},
- {"%#.4g", 123000.0, "1.230e+05"},
- {"%#9.4g", 1.0, " 1.000"},
- // The sharp flag has no effect for binary float format.
- {"%#b", 1.0, "4503599627370496p-52"},
- // Precision has no effect for binary float format.
- {"%.4b", float32(1.0), "8388608p-23"},
- {"%.4b", -1.0, "-4503599627370496p-52"},
- // Test correct f.intbuf boundary checks.
- {"%.68f", 1.0, zeroFill("1.", 68, "")},
- {"%.68f", -1.0, zeroFill("-1.", 68, "")},
- // float infinites and NaNs
- {"%f", posInf, "∞"},
- {"%.1f", negInf, "-∞"},
- {"% f", NaN, "NaN"},
- {"%20f", posInf, " ∞"},
- {"% 20F", posInf, " ∞"},
- {"% 20e", negInf, " -∞"},
- {"%+20E", negInf, " -∞"},
- {"% +20g", negInf, " -∞"},
- {"%+-20G", posInf, "+∞ "},
- {"%20e", NaN, " NaN"},
- {"% +20E", NaN, " NaN"},
- {"% -20g", NaN, "NaN "},
- {"%+-20G", NaN, "NaN "},
- // Zero padding does not apply to infinities and NaN.
- {"%+020e", posInf, " +∞"},
- {"%-020f", negInf, "-∞ "},
- {"%-020E", NaN, "NaN "},
-
- // complex values
- {"%.f", 0i, "(0+0i)"},
- {"% .f", 0i, "( 0+0i)"},
- {"%+.f", 0i, "(+0+0i)"},
- {"% +.f", 0i, "(+0+0i)"},
- {"%+.3e", 0i, "(+0.000\u202f×\u202f10⁰⁰+0.000\u202f×\u202f10⁰⁰i)"},
- {"%+.3f", 0i, "(+0.000+0.000i)"},
- {"%+.3g", 0i, "(+0+0i)"},
- {"%+.3e", 1 + 2i, "(+1.000\u202f×\u202f10⁰⁰+2.000\u202f×\u202f10⁰⁰i)"},
- {"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
- {"%+.3g", 1 + 2i, "(+1+2i)"},
- {"%.3e", 0i, "(0.000\u202f×\u202f10⁰⁰+0.000\u202f×\u202f10⁰⁰i)"},
- {"%.3f", 0i, "(0.000+0.000i)"},
- {"%.3F", 0i, "(0.000+0.000i)"},
- {"%.3F", complex64(0i), "(0.000+0.000i)"},
- {"%.3g", 0i, "(0+0i)"},
- {"%.3e", 1 + 2i, "(1.000\u202f×\u202f10⁰⁰+2.000\u202f×\u202f10⁰⁰i)"},
- {"%.3f", 1 + 2i, "(1.000+2.000i)"},
- {"%.3g", 1 + 2i, "(1+2i)"},
- {"%.3e", -1 - 2i, "(-1.000\u202f×\u202f10⁰⁰-2.000\u202f×\u202f10⁰⁰i)"},
- {"%.3f", -1 - 2i, "(-1.000-2.000i)"},
- {"%.3g", -1 - 2i, "(-1-2i)"},
- {"% .3E", -1 - 2i, "(-1.000\u202f×\u202f10⁰⁰-2.000\u202f×\u202f10⁰⁰i)"},
- {"%+.3g", 1 + 2i, "(+1+2i)"},
- {"%+.3g", complex64(1 + 2i), "(+1+2i)"},
- {"%#g", 1 + 2i, "(1.00000+2.00000i)"},
- {"%#g", 123456 + 789012i, "(123456.+789012.i)"},
- {"%#g", 1e-10i, "(0.00000+1.00000e-10i)"},
- {"%#g", -1e10 - 1.11e100i, "(-1.00000e+10-1.11000e+100i)"},
- {"%#.0f", 1.23 + 1.0i, "(1.+1.i)"},
- {"%#.0e", 1.23 + 1.0i, "(1.e+00+1.e+00i)"},
- {"%#.0g", 1.23 + 1.0i, "(1.+1.i)"},
- {"%#.0g", 0 + 100000i, "(0.+1.e+05i)"},
- {"%#.0g", 1230000 + 0i, "(1.e+06+0.i)"},
- {"%#.4f", 1 + 1.23i, "(1.0000+1.2300i)"},
- {"%#.4e", 123 + 1i, "(1.2300e+02+1.0000e+00i)"},
- {"%#.4g", 123 + 1.23i, "(123.0+1.230i)"},
- {"%#12.5g", 0 + 100000i, "( 0.0000 +1.0000e+05i)"},
- {"%#12.5g", 1230000 - 0i, "( 1.2300e+06 +0.0000i)"},
- {"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
- {"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
- // The sharp flag has no effect for binary complex format.
- {"%#b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
- // Precision has no effect for binary complex format.
- {"%.4b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
- {"%.4b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
- // complex infinites and NaNs
- {"%f", complex(posInf, posInf), "(∞+∞i)"},
- {"%f", complex(negInf, negInf), "(-∞-∞i)"},
- {"%f", complex(NaN, NaN), "(NaN+NaNi)"},
- {"%.1f", complex(posInf, posInf), "(∞+∞i)"},
- {"% f", complex(posInf, posInf), "( ∞+∞i)"},
- {"% f", complex(negInf, negInf), "(-∞-∞i)"},
- {"% f", complex(NaN, NaN), "(NaN+NaNi)"},
- {"%8e", complex(posInf, posInf), "( ∞ +∞i)"},
- {"% 8E", complex(posInf, posInf), "( ∞ +∞i)"},
- {"%+8f", complex(negInf, negInf), "( -∞ -∞i)"},
- {"% +8g", complex(negInf, negInf), "( -∞ -∞i)"}, // TODO(g)
- {"% -8G", complex(NaN, NaN), "(NaN +NaN i)"},
- {"%+-8b", complex(NaN, NaN), "(+NaN +NaN i)"},
- // Zero padding does not apply to infinities and NaN.
- {"%08f", complex(posInf, posInf), "( ∞ +∞i)"},
- {"%-08g", complex(negInf, negInf), "(-∞ -∞ i)"},
- {"%-08G", complex(NaN, NaN), "(NaN +NaN i)"},
-
- // old test/fmt_test.go
- {"%e", 1.0, "1.000000\u202f×\u202f10⁰⁰"},
- {"%e", 1234.5678e3, "1.234568\u202f×\u202f10⁰⁶"},
- {"%e", 1234.5678e-8, "1.234568\u202f×\u202f10⁻⁰⁵"},
- {"%e", -7.0, "-7.000000\u202f×\u202f10⁰⁰"},
- {"%e", -1e-9, "-1.000000\u202f×\u202f10⁻⁰⁹"},
- {"%f", 1234.5678e3, "1,234,567.800000"},
- {"%f", 1234.5678e-8, "0.000012"},
- {"%f", -7.0, "-7.000000"},
- {"%f", -1e-9, "-0.000000"},
- {"%g", 1234.5678e3, "1.2345678\u202f×\u202f10⁰⁶"},
- {"%g", float32(1234.5678e3), "1.2345678\u202f×\u202f10⁰⁶"},
- {"%g", 1234.5678e-8, "1.2345678\u202f×\u202f10⁻⁰⁵"},
- {"%g", -7.0, "-7"},
- {"%g", -1e-9, "-1\u202f×\u202f10⁻⁰⁹"},
- {"%g", float32(-1e-9), "-1\u202f×\u202f10⁻⁰⁹"},
- {"%E", 1.0, "1.000000\u202f×\u202f10⁰⁰"},
- {"%E", 1234.5678e3, "1.234568\u202f×\u202f10⁰⁶"},
- {"%E", 1234.5678e-8, "1.234568\u202f×\u202f10⁻⁰⁵"},
- {"%E", -7.0, "-7.000000\u202f×\u202f10⁰⁰"},
- {"%E", -1e-9, "-1.000000\u202f×\u202f10⁻⁰⁹"},
- {"%G", 1234.5678e3, "1.2345678\u202f×\u202f10⁰⁶"},
- {"%G", float32(1234.5678e3), "1.2345678\u202f×\u202f10⁰⁶"},
- {"%G", 1234.5678e-8, "1.2345678\u202f×\u202f10⁻⁰⁵"},
- {"%G", -7.0, "-7"},
- {"%G", -1e-9, "-1\u202f×\u202f10⁻⁰⁹"},
- {"%G", float32(-1e-9), "-1\u202f×\u202f10⁻⁰⁹"},
- {"%20.5s", "qwertyuiop", " qwert"},
- {"%.5s", "qwertyuiop", "qwert"},
- {"%-20.5s", "qwertyuiop", "qwert "},
- {"%20c", 'x', " x"},
- {"%-20c", 'x', "x "},
- {"%20.6e", 1.2345e3, " 1.234500\u202f×\u202f10⁰³"},
- {"%20.6e", 1.2345e-3, " 1.234500\u202f×\u202f10⁻⁰³"},
- {"%20e", 1.2345e3, " 1.234500\u202f×\u202f10⁰³"},
- {"%20e", 1.2345e-3, " 1.234500\u202f×\u202f10⁻⁰³"},
- {"%20.8e", 1.2345e3, " 1.23450000\u202f×\u202f10⁰³"},
- {"%20f", 1.23456789e3, " 1,234.567890"},
- {"%20f", 1.23456789e-3, " 0.001235"},
- {"%20f", 12345678901.23456789, "12,345,678,901.234568"},
- {"%-20f", 1.23456789e3, "1,234.567890 "},
- {"%20.8f", 1.23456789e3, " 1,234.56789000"},
- {"%20.8f", 1.23456789e-3, " 0.00123457"},
- {"%g", 1.23456789e3, "1,234.56789"},
- {"%g", 1.23456789e-3, "0.00123456789"},
- {"%g", 1.23456789e20, "1.23456789\u202f×\u202f10²⁰"},
-
- // arrays
- {"%v", array, "[1 2 3 4 5]"},
- {"%v", iarray, "[1 hello 2.5 <nil>]"},
- {"%v", barray, "[1 2 3 4 5]"},
- {"%v", &array, "&[1 2 3 4 5]"},
- {"%v", &iarray, "&[1 hello 2.5 <nil>]"},
- {"%v", &barray, "&[1 2 3 4 5]"},
-
- // slices
- {"%v", slice, "[1 2 3 4 5]"},
- {"%v", islice, "[1 hello 2.5 <nil>]"},
- {"%v", bslice, "[1 2 3 4 5]"},
- {"%v", &slice, "&[1 2 3 4 5]"},
- {"%v", &islice, "&[1 hello 2.5 <nil>]"},
- {"%v", &bslice, "&[1 2 3 4 5]"},
-
- // byte arrays and slices with %b,%c,%d,%o,%U and %v
- {"%b", [3]byte{65, 66, 67}, "[1000001 1000010 1000011]"},
- {"%c", [3]byte{65, 66, 67}, "[A B C]"},
- {"%d", [3]byte{65, 66, 67}, "[65 66 67]"},
- {"%o", [3]byte{65, 66, 67}, "[101 102 103]"},
- {"%U", [3]byte{65, 66, 67}, "[U+0041 U+0042 U+0043]"},
- {"%v", [3]byte{65, 66, 67}, "[65 66 67]"},
- {"%v", [1]byte{123}, "[123]"},
- {"%012v", []byte{}, "[]"},
- {"%#012v", []byte{}, "[]byte{}"},
- {"%6v", []byte{1, 11, 111}, "[ 1 11 111]"},
- {"%06v", []byte{1, 11, 111}, "[000001 000011 000111]"},
- {"%-6v", []byte{1, 11, 111}, "[1 11 111 ]"},
- {"%-06v", []byte{1, 11, 111}, "[1 11 111 ]"},
- {"%#v", []byte{1, 11, 111}, "[]byte{0x1, 0xb, 0x6f}"},
- {"%#6v", []byte{1, 11, 111}, "[]byte{ 0x1, 0xb, 0x6f}"},
- {"%#06v", []byte{1, 11, 111}, "[]byte{0x000001, 0x00000b, 0x00006f}"},
- {"%#-6v", []byte{1, 11, 111}, "[]byte{0x1 , 0xb , 0x6f }"},
- {"%#-06v", []byte{1, 11, 111}, "[]byte{0x1 , 0xb , 0x6f }"},
- // f.space should and f.plus should not have an effect with %v.
- {"% v", []byte{1, 11, 111}, "[ 1 11 111]"},
- {"%+v", [3]byte{1, 11, 111}, "[1 11 111]"},
- {"%# -6v", []byte{1, 11, 111}, "[]byte{ 0x1 , 0xb , 0x6f }"},
- {"%#+-6v", [3]byte{1, 11, 111}, "[3]uint8{0x1 , 0xb , 0x6f }"},
- // f.space and f.plus should have an effect with %d.
- {"% d", []byte{1, 11, 111}, "[ 1 11 111]"},
- {"%+d", [3]byte{1, 11, 111}, "[+1 +11 +111]"},
- {"%# -6d", []byte{1, 11, 111}, "[ 1 11 111 ]"},
- {"%#+-6d", [3]byte{1, 11, 111}, "[+1 +11 +111 ]"},
-
- // floates with %v
- {"%v", 1.2345678, "1.2345678"},
- {"%v", float32(1.2345678), "1.2345678"},
-
- // complexes with %v
- {"%v", 1 + 2i, "(1+2i)"},
- {"%v", complex64(1 + 2i), "(1+2i)"},
-
- // structs
- {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
- {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
-
- // +v on structs with Stringable items
- {"%+v", B{1, 2}, `{I:<1> j:2}`},
- {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
-
- // other formats on Stringable items
- {"%s", I(23), `<23>`},
- {"%q", I(23), `"<23>"`},
- {"%x", I(23), `3c32333e`},
- {"%#x", I(23), `0x3c32333e`},
- {"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
- // Stringer applies only to string formats.
- {"%d", I(23), `23`},
- // Stringer applies to the extracted value.
- {"%s", reflect.ValueOf(I(23)), `<23>`},
-
- // go syntax
- {"%#v", A{1, 2, "a", []int{1, 2}}, `message.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
- {"%#v", new(byte), "(*uint8)(0xPTR)"},
- {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
- {"%#v", make(chan int), "(chan int)(0xPTR)"},
- {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
- {"%#v", 1000000000, "1000000000"},
- {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
- {"%#v", map[string]B{"a": {1, 2}}, `map[string]message.B{"a":message.B{I:1, j:2}}`},
- {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
- {"%#v", SI{}, `message.SI{I:interface {}(nil)}`},
- {"%#v", []int(nil), `[]int(nil)`},
- {"%#v", []int{}, `[]int{}`},
- {"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
- {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
- {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
- {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
- {"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
- {"%#v", map[int]byte{}, `map[int]uint8{}`},
- {"%#v", "foo", `"foo"`},
- {"%#v", barray, `[5]message.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
- {"%#v", bslice, `[]message.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
- {"%#v", []int32(nil), "[]int32(nil)"},
- {"%#v", 1.2345678, "1.2345678"},
- {"%#v", float32(1.2345678), "1.2345678"},
- // Only print []byte and []uint8 as type []byte if they appear at the top level.
- {"%#v", []byte(nil), "[]byte(nil)"},
- {"%#v", []uint8(nil), "[]byte(nil)"},
- {"%#v", []byte{}, "[]byte{}"},
- {"%#v", []uint8{}, "[]byte{}"},
- {"%#v", reflect.ValueOf([]byte{}), "[]uint8{}"},
- {"%#v", reflect.ValueOf([]uint8{}), "[]uint8{}"},
- {"%#v", &[]byte{}, "&[]uint8{}"},
- {"%#v", &[]byte{}, "&[]uint8{}"},
- {"%#v", [3]byte{}, "[3]uint8{0x0, 0x0, 0x0}"},
- {"%#v", [3]uint8{}, "[3]uint8{0x0, 0x0, 0x0}"},
-
- // slices with other formats
- {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
- {"%x", []int{1, 2, 15}, `[1 2 f]`},
- {"%d", []int{1, 2, 15}, `[1 2 15]`},
- {"%d", []byte{1, 2, 15}, `[1 2 15]`},
- {"%q", []string{"a", "b"}, `["a" "b"]`},
- {"% 02x", []byte{1}, "01"},
- {"% 02x", []byte{1, 2, 3}, "01 02 03"},
-
- // Padding with byte slices.
- {"%2x", []byte{}, " "},
- {"%#2x", []byte{}, " "},
- {"% 02x", []byte{}, "00"},
- {"%# 02x", []byte{}, "00"},
- {"%-2x", []byte{}, " "},
- {"%-02x", []byte{}, " "},
- {"%8x", []byte{0xab}, " ab"},
- {"% 8x", []byte{0xab}, " ab"},
- {"%#8x", []byte{0xab}, " 0xab"},
- {"%# 8x", []byte{0xab}, " 0xab"},
- {"%08x", []byte{0xab}, "000000ab"},
- {"% 08x", []byte{0xab}, "000000ab"},
- {"%#08x", []byte{0xab}, "00000xab"},
- {"%# 08x", []byte{0xab}, "00000xab"},
- {"%10x", []byte{0xab, 0xcd}, " abcd"},
- {"% 10x", []byte{0xab, 0xcd}, " ab cd"},
- {"%#10x", []byte{0xab, 0xcd}, " 0xabcd"},
- {"%# 10x", []byte{0xab, 0xcd}, " 0xab 0xcd"},
- {"%010x", []byte{0xab, 0xcd}, "000000abcd"},
- {"% 010x", []byte{0xab, 0xcd}, "00000ab cd"},
- {"%#010x", []byte{0xab, 0xcd}, "00000xabcd"},
- {"%# 010x", []byte{0xab, 0xcd}, "00xab 0xcd"},
- {"%-10X", []byte{0xab}, "AB "},
- {"% -010X", []byte{0xab}, "AB "},
- {"%#-10X", []byte{0xab, 0xcd}, "0XABCD "},
- {"%# -010X", []byte{0xab, 0xcd}, "0XAB 0XCD "},
- // Same for strings
- {"%2x", "", " "},
- {"%#2x", "", " "},
- {"% 02x", "", "00"},
- {"%# 02x", "", "00"},
- {"%-2x", "", " "},
- {"%-02x", "", " "},
- {"%8x", "\xab", " ab"},
- {"% 8x", "\xab", " ab"},
- {"%#8x", "\xab", " 0xab"},
- {"%# 8x", "\xab", " 0xab"},
- {"%08x", "\xab", "000000ab"},
- {"% 08x", "\xab", "000000ab"},
- {"%#08x", "\xab", "00000xab"},
- {"%# 08x", "\xab", "00000xab"},
- {"%10x", "\xab\xcd", " abcd"},
- {"% 10x", "\xab\xcd", " ab cd"},
- {"%#10x", "\xab\xcd", " 0xabcd"},
- {"%# 10x", "\xab\xcd", " 0xab 0xcd"},
- {"%010x", "\xab\xcd", "000000abcd"},
- {"% 010x", "\xab\xcd", "00000ab cd"},
- {"%#010x", "\xab\xcd", "00000xabcd"},
- {"%# 010x", "\xab\xcd", "00xab 0xcd"},
- {"%-10X", "\xab", "AB "},
- {"% -010X", "\xab", "AB "},
- {"%#-10X", "\xab\xcd", "0XABCD "},
- {"%# -010X", "\xab\xcd", "0XAB 0XCD "},
-
- // renamings
- {"%v", renamedBool(true), "true"},
- {"%d", renamedBool(true), "%!d(message.renamedBool=true)"},
- {"%o", renamedInt(8), "10"},
- {"%d", renamedInt8(-9), "-9"},
- {"%v", renamedInt16(10), "10"},
- {"%v", renamedInt32(-11), "-11"},
- {"%X", renamedInt64(255), "FF"},
- {"%v", renamedUint(13), "13"},
- {"%o", renamedUint8(14), "16"},
- {"%X", renamedUint16(15), "F"},
- {"%d", renamedUint32(16), "16"},
- {"%X", renamedUint64(17), "11"},
- {"%o", renamedUintptr(18), "22"},
- {"%x", renamedString("thing"), "7468696e67"},
- {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
- {"%q", renamedBytes([]byte("hello")), `"hello"`},
- {"%x", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656c6c6f"},
- {"%X", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656C6C6F"},
- {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
- {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
- {"%v", renamedFloat32(22), "22"},
- {"%v", renamedFloat64(33), "33"},
- {"%v", renamedComplex64(3 + 4i), "(3+4i)"},
- {"%v", renamedComplex128(4 - 3i), "(4-3i)"},
-
- // Formatter
- {"%x", F(1), "<x=F(1)>"},
- {"%x", G(2), "2"},
- {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
-
- // GoStringer
- {"%#v", G(6), "GoString(6)"},
- {"%#v", S{F(7), G(8)}, "message.S{F:<v=F(7)>, G:GoString(8)}"},
-
- // %T
- {"%T", byte(0), "uint8"},
- {"%T", reflect.ValueOf(nil), "reflect.Value"},
- {"%T", (4 - 3i), "complex128"},
- {"%T", renamedComplex128(4 - 3i), "message.renamedComplex128"},
- {"%T", intVar, "int"},
- {"%6T", &intVar, " *int"},
- {"%10T", nil, " <nil>"},
- {"%-10T", nil, "<nil> "},
-
- // %p with pointers
- {"%p", (*int)(nil), "0x0"},
- {"%#p", (*int)(nil), "0"},
- {"%p", &intVar, "0xPTR"},
- {"%#p", &intVar, "PTR"},
- {"%p", &array, "0xPTR"},
- {"%p", &slice, "0xPTR"},
- {"%8.2p", (*int)(nil), " 0x00"},
- {"%-20.16p", &intVar, "0xPTR "},
- // %p on non-pointers
- {"%p", make(chan int), "0xPTR"},
- {"%p", make(map[int]int), "0xPTR"},
- {"%p", func() {}, "0xPTR"},
- {"%p", 27, "%!p(int=27)"}, // not a pointer at all
- {"%p", nil, "%!p(<nil>)"}, // nil on its own has no type ...
- {"%#p", nil, "%!p(<nil>)"}, // ... and hence is not a pointer type.
- // pointers with specified base
- {"%b", &intVar, "PTR_b"},
- {"%d", &intVar, "PTR_d"},
- {"%o", &intVar, "PTR_o"},
- {"%x", &intVar, "PTR_x"},
- {"%X", &intVar, "PTR_X"},
- // %v on pointers
- {"%v", nil, "<nil>"},
- {"%#v", nil, "<nil>"},
- {"%v", (*int)(nil), "<nil>"},
- {"%#v", (*int)(nil), "(*int)(nil)"},
- {"%v", &intVar, "0xPTR"},
- {"%#v", &intVar, "(*int)(0xPTR)"},
- {"%8.2v", (*int)(nil), " <nil>"},
- {"%-20.16v", &intVar, "0xPTR "},
- // string method on pointer
- {"%s", &pValue, "String(p)"}, // String method...
- {"%p", &pValue, "0xPTR"}, // ... is not called with %p.
-
- // %d on Stringer should give integer if possible
- {"%s", time.Time{}.Month(), "January"},
- {"%d", time.Time{}.Month(), "1"},
-
- // erroneous things
- {"%s %", "hello", "hello %!(NOVERB)"},
- {"%s %.2", "hello", "hello %!(NOVERB)"},
-
- // The "<nil>" show up because maps are printed by
- // first obtaining a list of keys and then looking up
- // each key. Since NaNs can be map keys but cannot
- // be fetched directly, the lookup fails and returns a
- // zero reflect.Value, which formats as <nil>.
- // This test is just to check that it shows the two NaNs at all.
- {"%v", map[float64]int{NaN: 1, NaN: 2}, "map[NaN:<nil> NaN:<nil>]"},
-
- // Comparison of padding rules with C printf.
- /*
- C program:
- #include <stdio.h>
-
- char *format[] = {
- "[%.2f]",
- "[% .2f]",
- "[%+.2f]",
- "[%7.2f]",
- "[% 7.2f]",
- "[%+7.2f]",
- "[% +7.2f]",
- "[%07.2f]",
- "[% 07.2f]",
- "[%+07.2f]",
- "[% +07.2f]"
- };
-
- int main(void) {
- int i;
- for(i = 0; i < 11; i++) {
- printf("%s: ", format[i]);
- printf(format[i], 1.0);
- printf(" ");
- printf(format[i], -1.0);
- printf("\n");
- }
- }
-
- Output:
- [%.2f]: [1.00] [-1.00]
- [% .2f]: [ 1.00] [-1.00]
- [%+.2f]: [+1.00] [-1.00]
- [%7.2f]: [ 1.00] [ -1.00]
- [% 7.2f]: [ 1.00] [ -1.00]
- [%+7.2f]: [ +1.00] [ -1.00]
- [% +7.2f]: [ +1.00] [ -1.00]
- [%07.2f]: [0001.00] [-001.00]
- [% 07.2f]: [ 001.00] [-001.00]
- [%+07.2f]: [+001.00] [-001.00]
- [% +07.2f]: [+001.00] [-001.00]
-
- */
- {"%.2f", 1.0, "1.00"},
- {"%.2f", -1.0, "-1.00"},
- {"% .2f", 1.0, " 1.00"},
- {"% .2f", -1.0, "-1.00"},
- {"%+.2f", 1.0, "+1.00"},
- {"%+.2f", -1.0, "-1.00"},
- {"%7.2f", 1.0, " 1.00"},
- {"%7.2f", -1.0, " -1.00"},
- {"% 7.2f", 1.0, " 1.00"},
- {"% 7.2f", -1.0, " -1.00"},
- {"%+7.2f", 1.0, " +1.00"},
- {"%+7.2f", -1.0, " -1.00"},
- {"% +7.2f", 1.0, " +1.00"},
- {"% +7.2f", -1.0, " -1.00"},
- // Padding with 0's indicates minimum number of integer digits minus the
- // period, if present, and minus the sign if it is fixed.
- // TODO: consider making this number the number of significant digits.
- {"%07.2f", 1.0, "0,001.00"},
- {"%07.2f", -1.0, "-0,001.00"},
- {"% 07.2f", 1.0, " 001.00"},
- {"% 07.2f", -1.0, "-001.00"},
- {"%+07.2f", 1.0, "+001.00"},
- {"%+07.2f", -1.0, "-001.00"},
- {"% +07.2f", 1.0, "+001.00"},
- {"% +07.2f", -1.0, "-001.00"},
-
- // Complex numbers: exhaustively tested in TestComplexFormatting.
- {"%7.2f", 1 + 2i, "( 1.00 +2.00i)"},
- {"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
-
- // Use spaces instead of zero if padding to the right.
- {"%0-5s", "abc", "abc "},
- {"%-05.1f", 1.0, "1.0 "},
-
- // float and complex formatting should not change the padding width
- // for other elements. See issue 14642.
- {"%06v", []interface{}{+10.0, 10}, "[000,010 000,010]"},
- {"%06v", []interface{}{-10.0, 10}, "[-000,010 000,010]"},
- {"%06v", []interface{}{+10.0 + 10i, 10}, "[(000,010+00,010i) 000,010]"},
- {"%06v", []interface{}{-10.0 + 10i, 10}, "[(-000,010+00,010i) 000,010]"},
-
- // integer formatting should not alter padding for other elements.
- {"%03.6v", []interface{}{1, 2.0, "x"}, "[000,001 002 00x]"},
- {"%03.0v", []interface{}{0, 2.0, "x"}, "[ 002 000]"},
-
- // Complex fmt used to leave the plus flag set for future entries in the array
- // causing +2+0i and +3+0i instead of 2+0i and 3+0i.
- {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
- {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
-
- // Incomplete format specification caused crash.
- {"%.", 3, "%!.(int=3)"},
-
- // Padding for complex numbers. Has been bad, then fixed, then bad again.
- {"%+10.2f", +104.66 + 440.51i, "( +104.66 +440.51i)"},
- {"%+10.2f", -104.66 + 440.51i, "( -104.66 +440.51i)"},
- {"%+10.2f", +104.66 - 440.51i, "( +104.66 -440.51i)"},
- {"%+10.2f", -104.66 - 440.51i, "( -104.66 -440.51i)"},
- {"%010.2f", +104.66 + 440.51i, "(0,000,104.66+000,440.51i)"},
- {"%+010.2f", +104.66 + 440.51i, "(+000,104.66+000,440.51i)"},
- {"%+010.2f", -104.66 + 440.51i, "(-000,104.66+000,440.51i)"},
- {"%+010.2f", +104.66 - 440.51i, "(+000,104.66-000,440.51i)"},
- {"%+010.2f", -104.66 - 440.51i, "(-000,104.66-000,440.51i)"},
-
- // []T where type T is a byte with a Stringer method.
- {"%v", byteStringerSlice, "[X X X X X]"},
- {"%s", byteStringerSlice, "hello"},
- {"%q", byteStringerSlice, "\"hello\""},
- {"%x", byteStringerSlice, "68656c6c6f"},
- {"%X", byteStringerSlice, "68656C6C6F"},
- {"%#v", byteStringerSlice, "[]message.byteStringer{0x68, 0x65, 0x6c, 0x6c, 0x6f}"},
-
- // And the same for Formatter.
- {"%v", byteFormatterSlice, "[X X X X X]"},
- {"%s", byteFormatterSlice, "hello"},
- {"%q", byteFormatterSlice, "\"hello\""},
- {"%x", byteFormatterSlice, "68656c6c6f"},
- {"%X", byteFormatterSlice, "68656C6C6F"},
- // This next case seems wrong, but the docs say the Formatter wins here.
- {"%#v", byteFormatterSlice, "[]message.byteFormatter{X, X, X, X, X}"},
-
- // reflect.Value handled specially in Go 1.5, making it possible to
- // see inside non-exported fields (which cannot be accessed with Interface()).
- // Issue 8965.
- {"%v", reflect.ValueOf(A{}).Field(0).String(), "<int Value>"}, // Equivalent to the old way.
- {"%v", reflect.ValueOf(A{}).Field(0), "0"}, // Sees inside the field.
-
- // verbs apply to the extracted value too.
- {"%s", reflect.ValueOf("hello"), "hello"},
- {"%q", reflect.ValueOf("hello"), `"hello"`},
- {"%#04x", reflect.ValueOf(256), "0x0100"},
-
- // invalid reflect.Value doesn't crash.
- {"%v", reflect.Value{}, "<invalid reflect.Value>"},
- {"%v", &reflect.Value{}, "<invalid Value>"},
- {"%v", SI{reflect.Value{}}, "{<invalid Value>}"},
-
- // Tests to check that not supported verbs generate an error string.
- {"%☠", nil, "%!☠(<nil>)"},
- {"%☠", interface{}(nil), "%!☠(<nil>)"},
- {"%☠", int(0), "%!☠(int=0)"},
- {"%☠", uint(0), "%!☠(uint=0)"},
- {"%☠", []byte{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
- {"%☠", []uint8{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
- {"%☠", [1]byte{0}, "[%!☠(uint8=0)]"},
- {"%☠", [1]uint8{0}, "[%!☠(uint8=0)]"},
- {"%☠", "hello", "%!☠(string=hello)"},
- {"%☠", 1.2345678, "%!☠(float64=1.2345678)"},
- {"%☠", float32(1.2345678), "%!☠(float32=1.2345678)"},
- {"%☠", 1.2345678 + 1.2345678i, "%!☠(complex128=(1.2345678+1.2345678i))"},
- {"%☠", complex64(1.2345678 + 1.2345678i), "%!☠(complex64=(1.2345678+1.2345678i))"},
- {"%☠", &intVar, "%!☠(*int=0xPTR)"},
- {"%☠", make(chan int), "%!☠(chan int=0xPTR)"},
- {"%☠", func() {}, "%!☠(func()=0xPTR)"},
- {"%☠", reflect.ValueOf(renamedInt(0)), "%!☠(message.renamedInt=0)"},
- {"%☠", SI{renamedInt(0)}, "{%!☠(message.renamedInt=0)}"},
- {"%☠", &[]interface{}{I(1), G(2)}, "&[%!☠(message.I=1) %!☠(message.G=2)]"},
- {"%☠", SI{&[]interface{}{I(1), G(2)}}, "{%!☠(*[]interface {}=&[1 2])}"},
- {"%☠", reflect.Value{}, "<invalid reflect.Value>"},
- {"%☠", map[float64]int{NaN: 1}, "map[%!☠(float64=NaN):%!☠(<nil>)]"},
-}
-
-// zeroFill generates zero-filled strings of the specified width. The length
-// of the suffix (but not the prefix) is compensated for in the width calculation.
-func zeroFill(prefix string, width int, suffix string) string {
- return prefix + strings.Repeat("0", width-len(suffix)) + suffix
-}
-
-func TestSprintf(t *testing.T) {
- p := NewPrinter(language.Und)
- for _, tt := range fmtTests {
- t.Run(fmt.Sprint(tt.fmt, "/", tt.val), func(t *testing.T) {
- s := p.Sprintf(tt.fmt, tt.val)
- i := strings.Index(tt.out, "PTR")
- if i >= 0 && i < len(s) {
- var pattern, chars string
- switch {
- case strings.HasPrefix(tt.out[i:], "PTR_b"):
- pattern = "PTR_b"
- chars = "01"
- case strings.HasPrefix(tt.out[i:], "PTR_o"):
- pattern = "PTR_o"
- chars = "01234567"
- case strings.HasPrefix(tt.out[i:], "PTR_d"):
- pattern = "PTR_d"
- chars = "0123456789"
- case strings.HasPrefix(tt.out[i:], "PTR_x"):
- pattern = "PTR_x"
- chars = "0123456789abcdef"
- case strings.HasPrefix(tt.out[i:], "PTR_X"):
- pattern = "PTR_X"
- chars = "0123456789ABCDEF"
- default:
- pattern = "PTR"
- chars = "0123456789abcdefABCDEF"
- }
- p := s[:i] + pattern
- for j := i; j < len(s); j++ {
- if !strings.ContainsRune(chars, rune(s[j])) {
- p += s[j:]
- break
- }
- }
- s = p
- }
- if s != tt.out {
- if _, ok := tt.val.(string); ok {
- // Don't requote the already-quoted strings.
- // It's too confusing to read the errors.
- t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
- } else {
- t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
- }
- }
- })
- }
-}
-
-var f float64
-
-// TestComplexFormatting checks that a complex always formats to the same
-// thing as if done by hand with two singleton prints.
-func TestComplexFormatting(t *testing.T) {
- var yesNo = []bool{true, false}
- var values = []float64{1, 0, -1, posInf, negInf, NaN}
- p := NewPrinter(language.Und)
- for _, plus := range yesNo {
- for _, zero := range yesNo {
- for _, space := range yesNo {
- for _, char := range "fFeEgG" {
- realFmt := "%"
- if zero {
- realFmt += "0"
- }
- if space {
- realFmt += " "
- }
- if plus {
- realFmt += "+"
- }
- realFmt += "10.2"
- realFmt += string(char)
- // Imaginary part always has a sign, so force + and ignore space.
- imagFmt := "%"
- if zero {
- imagFmt += "0"
- }
- imagFmt += "+"
- imagFmt += "10.2"
- imagFmt += string(char)
- for _, realValue := range values {
- for _, imagValue := range values {
- one := p.Sprintf(realFmt, complex(realValue, imagValue))
- two := p.Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue)
- if math.IsNaN(imagValue) {
- p := len(two) - len("NaNi)") - 1
- if two[p] == ' ' {
- two = two[:p] + "+" + two[p+1:]
- } else {
- two = two[:p+1] + "+" + two[p+1:]
- }
- }
- if one != two {
- t.Error(f, one, two)
- }
- }
- }
- }
- }
- }
- }
-}
-
-type SE []interface{} // slice of empty; notational compactness.
-
-var reorderTests = []struct {
- format string
- args SE
- out string
-}{
- {"%[1]d", SE{1}, "1"},
- {"%[2]d", SE{2, 1}, "1"},
- {"%[2]d %[1]d", SE{1, 2}, "2 1"},
- {"%[2]*[1]d", SE{2, 5}, " 2"},
- {"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line.
- {"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"},
- {"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"},
- {"%10f", SE{12.0}, " 12.000000"},
- {"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"},
- {"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line.
- {"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"},
- {"%6.f", SE{12.0}, " 12"}, // // Explicit version of next line; empty precision means zero.
- {"%[1]*.[3]f", SE{6, 3, 12.0}, " 12"},
- // An actual use! Print the same arguments twice.
- {"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"},
-
- // Erroneous cases.
- {"%[d", SE{2, 1}, "%!d(BADINDEX)"},
- {"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
- {"%[]d", SE{2, 1}, "%!d(BADINDEX)"},
- {"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"},
- {"%[99]d", SE{2, 1}, "%!d(BADINDEX)"},
- {"%[3]", SE{2, 1}, "%!(NOVERB)"},
- {"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"},
- {"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"},
- {"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
- {"%.[2]d", SE{7}, "%!d(BADINDEX)"},
- {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
- {"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
- {"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
- {"%.[]", SE{}, "%!](BADINDEX)"}, // Issue 10675
- {"%.-3d", SE{42}, "%!-(int=42)3d"}, // TODO: Should this set return better error messages?
- // The following messages are interpreted as if there is no substitution,
- // in which case it is okay to have extra arguments. This is different
- // semantics from the fmt package.
- {"%2147483648d", SE{42}, "%!(NOVERB)"},
- {"%-2147483648d", SE{42}, "%!(NOVERB)"},
- {"%.2147483648d", SE{42}, "%!(NOVERB)"},
-}
-
-func TestReorder(t *testing.T) {
- p := NewPrinter(language.Und)
- for _, tc := range reorderTests {
- t.Run(fmt.Sprint(tc.format, "/", tc.args), func(t *testing.T) {
- s := p.Sprintf(tc.format, tc.args...)
- if s != tc.out {
- t.Errorf("Sprintf(%q, %v) = %q want %q", tc.format, tc.args, s, tc.out)
- }
- })
- }
-}
-
-func BenchmarkSprintfPadding(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%16f", 1.0)
- }
- })
-}
-
-func BenchmarkSprintfEmpty(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("")
- }
- })
-}
-
-func BenchmarkSprintfString(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%s", "hello")
- }
- })
-}
-
-func BenchmarkSprintfTruncateString(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%.3s", "日本語日本語日本語")
- }
- })
-}
-
-func BenchmarkSprintfQuoteString(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%q", "日本語日本語日本語")
- }
- })
-}
-
-func BenchmarkSprintfInt(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%d", 5)
- }
- })
-}
-
-func BenchmarkSprintfIntInt(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%d %d", 5, 6)
- }
- })
-}
-
-func BenchmarkSprintfPrefixedInt(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
- }
- })
-}
-
-func BenchmarkSprintfFloat(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%g", 5.23184)
- }
- })
-}
-
-func BenchmarkSprintfComplex(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%f", 5.23184+5.23184i)
- }
- })
-}
-
-func BenchmarkSprintfBoolean(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%t", true)
- }
- })
-}
-
-func BenchmarkSprintfHexString(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("% #x", "0123456789abcdef")
- }
- })
-}
-
-func BenchmarkSprintfHexBytes(b *testing.B) {
- data := []byte("0123456789abcdef")
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("% #x", data)
- }
- })
-}
-
-func BenchmarkSprintfBytes(b *testing.B) {
- data := []byte("0123456789abcdef")
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%v", data)
- }
- })
-}
-
-func BenchmarkSprintfStringer(b *testing.B) {
- stringer := I(12345)
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%v", stringer)
- }
- })
-}
-
-func BenchmarkSprintfStructure(b *testing.B) {
- s := &[]interface{}{SI{12345}, map[int]string{0: "hello"}}
- b.RunParallel(func(pb *testing.PB) {
- p := NewPrinter(language.English)
- for pb.Next() {
- p.Sprintf("%#v", s)
- }
- })
-}
-
-func BenchmarkManyArgs(b *testing.B) {
- b.RunParallel(func(pb *testing.PB) {
- var buf bytes.Buffer
- p := NewPrinter(language.English)
- for pb.Next() {
- buf.Reset()
- p.Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
- }
- })
-}
-
-func BenchmarkFprintInt(b *testing.B) {
- var buf bytes.Buffer
- p := NewPrinter(language.English)
- for i := 0; i < b.N; i++ {
- buf.Reset()
- p.Fprint(&buf, 123456)
- }
-}
-
-func BenchmarkFprintfBytes(b *testing.B) {
- data := []byte(string("0123456789"))
- var buf bytes.Buffer
- p := NewPrinter(language.English)
- for i := 0; i < b.N; i++ {
- buf.Reset()
- p.Fprintf(&buf, "%s", data)
- }
-}
-
-func BenchmarkFprintIntNoAlloc(b *testing.B) {
- var x interface{} = 123456
- var buf bytes.Buffer
- p := NewPrinter(language.English)
- for i := 0; i < b.N; i++ {
- buf.Reset()
- p.Fprint(&buf, x)
- }
-}
-
-var mallocBuf bytes.Buffer
-var mallocPointer *int // A pointer so we know the interface value won't allocate.
-
-var mallocTest = []struct {
- count int
- desc string
- fn func(p *Printer)
-}{
- {0, `Sprintf("")`, func(p *Printer) { p.Sprintf("") }},
- {1, `Sprintf("xxx")`, func(p *Printer) { p.Sprintf("xxx") }},
- {2, `Sprintf("%x")`, func(p *Printer) { p.Sprintf("%x", 7) }},
- {2, `Sprintf("%s")`, func(p *Printer) { p.Sprintf("%s", "hello") }},
- {3, `Sprintf("%x %x")`, func(p *Printer) { p.Sprintf("%x %x", 7, 112) }},
- {2, `Sprintf("%g")`, func(p *Printer) { p.Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1?
- {1, `Fprintf(buf, "%s")`, func(p *Printer) { mallocBuf.Reset(); p.Fprintf(&mallocBuf, "%s", "hello") }},
- // If the interface value doesn't need to allocate, amortized allocation overhead should be zero.
- {0, `Fprintf(buf, "%x %x %x")`, func(p *Printer) {
- mallocBuf.Reset()
- p.Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer)
- }},
-}
-
-var _ bytes.Buffer
-
-func TestCountMallocs(t *testing.T) {
- switch {
- case testing.Short():
- t.Skip("skipping malloc count in short mode")
- case runtime.GOMAXPROCS(0) > 1:
- t.Skip("skipping; GOMAXPROCS>1")
- // TODO: detect race detecter enabled.
- // case race.Enabled:
- // t.Skip("skipping malloc count under race detector")
- }
- p := NewPrinter(language.English)
- for _, mt := range mallocTest {
- mallocs := testing.AllocsPerRun(100, func() { mt.fn(p) })
- if got, max := mallocs, float64(mt.count); got > max {
- t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
- }
- }
-}
-
-type flagPrinter struct{}
-
-func (flagPrinter) Format(f fmt.State, c rune) {
- s := "%"
- for i := 0; i < 128; i++ {
- if f.Flag(i) {
- s += string(i)
- }
- }
- if w, ok := f.Width(); ok {
- s += fmt.Sprintf("%d", w)
- }
- if p, ok := f.Precision(); ok {
- s += fmt.Sprintf(".%d", p)
- }
- s += string(c)
- io.WriteString(f, "["+s+"]")
-}
-
-var flagtests = []struct {
- in string
- out string
-}{
- {"%a", "[%a]"},
- {"%-a", "[%-a]"},
- {"%+a", "[%+a]"},
- {"%#a", "[%#a]"},
- {"% a", "[% a]"},
- {"%0a", "[%0a]"},
- {"%1.2a", "[%1.2a]"},
- {"%-1.2a", "[%-1.2a]"},
- {"%+1.2a", "[%+1.2a]"},
- {"%-+1.2a", "[%+-1.2a]"},
- {"%-+1.2abc", "[%+-1.2a]bc"},
- {"%-1.2abc", "[%-1.2a]bc"},
-}
-
-func TestFlagParser(t *testing.T) {
- var flagprinter flagPrinter
- for _, tt := range flagtests {
- s := NewPrinter(language.Und).Sprintf(tt.in, &flagprinter)
- if s != tt.out {
- t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
- }
- }
-}
-
-func TestStructPrinter(t *testing.T) {
- type T struct {
- a string
- b string
- c int
- }
- var s T
- s.a = "abc"
- s.b = "def"
- s.c = 123
- var tests = []struct {
- fmt string
- out string
- }{
- {"%v", "{abc def 123}"},
- {"%+v", "{a:abc b:def c:123}"},
- {"%#v", `message.T{a:"abc", b:"def", c:123}`},
- }
- p := NewPrinter(language.Und)
- for _, tt := range tests {
- out := p.Sprintf(tt.fmt, s)
- if out != tt.out {
- t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out)
- }
- // The same but with a pointer.
- out = p.Sprintf(tt.fmt, &s)
- if out != "&"+tt.out {
- t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out)
- }
- }
-}
-
-func TestSlicePrinter(t *testing.T) {
- p := NewPrinter(language.Und)
- slice := []int{}
- s := p.Sprint(slice)
- if s != "[]" {
- t.Errorf("empty slice printed as %q not %q", s, "[]")
- }
- slice = []int{1, 2, 3}
- s = p.Sprint(slice)
- if s != "[1 2 3]" {
- t.Errorf("slice: got %q expected %q", s, "[1 2 3]")
- }
- s = p.Sprint(&slice)
- if s != "&[1 2 3]" {
- t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]")
- }
-}
-
-// presentInMap checks map printing using substrings so we don't depend on the
-// print order.
-func presentInMap(s string, a []string, t *testing.T) {
- for i := 0; i < len(a); i++ {
- loc := strings.Index(s, a[i])
- if loc < 0 {
- t.Errorf("map print: expected to find %q in %q", a[i], s)
- }
- // make sure the match ends here
- loc += len(a[i])
- if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
- t.Errorf("map print: %q not properly terminated in %q", a[i], s)
- }
- }
-}
-
-func TestMapPrinter(t *testing.T) {
- p := NewPrinter(language.Und)
- m0 := make(map[int]string)
- s := p.Sprint(m0)
- if s != "map[]" {
- t.Errorf("empty map printed as %q not %q", s, "map[]")
- }
- m1 := map[int]string{1: "one", 2: "two", 3: "three"}
- a := []string{"1:one", "2:two", "3:three"}
- presentInMap(p.Sprintf("%v", m1), a, t)
- presentInMap(p.Sprint(m1), a, t)
- // Pointer to map prints the same but with initial &.
- if !strings.HasPrefix(p.Sprint(&m1), "&") {
- t.Errorf("no initial & for address of map")
- }
- presentInMap(p.Sprintf("%v", &m1), a, t)
- presentInMap(p.Sprint(&m1), a, t)
-}
-
-func TestEmptyMap(t *testing.T) {
- const emptyMapStr = "map[]"
- var m map[string]int
- p := NewPrinter(language.Und)
- s := p.Sprint(m)
- if s != emptyMapStr {
- t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
- }
- m = make(map[string]int)
- s = p.Sprint(m)
- if s != emptyMapStr {
- t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
- }
-}
-
-// TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the
-// right places, that is, between arg pairs in which neither is a string.
-func TestBlank(t *testing.T) {
- p := NewPrinter(language.Und)
- got := p.Sprint("<", 1, ">:", 1, 2, 3, "!")
- expect := "<1>:1 2 3!"
- if got != expect {
- t.Errorf("got %q expected %q", got, expect)
- }
-}
-
-// TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in
-// the right places, that is, between all arg pairs.
-func TestBlankln(t *testing.T) {
- p := NewPrinter(language.Und)
- got := p.Sprintln("<", 1, ">:", 1, 2, 3, "!")
- expect := "< 1 >: 1 2 3 !\n"
- if got != expect {
- t.Errorf("got %q expected %q", got, expect)
- }
-}
-
-// TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf.
-func TestFormatterPrintln(t *testing.T) {
- p := NewPrinter(language.Und)
- f := F(1)
- expect := "<v=F(1)>\n"
- s := p.Sprint(f, "\n")
- if s != expect {
- t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
- }
- s = p.Sprintln(f)
- if s != expect {
- t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
- }
- s = p.Sprintf("%v\n", f)
- if s != expect {
- t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
- }
-}
-
-func args(a ...interface{}) []interface{} { return a }
-
-var startests = []struct {
- fmt string
- in []interface{}
- out string
-}{
- {"%*d", args(4, 42), " 42"},
- {"%-*d", args(4, 42), "42 "},
- {"%*d", args(-4, 42), "42 "},
- {"%-*d", args(-4, 42), "42 "},
- {"%.*d", args(4, 42), "0,042"},
- {"%*.*d", args(8, 4, 42), " 0,042"},
- {"%0*d", args(4, 42), "0,042"},
- // Some non-int types for width. (Issue 10732).
- {"%0*d", args(uint(4), 42), "0,042"},
- {"%0*d", args(uint64(4), 42), "0,042"},
- {"%0*d", args('\x04', 42), "0,042"},
- {"%0*d", args(uintptr(4), 42), "0,042"},
-
- // erroneous
- {"%*d", args(nil, 42), "%!(BADWIDTH)42"},
- {"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"},
- {"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"},
- {"%.*d", args(nil, 42), "%!(BADPREC)42"},
- {"%.*d", args(-1, 42), "%!(BADPREC)42"},
- {"%.*d", args(int(1e7), 42), "%!(BADPREC)42"},
- {"%.*d", args(uint(1e7), 42), "%!(BADPREC)42"},
- {"%.*d", args(uint64(1<<63), 42), "%!(BADPREC)42"}, // Huge negative (-inf).
- {"%.*d", args(uint64(1<<64-1), 42), "%!(BADPREC)42"}, // Small negative (-1).
- {"%*d", args(5, "foo"), "%!d(string= foo)"},
- {"%*% %d", args(20, 5), "% 5"},
- {"%*", args(4), "%!(NOVERB)"},
-}
-
-func TestWidthAndPrecision(t *testing.T) {
- p := NewPrinter(language.Und)
- for i, tt := range startests {
- t.Run(fmt.Sprint(tt.fmt, tt.in), func(t *testing.T) {
- s := p.Sprintf(tt.fmt, tt.in...)
- if s != tt.out {
- t.Errorf("#%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
- }
- })
- }
-}
-
-// PanicS is a type that panics in String.
-type PanicS struct {
- message interface{}
-}
-
-// Value receiver.
-func (p PanicS) String() string {
- panic(p.message)
-}
-
-// PanicGo is a type that panics in GoString.
-type PanicGo struct {
- message interface{}
-}
-
-// Value receiver.
-func (p PanicGo) GoString() string {
- panic(p.message)
-}
-
-// PanicF is a type that panics in Format.
-type PanicF struct {
- message interface{}
-}
-
-// Value receiver.
-func (p PanicF) Format(f fmt.State, c rune) {
- panic(p.message)
-}
-
-var panictests = []struct {
- desc string
- fmt string
- in interface{}
- out string
-}{
- // String
- {"String", "%s", (*PanicS)(nil), "<nil>"}, // nil pointer special case
- {"String", "%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
- {"String", "%s", PanicS{3}, "%!s(PANIC=3)"},
- // GoString
- {"GoString", "%#v", (*PanicGo)(nil), "<nil>"}, // nil pointer special case
- {"GoString", "%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"},
- {"GoString", "%#v", PanicGo{3}, "%!v(PANIC=3)"},
- // Issue 18282. catchPanic should not clear fmtFlags permanently.
- {"Issue 18282", "%#v", []interface{}{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=3), %!v(PANIC=3)}"},
- // Format
- {"Format", "%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
- {"Format", "%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
- {"Format", "%s", PanicF{3}, "%!s(PANIC=3)"},
-}
-
-func TestPanics(t *testing.T) {
- p := NewPrinter(language.Und)
- for i, tt := range panictests {
- t.Run(fmt.Sprint(tt.desc, "/", tt.fmt, "/", tt.in), func(t *testing.T) {
- s := p.Sprintf(tt.fmt, tt.in)
- if s != tt.out {
- t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
- }
- })
- }
-}
-
-// recurCount tests that erroneous String routine doesn't cause fatal recursion.
-var recurCount = 0
-
-type Recur struct {
- i int
- failed *bool
-}
-
-func (r *Recur) String() string {
- p := NewPrinter(language.Und)
- if recurCount++; recurCount > 10 {
- *r.failed = true
- return "FAIL"
- }
- // This will call badVerb. Before the fix, that would cause us to recur into
- // this routine to print %!p(value). Now we don't call the user's method
- // during an error.
- return p.Sprintf("recur@%p value: %d", r, r.i)
-}
-
-func TestBadVerbRecursion(t *testing.T) {
- p := NewPrinter(language.Und)
- failed := false
- r := &Recur{3, &failed}
- p.Sprintf("recur@%p value: %d\n", &r, r.i)
- if failed {
- t.Error("fail with pointer")
- }
- failed = false
- r = &Recur{4, &failed}
- p.Sprintf("recur@%p, value: %d\n", r, r.i)
- if failed {
- t.Error("fail with value")
- }
-}
-
-func TestNilDoesNotBecomeTyped(t *testing.T) {
- p := NewPrinter(language.Und)
- type A struct{}
- type B struct{}
- var a *A = nil
- var b B = B{}
-
- // indirect the Sprintf call through this noVetWarn variable to avoid
- // "go test" failing vet checks in Go 1.10+.
- noVetWarn := p.Sprintf
- got := noVetWarn("%s %s %s %s %s", nil, a, nil, b, nil)
-
- const expect = "%!s(<nil>) %!s(*message.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
- if got != expect {
- t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
- }
-}
-
-var formatterFlagTests = []struct {
- in string
- val interface{}
- out string
-}{
- // scalar values with the (unused by fmt) 'a' verb.
- {"%a", flagPrinter{}, "[%a]"},
- {"%-a", flagPrinter{}, "[%-a]"},
- {"%+a", flagPrinter{}, "[%+a]"},
- {"%#a", flagPrinter{}, "[%#a]"},
- {"% a", flagPrinter{}, "[% a]"},
- {"%0a", flagPrinter{}, "[%0a]"},
- {"%1.2a", flagPrinter{}, "[%1.2a]"},
- {"%-1.2a", flagPrinter{}, "[%-1.2a]"},
- {"%+1.2a", flagPrinter{}, "[%+1.2a]"},
- {"%-+1.2a", flagPrinter{}, "[%+-1.2a]"},
- {"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"},
- {"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"},
-
- // composite values with the 'a' verb
- {"%a", [1]flagPrinter{}, "[[%a]]"},
- {"%-a", [1]flagPrinter{}, "[[%-a]]"},
- {"%+a", [1]flagPrinter{}, "[[%+a]]"},
- {"%#a", [1]flagPrinter{}, "[[%#a]]"},
- {"% a", [1]flagPrinter{}, "[[% a]]"},
- {"%0a", [1]flagPrinter{}, "[[%0a]]"},
- {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
- {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
- {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
- {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
- {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
- {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
-
- // simple values with the 'v' verb
- {"%v", flagPrinter{}, "[%v]"},
- {"%-v", flagPrinter{}, "[%-v]"},
- {"%+v", flagPrinter{}, "[%+v]"},
- {"%#v", flagPrinter{}, "[%#v]"},
- {"% v", flagPrinter{}, "[% v]"},
- {"%0v", flagPrinter{}, "[%0v]"},
- {"%1.2v", flagPrinter{}, "[%1.2v]"},
- {"%-1.2v", flagPrinter{}, "[%-1.2v]"},
- {"%+1.2v", flagPrinter{}, "[%+1.2v]"},
- {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
- {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
- {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
-
- // composite values with the 'v' verb.
- {"%v", [1]flagPrinter{}, "[[%v]]"},
- {"%-v", [1]flagPrinter{}, "[[%-v]]"},
- {"%+v", [1]flagPrinter{}, "[[%+v]]"},
- {"%#v", [1]flagPrinter{}, "[1]message.flagPrinter{[%#v]}"},
- {"% v", [1]flagPrinter{}, "[[% v]]"},
- {"%0v", [1]flagPrinter{}, "[[%0v]]"},
- {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
- {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
- {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
- {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
- {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
- {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
-}
-
-func TestFormatterFlags(t *testing.T) {
- p := NewPrinter(language.Und)
- for _, tt := range formatterFlagTests {
- s := p.Sprintf(tt.in, tt.val)
- if s != tt.out {
- t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out)
- }
- }
-}
diff --git a/vendor/golang.org/x/text/message/format.go b/vendor/golang.org/x/text/message/format.go
deleted file mode 100644
index a47d17dd4..000000000
--- a/vendor/golang.org/x/text/message/format.go
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package message
-
-import (
- "bytes"
- "strconv"
- "unicode/utf8"
-
- "golang.org/x/text/internal/format"
-)
-
-const (
- ldigits = "0123456789abcdefx"
- udigits = "0123456789ABCDEFX"
-)
-
-const (
- signed = true
- unsigned = false
-)
-
-// A formatInfo is the raw formatter used by Printf etc.
-// It prints into a buffer that must be set up separately.
-type formatInfo struct {
- buf *bytes.Buffer
-
- format.Parser
-
- // intbuf is large enough to store %b of an int64 with a sign and
- // avoids padding at the end of the struct on 32 bit architectures.
- intbuf [68]byte
-}
-
-func (f *formatInfo) init(buf *bytes.Buffer) {
- f.ClearFlags()
- f.buf = buf
-}
-
-// writePadding generates n bytes of padding.
-func (f *formatInfo) writePadding(n int) {
- if n <= 0 { // No padding bytes needed.
- return
- }
- f.buf.Grow(n)
- // Decide which byte the padding should be filled with.
- padByte := byte(' ')
- if f.Zero {
- padByte = byte('0')
- }
- // Fill padding with padByte.
- for i := 0; i < n; i++ {
- f.buf.WriteByte(padByte) // TODO: make more efficient.
- }
-}
-
-// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
-func (f *formatInfo) pad(b []byte) {
- if !f.WidthPresent || f.Width == 0 {
- f.buf.Write(b)
- return
- }
- width := f.Width - utf8.RuneCount(b)
- if !f.Minus {
- // left padding
- f.writePadding(width)
- f.buf.Write(b)
- } else {
- // right padding
- f.buf.Write(b)
- f.writePadding(width)
- }
-}
-
-// padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
-func (f *formatInfo) padString(s string) {
- if !f.WidthPresent || f.Width == 0 {
- f.buf.WriteString(s)
- return
- }
- width := f.Width - utf8.RuneCountInString(s)
- if !f.Minus {
- // left padding
- f.writePadding(width)
- f.buf.WriteString(s)
- } else {
- // right padding
- f.buf.WriteString(s)
- f.writePadding(width)
- }
-}
-
-// fmt_boolean formats a boolean.
-func (f *formatInfo) fmt_boolean(v bool) {
- if v {
- f.padString("true")
- } else {
- f.padString("false")
- }
-}
-
-// fmt_unicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'".
-func (f *formatInfo) fmt_unicode(u uint64) {
- buf := f.intbuf[0:]
-
- // With default precision set the maximum needed buf length is 18
- // for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits
- // into the already allocated intbuf with a capacity of 68 bytes.
- prec := 4
- if f.PrecPresent && f.Prec > 4 {
- prec = f.Prec
- // Compute space needed for "U+" , number, " '", character, "'".
- width := 2 + prec + 2 + utf8.UTFMax + 1
- if width > len(buf) {
- buf = make([]byte, width)
- }
- }
-
- // Format into buf, ending at buf[i]. Formatting numbers is easier right-to-left.
- i := len(buf)
-
- // For %#U we want to add a space and a quoted character at the end of the buffer.
- if f.Sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
- i--
- buf[i] = '\''
- i -= utf8.RuneLen(rune(u))
- utf8.EncodeRune(buf[i:], rune(u))
- i--
- buf[i] = '\''
- i--
- buf[i] = ' '
- }
- // Format the Unicode code point u as a hexadecimal number.
- for u >= 16 {
- i--
- buf[i] = udigits[u&0xF]
- prec--
- u >>= 4
- }
- i--
- buf[i] = udigits[u]
- prec--
- // Add zeros in front of the number until requested precision is reached.
- for prec > 0 {
- i--
- buf[i] = '0'
- prec--
- }
- // Add a leading "U+".
- i--
- buf[i] = '+'
- i--
- buf[i] = 'U'
-
- oldZero := f.Zero
- f.Zero = false
- f.pad(buf[i:])
- f.Zero = oldZero
-}
-
-// fmt_integer formats signed and unsigned integers.
-func (f *formatInfo) fmt_integer(u uint64, base int, isSigned bool, digits string) {
- negative := isSigned && int64(u) < 0
- if negative {
- u = -u
- }
-
- buf := f.intbuf[0:]
- // The already allocated f.intbuf with a capacity of 68 bytes
- // is large enough for integer formatting when no precision or width is set.
- if f.WidthPresent || f.PrecPresent {
- // Account 3 extra bytes for possible addition of a sign and "0x".
- width := 3 + f.Width + f.Prec // wid and prec are always positive.
- if width > len(buf) {
- // We're going to need a bigger boat.
- buf = make([]byte, width)
- }
- }
-
- // Two ways to ask for extra leading zero digits: %.3d or %03d.
- // If both are specified the f.zero flag is ignored and
- // padding with spaces is used instead.
- prec := 0
- if f.PrecPresent {
- prec = f.Prec
- // Precision of 0 and value of 0 means "print nothing" but padding.
- if prec == 0 && u == 0 {
- oldZero := f.Zero
- f.Zero = false
- f.writePadding(f.Width)
- f.Zero = oldZero
- return
- }
- } else if f.Zero && f.WidthPresent {
- prec = f.Width
- if negative || f.Plus || f.Space {
- prec-- // leave room for sign
- }
- }
-
- // Because printing is easier right-to-left: format u into buf, ending at buf[i].
- // We could make things marginally faster by splitting the 32-bit case out
- // into a separate block but it's not worth the duplication, so u has 64 bits.
- i := len(buf)
- // Use constants for the division and modulo for more efficient code.
- // Switch cases ordered by popularity.
- switch base {
- case 10:
- for u >= 10 {
- i--
- next := u / 10
- buf[i] = byte('0' + u - next*10)
- u = next
- }
- case 16:
- for u >= 16 {
- i--
- buf[i] = digits[u&0xF]
- u >>= 4
- }
- case 8:
- for u >= 8 {
- i--
- buf[i] = byte('0' + u&7)
- u >>= 3
- }
- case 2:
- for u >= 2 {
- i--
- buf[i] = byte('0' + u&1)
- u >>= 1
- }
- default:
- panic("fmt: unknown base; can't happen")
- }
- i--
- buf[i] = digits[u]
- for i > 0 && prec > len(buf)-i {
- i--
- buf[i] = '0'
- }
-
- // Various prefixes: 0x, -, etc.
- if f.Sharp {
- switch base {
- case 8:
- if buf[i] != '0' {
- i--
- buf[i] = '0'
- }
- case 16:
- // Add a leading 0x or 0X.
- i--
- buf[i] = digits[16]
- i--
- buf[i] = '0'
- }
- }
-
- if negative {
- i--
- buf[i] = '-'
- } else if f.Plus {
- i--
- buf[i] = '+'
- } else if f.Space {
- i--
- buf[i] = ' '
- }
-
- // Left padding with zeros has already been handled like precision earlier
- // or the f.zero flag is ignored due to an explicitly set precision.
- oldZero := f.Zero
- f.Zero = false
- f.pad(buf[i:])
- f.Zero = oldZero
-}
-
-// truncate truncates the string to the specified precision, if present.
-func (f *formatInfo) truncate(s string) string {
- if f.PrecPresent {
- n := f.Prec
- for i := range s {
- n--
- if n < 0 {
- return s[:i]
- }
- }
- }
- return s
-}
-
-// fmt_s formats a string.
-func (f *formatInfo) fmt_s(s string) {
- s = f.truncate(s)
- f.padString(s)
-}
-
-// fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes.
-func (f *formatInfo) fmt_sbx(s string, b []byte, digits string) {
- length := len(b)
- if b == nil {
- // No byte slice present. Assume string s should be encoded.
- length = len(s)
- }
- // Set length to not process more bytes than the precision demands.
- if f.PrecPresent && f.Prec < length {
- length = f.Prec
- }
- // Compute width of the encoding taking into account the f.sharp and f.space flag.
- width := 2 * length
- if width > 0 {
- if f.Space {
- // Each element encoded by two hexadecimals will get a leading 0x or 0X.
- if f.Sharp {
- width *= 2
- }
- // Elements will be separated by a space.
- width += length - 1
- } else if f.Sharp {
- // Only a leading 0x or 0X will be added for the whole string.
- width += 2
- }
- } else { // The byte slice or string that should be encoded is empty.
- if f.WidthPresent {
- f.writePadding(f.Width)
- }
- return
- }
- // Handle padding to the left.
- if f.WidthPresent && f.Width > width && !f.Minus {
- f.writePadding(f.Width - width)
- }
- // Write the encoding directly into the output buffer.
- buf := f.buf
- if f.Sharp {
- // Add leading 0x or 0X.
- buf.WriteByte('0')
- buf.WriteByte(digits[16])
- }
- var c byte
- for i := 0; i < length; i++ {
- if f.Space && i > 0 {
- // Separate elements with a space.
- buf.WriteByte(' ')
- if f.Sharp {
- // Add leading 0x or 0X for each element.
- buf.WriteByte('0')
- buf.WriteByte(digits[16])
- }
- }
- if b != nil {
- c = b[i] // Take a byte from the input byte slice.
- } else {
- c = s[i] // Take a byte from the input string.
- }
- // Encode each byte as two hexadecimal digits.
- buf.WriteByte(digits[c>>4])
- buf.WriteByte(digits[c&0xF])
- }
- // Handle padding to the right.
- if f.WidthPresent && f.Width > width && f.Minus {
- f.writePadding(f.Width - width)
- }
-}
-
-// fmt_sx formats a string as a hexadecimal encoding of its bytes.
-func (f *formatInfo) fmt_sx(s, digits string) {
- f.fmt_sbx(s, nil, digits)
-}
-
-// fmt_bx formats a byte slice as a hexadecimal encoding of its bytes.
-func (f *formatInfo) fmt_bx(b []byte, digits string) {
- f.fmt_sbx("", b, digits)
-}
-
-// fmt_q formats a string as a double-quoted, escaped Go string constant.
-// If f.sharp is set a raw (backquoted) string may be returned instead
-// if the string does not contain any control characters other than tab.
-func (f *formatInfo) fmt_q(s string) {
- s = f.truncate(s)
- if f.Sharp && strconv.CanBackquote(s) {
- f.padString("`" + s + "`")
- return
- }
- buf := f.intbuf[:0]
- if f.Plus {
- f.pad(strconv.AppendQuoteToASCII(buf, s))
- } else {
- f.pad(strconv.AppendQuote(buf, s))
- }
-}
-
-// fmt_c formats an integer as a Unicode character.
-// If the character is not valid Unicode, it will print '\ufffd'.
-func (f *formatInfo) fmt_c(c uint64) {
- r := rune(c)
- if c > utf8.MaxRune {
- r = utf8.RuneError
- }
- buf := f.intbuf[:0]
- w := utf8.EncodeRune(buf[:utf8.UTFMax], r)
- f.pad(buf[:w])
-}
-
-// fmt_qc formats an integer as a single-quoted, escaped Go character constant.
-// If the character is not valid Unicode, it will print '\ufffd'.
-func (f *formatInfo) fmt_qc(c uint64) {
- r := rune(c)
- if c > utf8.MaxRune {
- r = utf8.RuneError
- }
- buf := f.intbuf[:0]
- if f.Plus {
- f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
- } else {
- f.pad(strconv.AppendQuoteRune(buf, r))
- }
-}
-
-// fmt_float formats a float64. It assumes that verb is a valid format specifier
-// for strconv.AppendFloat and therefore fits into a byte.
-func (f *formatInfo) fmt_float(v float64, size int, verb rune, prec int) {
- // Explicit precision in format specifier overrules default precision.
- if f.PrecPresent {
- prec = f.Prec
- }
- // Format number, reserving space for leading + sign if needed.
- num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size)
- if num[1] == '-' || num[1] == '+' {
- num = num[1:]
- } else {
- num[0] = '+'
- }
- // f.space means to add a leading space instead of a "+" sign unless
- // the sign is explicitly asked for by f.plus.
- if f.Space && num[0] == '+' && !f.Plus {
- num[0] = ' '
- }
- // Special handling for infinities and NaN,
- // which don't look like a number so shouldn't be padded with zeros.
- if num[1] == 'I' || num[1] == 'N' {
- oldZero := f.Zero
- f.Zero = false
- // Remove sign before NaN if not asked for.
- if num[1] == 'N' && !f.Space && !f.Plus {
- num = num[1:]
- }
- f.pad(num)
- f.Zero = oldZero
- return
- }
- // The sharp flag forces printing a decimal point for non-binary formats
- // and retains trailing zeros, which we may need to restore.
- if f.Sharp && verb != 'b' {
- digits := 0
- switch verb {
- case 'v', 'g', 'G':
- digits = prec
- // If no precision is set explicitly use a precision of 6.
- if digits == -1 {
- digits = 6
- }
- }
-
- // Buffer pre-allocated with enough room for
- // exponent notations of the form "e+123".
- var tailBuf [5]byte
- tail := tailBuf[:0]
-
- hasDecimalPoint := false
- // Starting from i = 1 to skip sign at num[0].
- for i := 1; i < len(num); i++ {
- switch num[i] {
- case '.':
- hasDecimalPoint = true
- case 'e', 'E':
- tail = append(tail, num[i:]...)
- num = num[:i]
- default:
- digits--
- }
- }
- if !hasDecimalPoint {
- num = append(num, '.')
- }
- for digits > 0 {
- num = append(num, '0')
- digits--
- }
- num = append(num, tail...)
- }
- // We want a sign if asked for and if the sign is not positive.
- if f.Plus || num[0] != '+' {
- // If we're zero padding to the left we want the sign before the leading zeros.
- // Achieve this by writing the sign out and then padding the unsigned number.
- if f.Zero && f.WidthPresent && f.Width > len(num) {
- f.buf.WriteByte(num[0])
- f.writePadding(f.Width - len(num))
- f.buf.Write(num[1:])
- return
- }
- f.pad(num)
- return
- }
- // No sign to show and the number is positive; just print the unsigned number.
- f.pad(num[1:])
-}
diff --git a/vendor/golang.org/x/text/message/message.go b/vendor/golang.org/x/text/message/message.go
deleted file mode 100644
index a3473bffd..000000000
--- a/vendor/golang.org/x/text/message/message.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package message // import "golang.org/x/text/message"
-
-import (
- "io"
- "os"
-
- // Include features to facilitate generated catalogs.
- _ "golang.org/x/text/feature/plural"
-
- "golang.org/x/text/internal/number"
- "golang.org/x/text/language"
- "golang.org/x/text/message/catalog"
-)
-
-// A Printer implements language-specific formatted I/O analogous to the fmt
-// package.
-type Printer struct {
- // the language
- tag language.Tag
-
- toDecimal number.Formatter
- toScientific number.Formatter
-
- cat catalog.Catalog
-}
-
-type options struct {
- cat catalog.Catalog
- // TODO:
- // - allow %s to print integers in written form (tables are likely too large
- // to enable this by default).
- // - list behavior
- //
-}
-
-// An Option defines an option of a Printer.
-type Option func(o *options)
-
-// Catalog defines the catalog to be used.
-func Catalog(c catalog.Catalog) Option {
- return func(o *options) { o.cat = c }
-}
-
-// NewPrinter returns a Printer that formats messages tailored to language t.
-func NewPrinter(t language.Tag, opts ...Option) *Printer {
- options := &options{
- cat: DefaultCatalog,
- }
- for _, o := range opts {
- o(options)
- }
- p := &Printer{
- tag: t,
- cat: options.cat,
- }
- p.toDecimal.InitDecimal(t)
- p.toScientific.InitScientific(t)
- return p
-}
-
-// Sprint is like fmt.Sprint, but using language-specific formatting.
-func (p *Printer) Sprint(a ...interface{}) string {
- pp := newPrinter(p)
- pp.doPrint(a)
- s := pp.String()
- pp.free()
- return s
-}
-
-// Fprint is like fmt.Fprint, but using language-specific formatting.
-func (p *Printer) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
- pp := newPrinter(p)
- pp.doPrint(a)
- n64, err := io.Copy(w, &pp.Buffer)
- pp.free()
- return int(n64), err
-}
-
-// Print is like fmt.Print, but using language-specific formatting.
-func (p *Printer) Print(a ...interface{}) (n int, err error) {
- return p.Fprint(os.Stdout, a...)
-}
-
-// Sprintln is like fmt.Sprintln, but using language-specific formatting.
-func (p *Printer) Sprintln(a ...interface{}) string {
- pp := newPrinter(p)
- pp.doPrintln(a)
- s := pp.String()
- pp.free()
- return s
-}
-
-// Fprintln is like fmt.Fprintln, but using language-specific formatting.
-func (p *Printer) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
- pp := newPrinter(p)
- pp.doPrintln(a)
- n64, err := io.Copy(w, &pp.Buffer)
- pp.free()
- return int(n64), err
-}
-
-// Println is like fmt.Println, but using language-specific formatting.
-func (p *Printer) Println(a ...interface{}) (n int, err error) {
- return p.Fprintln(os.Stdout, a...)
-}
-
-// Sprintf is like fmt.Sprintf, but using language-specific formatting.
-func (p *Printer) Sprintf(key Reference, a ...interface{}) string {
- pp := newPrinter(p)
- lookupAndFormat(pp, key, a)
- s := pp.String()
- pp.free()
- return s
-}
-
-// Fprintf is like fmt.Fprintf, but using language-specific formatting.
-func (p *Printer) Fprintf(w io.Writer, key Reference, a ...interface{}) (n int, err error) {
- pp := newPrinter(p)
- lookupAndFormat(pp, key, a)
- n, err = w.Write(pp.Bytes())
- pp.free()
- return n, err
-
-}
-
-// Printf is like fmt.Printf, but using language-specific formatting.
-func (p *Printer) Printf(key Reference, a ...interface{}) (n int, err error) {
- pp := newPrinter(p)
- lookupAndFormat(pp, key, a)
- n, err = os.Stdout.Write(pp.Bytes())
- pp.free()
- return n, err
-}
-
-func lookupAndFormat(p *printer, r Reference, a []interface{}) {
- p.fmt.Reset(a)
- var id, msg string
- switch v := r.(type) {
- case string:
- id, msg = v, v
- case key:
- id, msg = v.id, v.fallback
- default:
- panic("key argument is not a Reference")
- }
-
- if p.catContext.Execute(id) == catalog.ErrNotFound {
- if p.catContext.Execute(msg) == catalog.ErrNotFound {
- p.Render(msg)
- return
- }
- }
-}
-
-// Arg implements catmsg.Renderer.
-func (p *printer) Arg(i int) interface{} { // TODO, also return "ok" bool
- i--
- if uint(i) < uint(len(p.fmt.Args)) {
- return p.fmt.Args[i]
- }
- return nil
-}
-
-// Render implements catmsg.Renderer.
-func (p *printer) Render(msg string) {
- p.doPrintf(msg)
-}
-
-// A Reference is a string or a message reference.
-type Reference interface {
- // TODO: also allow []string
-}
-
-// Key creates a message Reference for a message where the given id is used for
-// message lookup and the fallback is returned when no matches are found.
-func Key(id string, fallback string) Reference {
- return key{id, fallback}
-}
-
-type key struct {
- id, fallback string
-}
diff --git a/vendor/golang.org/x/text/message/message_test.go b/vendor/golang.org/x/text/message/message_test.go
deleted file mode 100644
index 326f716fb..000000000
--- a/vendor/golang.org/x/text/message/message_test.go
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package message
-
-import (
- "bytes"
- "fmt"
- "io"
- "testing"
-
- "golang.org/x/text/internal"
- "golang.org/x/text/internal/format"
- "golang.org/x/text/language"
- "golang.org/x/text/message/catalog"
-)
-
-type formatFunc func(s fmt.State, v rune)
-
-func (f formatFunc) Format(s fmt.State, v rune) { f(s, v) }
-
-func TestBinding(t *testing.T) {
- testCases := []struct {
- tag string
- value interface{}
- want string
- }{
- {"en", 1, "1"},
- {"en", "2", "2"},
- { // Language is passed.
- "en",
- formatFunc(func(fs fmt.State, v rune) {
- s := fs.(format.State)
- io.WriteString(s, s.Language().String())
- }),
- "en",
- },
- }
- for i, tc := range testCases {
- p := NewPrinter(language.MustParse(tc.tag))
- if got := p.Sprint(tc.value); got != tc.want {
- t.Errorf("%d:%s:Sprint(%v) = %q; want %q", i, tc.tag, tc.value, got, tc.want)
- }
- var buf bytes.Buffer
- p.Fprint(&buf, tc.value)
- if got := buf.String(); got != tc.want {
- t.Errorf("%d:%s:Fprint(%v) = %q; want %q", i, tc.tag, tc.value, got, tc.want)
- }
- }
-}
-
-func TestLocalization(t *testing.T) {
- type test struct {
- tag string
- key Reference
- args []interface{}
- want string
- }
- args := func(x ...interface{}) []interface{} { return x }
- empty := []interface{}{}
- joe := []interface{}{"Joe"}
- joeAndMary := []interface{}{"Joe", "Mary"}
-
- testCases := []struct {
- desc string
- cat []entry
- test []test
- }{{
- desc: "empty",
- test: []test{
- {"en", "key", empty, "key"},
- {"en", "", empty, ""},
- {"nl", "", empty, ""},
- },
- }, {
- desc: "hierarchical languages",
- cat: []entry{
- {"en", "hello %s", "Hello %s!"},
- {"en-GB", "hello %s", "Hellø %s!"},
- {"en-US", "hello %s", "Howdy %s!"},
- {"en", "greetings %s and %s", "Greetings %s and %s!"},
- },
- test: []test{
- {"und", "hello %s", joe, "hello Joe"},
- {"nl", "hello %s", joe, "hello Joe"},
- {"en", "hello %s", joe, "Hello Joe!"},
- {"en-US", "hello %s", joe, "Howdy Joe!"},
- {"en-GB", "hello %s", joe, "Hellø Joe!"},
- {"en-oxendict", "hello %s", joe, "Hello Joe!"},
- {"en-US-oxendict-u-ms-metric", "hello %s", joe, "Howdy Joe!"},
-
- {"und", "greetings %s and %s", joeAndMary, "greetings Joe and Mary"},
- {"nl", "greetings %s and %s", joeAndMary, "greetings Joe and Mary"},
- {"en", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"},
- {"en-US", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"},
- {"en-GB", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"},
- {"en-oxendict", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"},
- {"en-US-oxendict-u-ms-metric", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"},
- },
- }, {
- desc: "references",
- cat: []entry{
- {"en", "hello", "Hello!"},
- },
- test: []test{
- {"en", "hello", empty, "Hello!"},
- {"en", Key("hello", "fallback"), empty, "Hello!"},
- {"en", Key("xxx", "fallback"), empty, "fallback"},
- {"und", Key("hello", "fallback"), empty, "fallback"},
- },
- }, {
- desc: "zero substitution", // work around limitation of fmt
- cat: []entry{
- {"en", "hello %s", "Hello!"},
- {"en", "hi %s and %s", "Hello %[2]s!"},
- },
- test: []test{
- {"en", "hello %s", joe, "Hello!"},
- {"en", "hello %s", joeAndMary, "Hello!"},
- {"en", "hi %s and %s", joeAndMary, "Hello Mary!"},
- // The following tests resolve to the fallback string.
- {"und", "hello", joeAndMary, "hello"},
- {"und", "hello %%%%", joeAndMary, "hello %%"},
- {"und", "hello %#%%4.2% ", joeAndMary, "hello %% "},
- {"und", "hello %s", joeAndMary, "hello Joe%!(EXTRA string=Mary)"},
- {"und", "hello %+%%s", joeAndMary, "hello %Joe%!(EXTRA string=Mary)"},
- {"und", "hello %-42%%s ", joeAndMary, "hello %Joe %!(EXTRA string=Mary)"},
- },
- }, {
- desc: "number formatting", // work around limitation of fmt
- cat: []entry{
- {"und", "files", "%d files left"},
- {"und", "meters", "%.2f meters"},
- {"de", "files", "%d Dateien übrig"},
- },
- test: []test{
- {"en", "meters", args(3000.2), "3,000.20 meters"},
- {"en-u-nu-gujr", "files", args(123456), "૧૨૩,૪૫૬ files left"},
- {"de", "files", args(1234), "1.234 Dateien übrig"},
- {"de-CH", "files", args(1234), "1’234 Dateien übrig"},
- {"de-CH-u-nu-mong", "files", args(1234), "᠑’᠒᠓᠔ Dateien übrig"},
- },
- }}
-
- for _, tc := range testCases {
- cat, _ := initCat(tc.cat)
-
- for i, pt := range tc.test {
- t.Run(fmt.Sprintf("%s:%d", tc.desc, i), func(t *testing.T) {
- p := NewPrinter(language.MustParse(pt.tag), Catalog(cat))
-
- if got := p.Sprintf(pt.key, pt.args...); got != pt.want {
- t.Errorf("Sprintf(%q, %v) = %s; want %s",
- pt.key, pt.args, got, pt.want)
- return // Next error will likely be the same.
- }
-
- w := &bytes.Buffer{}
- p.Fprintf(w, pt.key, pt.args...)
- if got := w.String(); got != pt.want {
- t.Errorf("Fprintf(%q, %v) = %s; want %s",
- pt.key, pt.args, got, pt.want)
- }
- })
- }
- }
-}
-
-type entry struct{ tag, key, msg string }
-
-func initCat(entries []entry) (*catalog.Builder, []language.Tag) {
- tags := []language.Tag{}
- cat := catalog.NewBuilder()
- for _, e := range entries {
- tag := language.MustParse(e.tag)
- tags = append(tags, tag)
- cat.SetString(tag, e.key, e.msg)
- }
- return cat, internal.UniqueTags(tags)
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/extract.go b/vendor/golang.org/x/text/message/pipeline/extract.go
deleted file mode 100644
index 379cc6d86..000000000
--- a/vendor/golang.org/x/text/message/pipeline/extract.go
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pipeline
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/constant"
- "go/format"
- "go/token"
- "go/types"
- "path"
- "path/filepath"
- "strings"
- "unicode"
- "unicode/utf8"
-
- fmtparser "golang.org/x/text/internal/format"
- "golang.org/x/tools/go/loader"
-)
-
-// TODO:
-// - merge information into existing files
-// - handle different file formats (PO, XLIFF)
-// - handle features (gender, plural)
-// - message rewriting
-
-// - %m substitutions
-// - `msg:"etc"` tags
-// - msg/Msg top-level vars and strings.
-
-// Extract extracts all strings form the package defined in Config.
-func Extract(c *Config) (*State, error) {
- conf := loader.Config{}
- prog, err := loadPackages(&conf, c.Packages)
- if err != nil {
- return nil, wrap(err, "")
- }
-
- // print returns Go syntax for the specified node.
- print := func(n ast.Node) string {
- var buf bytes.Buffer
- format.Node(&buf, conf.Fset, n)
- return buf.String()
- }
-
- var messages []Message
-
- for _, info := range prog.AllPackages {
- for _, f := range info.Files {
- // Associate comments with nodes.
- cmap := ast.NewCommentMap(prog.Fset, f, f.Comments)
- getComment := func(n ast.Node) string {
- cs := cmap.Filter(n).Comments()
- if len(cs) > 0 {
- return strings.TrimSpace(cs[0].Text())
- }
- return ""
- }
-
- // Find function calls.
- ast.Inspect(f, func(n ast.Node) bool {
- call, ok := n.(*ast.CallExpr)
- if !ok {
- return true
- }
-
- // Skip calls of functions other than
- // (*message.Printer).{Sp,Fp,P}rintf.
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return true
- }
- meth := info.Selections[sel]
- if meth == nil || meth.Kind() != types.MethodVal {
- return true
- }
- // TODO: remove cheap hack and check if the type either
- // implements some interface or is specifically of type
- // "golang.org/x/text/message".Printer.
- m, ok := extractFuncs[path.Base(meth.Recv().String())]
- if !ok {
- return true
- }
-
- fmtType, ok := m[meth.Obj().Name()]
- if !ok {
- return true
- }
- // argn is the index of the format string.
- argn := fmtType.arg
- if argn >= len(call.Args) {
- return true
- }
-
- args := call.Args[fmtType.arg:]
-
- fmtMsg, ok := msgStr(info, args[0])
- if !ok {
- // TODO: identify the type of the format argument. If it
- // is not a string, multiple keys may be defined.
- return true
- }
- comment := ""
- key := []string{}
- if ident, ok := args[0].(*ast.Ident); ok {
- key = append(key, ident.Name)
- if v, ok := ident.Obj.Decl.(*ast.ValueSpec); ok && v.Comment != nil {
- // TODO: get comment above ValueSpec as well
- comment = v.Comment.Text()
- }
- }
-
- arguments := []argument{}
- args = args[1:]
- simArgs := make([]interface{}, len(args))
- for i, arg := range args {
- expr := print(arg)
- val := ""
- if v := info.Types[arg].Value; v != nil {
- val = v.ExactString()
- simArgs[i] = val
- switch arg.(type) {
- case *ast.BinaryExpr, *ast.UnaryExpr:
- expr = val
- }
- }
- arguments = append(arguments, argument{
- ArgNum: i + 1,
- Type: info.Types[arg].Type.String(),
- UnderlyingType: info.Types[arg].Type.Underlying().String(),
- Expr: expr,
- Value: val,
- Comment: getComment(arg),
- Position: posString(conf, info, arg.Pos()),
- // TODO report whether it implements
- // interfaces plural.Interface,
- // gender.Interface.
- })
- }
- msg := ""
-
- ph := placeholders{index: map[string]string{}}
-
- trimmed, _, _ := trimWS(fmtMsg)
-
- p := fmtparser.Parser{}
- p.Reset(simArgs)
- for p.SetFormat(trimmed); p.Scan(); {
- switch p.Status {
- case fmtparser.StatusText:
- msg += p.Text()
- case fmtparser.StatusSubstitution,
- fmtparser.StatusBadWidthSubstitution,
- fmtparser.StatusBadPrecSubstitution:
- arguments[p.ArgNum-1].used = true
- arg := arguments[p.ArgNum-1]
- sub := p.Text()
- if !p.HasIndex {
- r, sz := utf8.DecodeLastRuneInString(sub)
- sub = fmt.Sprintf("%s[%d]%c", sub[:len(sub)-sz], p.ArgNum, r)
- }
- msg += fmt.Sprintf("{%s}", ph.addArg(&arg, sub))
- }
- }
- key = append(key, msg)
-
- // Add additional Placeholders that can be used in translations
- // that are not present in the string.
- for _, arg := range arguments {
- if arg.used {
- continue
- }
- ph.addArg(&arg, fmt.Sprintf("%%[%d]v", arg.ArgNum))
- }
-
- if c := getComment(call.Args[0]); c != "" {
- comment = c
- }
-
- messages = append(messages, Message{
- ID: key,
- Key: fmtMsg,
- Message: Text{Msg: msg},
- // TODO(fix): this doesn't get the before comment.
- Comment: comment,
- Placeholders: ph.slice,
- Position: posString(conf, info, call.Lparen),
- })
- return true
- })
- }
- }
-
- return &State{
- Config: *c,
- program: prog,
- Extracted: Messages{
- Language: c.SourceLanguage,
- Messages: messages,
- },
- }, nil
-}
-
-func posString(conf loader.Config, info *loader.PackageInfo, pos token.Pos) string {
- p := conf.Fset.Position(pos)
- file := fmt.Sprintf("%s:%d:%d", filepath.Base(p.Filename), p.Line, p.Column)
- return filepath.Join(info.Pkg.Path(), file)
-}
-
-// extractFuncs indicates the types and methods for which to extract strings,
-// and which argument to extract.
-// TODO: use the types in conf.Import("golang.org/x/text/message") to extract
-// the correct instances.
-var extractFuncs = map[string]map[string]extractType{
- // TODO: Printer -> *golang.org/x/text/message.Printer
- "message.Printer": {
- "Printf": extractType{arg: 0, format: true},
- "Sprintf": extractType{arg: 0, format: true},
- "Fprintf": extractType{arg: 1, format: true},
-
- "Lookup": extractType{arg: 0},
- },
-}
-
-type extractType struct {
- // format indicates if the next arg is a formatted string or whether to
- // concatenate all arguments
- format bool
- // arg indicates the position of the argument to extract.
- arg int
-}
-
-func getID(arg *argument) string {
- s := getLastComponent(arg.Expr)
- s = strip(s)
- s = strings.Replace(s, " ", "", -1)
- // For small variable names, use user-defined types for more info.
- if len(s) <= 2 && arg.UnderlyingType != arg.Type {
- s = getLastComponent(arg.Type)
- }
- return strings.Title(s)
-}
-
-// strip is a dirty hack to convert function calls to placeholder IDs.
-func strip(s string) string {
- s = strings.Map(func(r rune) rune {
- if unicode.IsSpace(r) || r == '-' {
- return '_'
- }
- if !unicode.In(r, unicode.Letter, unicode.Mark, unicode.Number) {
- return -1
- }
- return r
- }, s)
- // Strip "Get" from getter functions.
- if strings.HasPrefix(s, "Get") || strings.HasPrefix(s, "get") {
- if len(s) > len("get") {
- r, _ := utf8.DecodeRuneInString(s)
- if !unicode.In(r, unicode.Ll, unicode.M) { // not lower or mark
- s = s[len("get"):]
- }
- }
- }
- return s
-}
-
-type placeholders struct {
- index map[string]string
- slice []Placeholder
-}
-
-func (p *placeholders) addArg(arg *argument, sub string) (id string) {
- id = getID(arg)
- id1 := id
- alt, ok := p.index[id1]
- for i := 1; ok && alt != sub; i++ {
- id1 = fmt.Sprintf("%s_%d", id, i)
- alt, ok = p.index[id1]
- }
- p.index[id1] = sub
- p.slice = append(p.slice, Placeholder{
- ID: id1,
- String: sub,
- Type: arg.Type,
- UnderlyingType: arg.UnderlyingType,
- ArgNum: arg.ArgNum,
- Expr: arg.Expr,
- Comment: arg.Comment,
- })
- return id1
-}
-
-func getLastComponent(s string) string {
- return s[1+strings.LastIndexByte(s, '.'):]
-}
-
-func msgStr(info *loader.PackageInfo, e ast.Expr) (s string, ok bool) {
- v := info.Types[e].Value
- if v == nil || v.Kind() != constant.String {
- return "", false
- }
- s = constant.StringVal(v)
- // Only record strings with letters.
- for _, r := range s {
- if unicode.In(r, unicode.L) {
- return s, true
- }
- }
- return "", false
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/generate.go b/vendor/golang.org/x/text/message/pipeline/generate.go
deleted file mode 100644
index 5d329b2f4..000000000
--- a/vendor/golang.org/x/text/message/pipeline/generate.go
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pipeline
-
-import (
- "fmt"
- "go/build"
- "io"
- "path/filepath"
- "regexp"
- "sort"
- "strings"
- "text/template"
-
- "golang.org/x/text/collate"
- "golang.org/x/text/feature/plural"
- "golang.org/x/text/internal"
- "golang.org/x/text/internal/catmsg"
- "golang.org/x/text/internal/gen"
- "golang.org/x/text/language"
- "golang.org/x/tools/go/loader"
-)
-
-var transRe = regexp.MustCompile(`messages\.(.*)\.json`)
-
-// Generate writes a Go file that defines a Catalog with translated messages.
-// Translations are retrieved from s.Messages, not s.Translations, so it
-// is assumed Merge has been called.
-func (s *State) Generate() error {
- path := s.Config.GenPackage
- if path == "" {
- path = "."
- }
- isDir := path[0] == '.'
- prog, err := loadPackages(&loader.Config{}, []string{path})
- if err != nil {
- return wrap(err, "could not load package")
- }
- pkgs := prog.InitialPackages()
- if len(pkgs) != 1 {
- return errorf("more than one package selected: %v", pkgs)
- }
- pkg := pkgs[0].Pkg.Name()
-
- cw, err := s.generate()
- if err != nil {
- return err
- }
- if !isDir {
- gopath := build.Default.GOPATH
- path = filepath.Join(gopath, filepath.FromSlash(pkgs[0].Pkg.Path()))
- }
- path = filepath.Join(path, s.Config.GenFile)
- cw.WriteGoFile(path, pkg) // TODO: WriteGoFile should return error.
- return err
-}
-
-// WriteGen writes a Go file with the given package name to w that defines a
-// Catalog with translated messages. Translations are retrieved from s.Messages,
-// not s.Translations, so it is assumed Merge has been called.
-func (s *State) WriteGen(w io.Writer, pkg string) error {
- cw, err := s.generate()
- if err != nil {
- return err
- }
- _, err = cw.WriteGo(w, pkg, "")
- return err
-}
-
-// Generate is deprecated; use (*State).Generate().
-func Generate(w io.Writer, pkg string, extracted *Messages, trans ...Messages) (n int, err error) {
- s := State{
- Extracted: *extracted,
- Translations: trans,
- }
- cw, err := s.generate()
- if err != nil {
- return 0, err
- }
- return cw.WriteGo(w, pkg, "")
-}
-
-func (s *State) generate() (*gen.CodeWriter, error) {
- // Build up index of translations and original messages.
- translations := map[language.Tag]map[string]Message{}
- languages := []language.Tag{}
- usedKeys := map[string]int{}
-
- for _, loc := range s.Messages {
- tag := loc.Language
- if _, ok := translations[tag]; !ok {
- translations[tag] = map[string]Message{}
- languages = append(languages, tag)
- }
- for _, m := range loc.Messages {
- if !m.Translation.IsEmpty() {
- for _, id := range m.ID {
- if _, ok := translations[tag][id]; ok {
- warnf("Duplicate translation in locale %q for message %q", tag, id)
- }
- translations[tag][id] = m
- }
- }
- }
- }
-
- // Verify completeness and register keys.
- internal.SortTags(languages)
-
- langVars := []string{}
- for _, tag := range languages {
- langVars = append(langVars, strings.Replace(tag.String(), "-", "_", -1))
- dict := translations[tag]
- for _, msg := range s.Extracted.Messages {
- for _, id := range msg.ID {
- if trans, ok := dict[id]; ok && !trans.Translation.IsEmpty() {
- if _, ok := usedKeys[msg.Key]; !ok {
- usedKeys[msg.Key] = len(usedKeys)
- }
- break
- }
- // TODO: log missing entry.
- warnf("%s: Missing entry for %q.", tag, id)
- }
- }
- }
-
- cw := gen.NewCodeWriter()
-
- x := &struct {
- Fallback language.Tag
- Languages []string
- }{
- Fallback: s.Extracted.Language,
- Languages: langVars,
- }
-
- if err := lookup.Execute(cw, x); err != nil {
- return nil, wrap(err, "error")
- }
-
- keyToIndex := []string{}
- for k := range usedKeys {
- keyToIndex = append(keyToIndex, k)
- }
- sort.Strings(keyToIndex)
- fmt.Fprint(cw, "var messageKeyToIndex = map[string]int{\n")
- for _, k := range keyToIndex {
- fmt.Fprintf(cw, "%q: %d,\n", k, usedKeys[k])
- }
- fmt.Fprint(cw, "}\n\n")
-
- for i, tag := range languages {
- dict := translations[tag]
- a := make([]string, len(usedKeys))
- for _, msg := range s.Extracted.Messages {
- for _, id := range msg.ID {
- if trans, ok := dict[id]; ok && !trans.Translation.IsEmpty() {
- m, err := assemble(&msg, &trans.Translation)
- if err != nil {
- return nil, wrap(err, "error")
- }
- _, leadWS, trailWS := trimWS(msg.Key)
- if leadWS != "" || trailWS != "" {
- m = catmsg.Affix{
- Message: m,
- Prefix: leadWS,
- Suffix: trailWS,
- }
- }
- // TODO: support macros.
- data, err := catmsg.Compile(tag, nil, m)
- if err != nil {
- return nil, wrap(err, "error")
- }
- key := usedKeys[msg.Key]
- if d := a[key]; d != "" && d != data {
- warnf("Duplicate non-consistent translation for key %q, picking the one for message %q", msg.Key, id)
- }
- a[key] = string(data)
- break
- }
- }
- }
- index := []uint32{0}
- p := 0
- for _, s := range a {
- p += len(s)
- index = append(index, uint32(p))
- }
-
- cw.WriteVar(langVars[i]+"Index", index)
- cw.WriteConst(langVars[i]+"Data", strings.Join(a, ""))
- }
- return cw, nil
-}
-
-func assemble(m *Message, t *Text) (msg catmsg.Message, err error) {
- keys := []string{}
- for k := range t.Var {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- var a []catmsg.Message
- for _, k := range keys {
- t := t.Var[k]
- m, err := assemble(m, &t)
- if err != nil {
- return nil, err
- }
- a = append(a, &catmsg.Var{Name: k, Message: m})
- }
- if t.Select != nil {
- s, err := assembleSelect(m, t.Select)
- if err != nil {
- return nil, err
- }
- a = append(a, s)
- }
- if t.Msg != "" {
- sub, err := m.Substitute(t.Msg)
- if err != nil {
- return nil, err
- }
- a = append(a, catmsg.String(sub))
- }
- switch len(a) {
- case 0:
- return nil, errorf("generate: empty message")
- case 1:
- return a[0], nil
- default:
- return catmsg.FirstOf(a), nil
-
- }
-}
-
-func assembleSelect(m *Message, s *Select) (msg catmsg.Message, err error) {
- cases := []string{}
- for c := range s.Cases {
- cases = append(cases, c)
- }
- sortCases(cases)
-
- caseMsg := []interface{}{}
- for _, c := range cases {
- cm := s.Cases[c]
- m, err := assemble(m, &cm)
- if err != nil {
- return nil, err
- }
- caseMsg = append(caseMsg, c, m)
- }
-
- ph := m.Placeholder(s.Arg)
-
- switch s.Feature {
- case "plural":
- // TODO: only printf-style selects are supported as of yet.
- return plural.Selectf(ph.ArgNum, ph.String, caseMsg...), nil
- }
- return nil, errorf("unknown feature type %q", s.Feature)
-}
-
-func sortCases(cases []string) {
- // TODO: implement full interface.
- sort.Slice(cases, func(i, j int) bool {
- if cases[j] == "other" && cases[i] != "other" {
- return true
- }
- // the following code relies on '<' < '=' < any letter.
- return cmpNumeric(cases[i], cases[j]) == -1
- })
-}
-
-var cmpNumeric = collate.New(language.Und, collate.Numeric).CompareString
-
-var lookup = template.Must(template.New("gen").Parse(`
-import (
- "golang.org/x/text/language"
- "golang.org/x/text/message"
- "golang.org/x/text/message/catalog"
-)
-
-type dictionary struct {
- index []uint32
- data string
-}
-
-func (d *dictionary) Lookup(key string) (data string, ok bool) {
- p := messageKeyToIndex[key]
- start, end := d.index[p], d.index[p+1]
- if start == end {
- return "", false
- }
- return d.data[start:end], true
-}
-
-func init() {
- dict := map[string]catalog.Dictionary{
- {{range .Languages}}"{{.}}": &dictionary{index: {{.}}Index, data: {{.}}Data },
- {{end}}
- }
- fallback := language.MustParse("{{.Fallback}}")
- cat, err := catalog.NewFromMap(dict, catalog.Fallback(fallback))
- if err != nil {
- panic(err)
- }
- message.DefaultCatalog = cat
-}
-
-`))
diff --git a/vendor/golang.org/x/text/message/pipeline/go19_test.go b/vendor/golang.org/x/text/message/pipeline/go19_test.go
deleted file mode 100644
index c9517c130..000000000
--- a/vendor/golang.org/x/text/message/pipeline/go19_test.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.9
-
-package pipeline
-
-import "testing"
-
-func init() {
- setHelper = (*testing.T).Helper
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/message.go b/vendor/golang.org/x/text/message/pipeline/message.go
deleted file mode 100644
index c83a8fd87..000000000
--- a/vendor/golang.org/x/text/message/pipeline/message.go
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pipeline
-
-import (
- "encoding/json"
- "errors"
- "strings"
-
- "golang.org/x/text/language"
-)
-
-// TODO: these definitions should be moved to a package so that the can be used
-// by other tools.
-
-// The file contains the structures used to define translations of a certain
-// messages.
-//
-// A translation may have multiple translations strings, or messages, depending
-// on the feature values of the various arguments. For instance, consider
-// a hypothetical translation from English to English, where the source defines
-// the format string "%d file(s) remaining".
-// See the examples directory for examples of extracted messages.
-
-// Messages is used to store translations for a single language.
-type Messages struct {
- Language language.Tag `json:"language"`
- Messages []Message `json:"messages"`
- Macros map[string]Text `json:"macros,omitempty"`
-}
-
-// A Message describes a message to be translated.
-type Message struct {
- // ID contains a list of identifiers for the message.
- ID IDList `json:"id"`
- // Key is the string that is used to look up the message at runtime.
- Key string `json:"key,omitempty"`
- Meaning string `json:"meaning,omitempty"`
- Message Text `json:"message"`
- Translation Text `json:"translation"`
-
- Comment string `json:"comment,omitempty"`
- TranslatorComment string `json:"translatorComment,omitempty"`
-
- Placeholders []Placeholder `json:"placeholders,omitempty"`
-
- // Fuzzy indicates that the provide translation needs review by a
- // translator, for instance because it was derived from automated
- // translation.
- Fuzzy bool `json:"fuzzy,omitempty"`
-
- // TODO: default placeholder syntax is {foo}. Allow alternative escaping
- // like `foo`.
-
- // Extraction information.
- Position string `json:"position,omitempty"` // filePosition:line
-}
-
-// Placeholder reports the placeholder for the given ID if it is defined or nil
-// otherwise.
-func (m *Message) Placeholder(id string) *Placeholder {
- for _, p := range m.Placeholders {
- if p.ID == id {
- return &p
- }
- }
- return nil
-}
-
-// Substitute replaces placeholders in msg with their original value.
-func (m *Message) Substitute(msg string) (sub string, err error) {
- last := 0
- for i := 0; i < len(msg); {
- pLeft := strings.IndexByte(msg[i:], '{')
- if pLeft == -1 {
- break
- }
- pLeft += i
- pRight := strings.IndexByte(msg[pLeft:], '}')
- if pRight == -1 {
- return "", errorf("unmatched '}'")
- }
- pRight += pLeft
- id := strings.TrimSpace(msg[pLeft+1 : pRight])
- i = pRight + 1
- if id != "" && id[0] == '$' {
- continue
- }
- sub += msg[last:pLeft]
- last = i
- ph := m.Placeholder(id)
- if ph == nil {
- return "", errorf("unknown placeholder %q in message %q", id, msg)
- }
- sub += ph.String
- }
- sub += msg[last:]
- return sub, err
-}
-
-var errIncompatibleMessage = errors.New("messages incompatible")
-
-func checkEquivalence(a, b *Message) error {
- for _, v := range a.ID {
- for _, w := range b.ID {
- if v == w {
- return nil
- }
- }
- }
- // TODO: canonicalize placeholders and check for type equivalence.
- return errIncompatibleMessage
-}
-
-// A Placeholder is a part of the message that should not be changed by a
-// translator. It can be used to hide or prettify format strings (e.g. %d or
-// {{.Count}}), hide HTML, or mark common names that should not be translated.
-type Placeholder struct {
- // ID is the placeholder identifier without the curly braces.
- ID string `json:"id"`
-
- // String is the string with which to replace the placeholder. This may be a
- // formatting string (for instance "%d" or "{{.Count}}") or a literal string
- // (<div>).
- String string `json:"string"`
-
- Type string `json:"type"`
- UnderlyingType string `json:"underlyingType"`
- // ArgNum and Expr are set if the placeholder is a substitution of an
- // argument.
- ArgNum int `json:"argNum,omitempty"`
- Expr string `json:"expr,omitempty"`
-
- Comment string `json:"comment,omitempty"`
- Example string `json:"example,omitempty"`
-
- // Features contains the features that are available for the implementation
- // of this argument.
- Features []Feature `json:"features,omitempty"`
-}
-
-// An argument contains information about the arguments passed to a message.
-type argument struct {
- // ArgNum corresponds to the number that should be used for explicit argument indexes (e.g.
- // "%[1]d").
- ArgNum int `json:"argNum,omitempty"`
-
- used bool // Used by Placeholder
- Type string `json:"type"`
- UnderlyingType string `json:"underlyingType"`
- Expr string `json:"expr"`
- Value string `json:"value,omitempty"`
- Comment string `json:"comment,omitempty"`
- Position string `json:"position,omitempty"`
-}
-
-// Feature holds information about a feature that can be implemented by
-// an Argument.
-type Feature struct {
- Type string `json:"type"` // Right now this is only gender and plural.
-
- // TODO: possible values and examples for the language under consideration.
-
-}
-
-// Text defines a message to be displayed.
-type Text struct {
- // Msg and Select contains the message to be displayed. Msg may be used as
- // a fallback value if none of the select cases match.
- Msg string `json:"msg,omitempty"`
- Select *Select `json:"select,omitempty"`
-
- // Var defines a map of variables that may be substituted in the selected
- // message.
- Var map[string]Text `json:"var,omitempty"`
-
- // Example contains an example message formatted with default values.
- Example string `json:"example,omitempty"`
-}
-
-// IsEmpty reports whether this Text can generate anything.
-func (t *Text) IsEmpty() bool {
- return t.Msg == "" && t.Select == nil && t.Var == nil
-}
-
-// rawText erases the UnmarshalJSON method.
-type rawText Text
-
-// UnmarshalJSON implements json.Unmarshaler.
-func (t *Text) UnmarshalJSON(b []byte) error {
- if b[0] == '"' {
- return json.Unmarshal(b, &t.Msg)
- }
- return json.Unmarshal(b, (*rawText)(t))
-}
-
-// MarshalJSON implements json.Marshaler.
-func (t *Text) MarshalJSON() ([]byte, error) {
- if t.Select == nil && t.Var == nil && t.Example == "" {
- return json.Marshal(t.Msg)
- }
- return json.Marshal((*rawText)(t))
-}
-
-// IDList is a set identifiers that each may refer to possibly different
-// versions of the same message. When looking up a messages, the first
-// identifier in the list takes precedence.
-type IDList []string
-
-// UnmarshalJSON implements json.Unmarshaler.
-func (id *IDList) UnmarshalJSON(b []byte) error {
- if b[0] == '"' {
- *id = []string{""}
- return json.Unmarshal(b, &((*id)[0]))
- }
- return json.Unmarshal(b, (*[]string)(id))
-}
-
-// MarshalJSON implements json.Marshaler.
-func (id *IDList) MarshalJSON() ([]byte, error) {
- if len(*id) == 1 {
- return json.Marshal((*id)[0])
- }
- return json.Marshal((*[]string)(id))
-}
-
-// Select selects a Text based on the feature value associated with a feature of
-// a certain argument.
-type Select struct {
- Feature string `json:"feature"` // Name of Feature type (e.g plural)
- Arg string `json:"arg"` // The placeholder ID
- Cases map[string]Text `json:"cases"`
-}
-
-// TODO: order matters, but can we derive the ordering from the case keys?
-// type Case struct {
-// Key string `json:"key"`
-// Value Text `json:"value"`
-// }
diff --git a/vendor/golang.org/x/text/message/pipeline/pipeline.go b/vendor/golang.org/x/text/message/pipeline/pipeline.go
deleted file mode 100644
index cafd6f29b..000000000
--- a/vendor/golang.org/x/text/message/pipeline/pipeline.go
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package pipeline provides tools for creating translation pipelines.
-//
-// NOTE: UNDER DEVELOPMENT. API MAY CHANGE.
-package pipeline
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "go/build"
- "go/parser"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "regexp"
- "strings"
- "text/template"
- "unicode"
-
- "golang.org/x/text/internal"
- "golang.org/x/text/language"
- "golang.org/x/text/runes"
- "golang.org/x/tools/go/loader"
-)
-
-const (
- extractFile = "extracted.gotext.json"
- outFile = "out.gotext.json"
- gotextSuffix = "gotext.json"
-)
-
-// Config contains configuration for the translation pipeline.
-type Config struct {
- // Supported indicates the languages for which data should be generated.
- // The default is to support all locales for which there are matching
- // translation files.
- Supported []language.Tag
-
- // --- Extraction
-
- SourceLanguage language.Tag
-
- Packages []string
-
- // --- File structure
-
- // Dir is the root dir for all operations.
- Dir string
-
- // TranslationsPattern is a regular expression to match incoming translation
- // files. These files may appear in any directory rooted at Dir.
- // language for the translation files is determined as follows:
- // 1. From the Language field in the file.
- // 2. If not present, from a valid language tag in the filename, separated
- // by dots (e.g. "en-US.json" or "incoming.pt_PT.xmb").
- // 3. If not present, from a the closest subdirectory in which the file
- // is contained that parses as a valid language tag.
- TranslationsPattern string
-
- // OutPattern defines the location for translation files for a certain
- // language. The default is "{{.Dir}}/{{.Language}}/out.{{.Ext}}"
- OutPattern string
-
- // Format defines the file format for generated translation files.
- // The default is XMB. Alternatives are GetText, XLIFF, L20n, GoText.
- Format string
-
- Ext string
-
- // TODO:
- // Actions are additional actions to be performed after the initial extract
- // and merge.
- // Actions []struct {
- // Name string
- // Options map[string]string
- // }
-
- // --- Generation
-
- // GenFile may be in a different package. It is not defined, it will
- // be written to stdout.
- GenFile string
-
- // GenPackage is the package or relative path into which to generate the
- // file. If not specified it is relative to the current directory.
- GenPackage string
-
- // DeclareVar defines a variable to which to assing the generated Catalog.
- DeclareVar string
-
- // SetDefault determines whether to assign the generated Catalog to
- // message.DefaultCatalog. The default for this is true if DeclareVar is
- // not defined, false otherwise.
- SetDefault bool
-
- // TODO:
- // - Printf-style configuration
- // - Template-style configuration
- // - Extraction options
- // - Rewrite options
- // - Generation options
-}
-
-// Operations:
-// - extract: get the strings
-// - disambiguate: find messages with the same key, but possible different meaning.
-// - create out: create a list of messages that need translations
-// - load trans: load the list of current translations
-// - merge: assign list of translations as done
-// - (action)expand: analyze features and create example sentences for each version.
-// - (action)googletrans: pre-populate messages with automatic translations.
-// - (action)export: send out messages somewhere non-standard
-// - (action)import: load messages from somewhere non-standard
-// - vet program: don't pass "foo" + var + "bar" strings. Not using funcs for translated strings.
-// - vet trans: coverage: all translations/ all features.
-// - generate: generate Go code
-
-// State holds all accumulated information on translations during processing.
-type State struct {
- Config Config
-
- Package string
- program *loader.Program
-
- Extracted Messages `json:"messages"`
-
- // Messages includes all messages for which there need to be translations.
- // Duplicates may be eliminated. Generation will be done from these messages
- // (usually after merging).
- Messages []Messages
-
- // Translations are incoming translations for the application messages.
- Translations []Messages
-}
-
-func (s *State) dir() string {
- if d := s.Config.Dir; d != "" {
- return d
- }
- return "./locales"
-}
-
-func outPattern(s *State) (string, error) {
- c := s.Config
- pat := c.OutPattern
- if pat == "" {
- pat = "{{.Dir}}/{{.Language}}/out.{{.Ext}}"
- }
-
- ext := c.Ext
- if ext == "" {
- ext = c.Format
- }
- if ext == "" {
- ext = gotextSuffix
- }
- t, err := template.New("").Parse(pat)
- if err != nil {
- return "", wrap(err, "error parsing template")
- }
- buf := bytes.Buffer{}
- err = t.Execute(&buf, map[string]string{
- "Dir": s.dir(),
- "Language": "%s",
- "Ext": ext,
- })
- return filepath.FromSlash(buf.String()), wrap(err, "incorrect OutPattern")
-}
-
-var transRE = regexp.MustCompile(`.*\.` + gotextSuffix)
-
-// Import loads existing translation files.
-func (s *State) Import() error {
- outPattern, err := outPattern(s)
- if err != nil {
- return err
- }
- re := transRE
- if pat := s.Config.TranslationsPattern; pat != "" {
- if re, err = regexp.Compile(pat); err != nil {
- return wrapf(err, "error parsing regexp %q", s.Config.TranslationsPattern)
- }
- }
- x := importer{s, outPattern, re}
- return x.walkImport(s.dir(), s.Config.SourceLanguage)
-}
-
-type importer struct {
- state *State
- outPattern string
- transFile *regexp.Regexp
-}
-
-func (i *importer) walkImport(path string, tag language.Tag) error {
- files, err := ioutil.ReadDir(path)
- if err != nil {
- return nil
- }
- for _, f := range files {
- name := f.Name()
- tag := tag
- if f.IsDir() {
- if t, err := language.Parse(name); err == nil {
- tag = t
- }
- // We ignore errors
- if err := i.walkImport(filepath.Join(path, name), tag); err != nil {
- return err
- }
- continue
- }
- for _, l := range strings.Split(name, ".") {
- if t, err := language.Parse(l); err == nil {
- tag = t
- }
- }
- file := filepath.Join(path, name)
- // TODO: Should we skip files that match output files?
- if fmt.Sprintf(i.outPattern, tag) == file {
- continue
- }
- // TODO: handle different file formats.
- if !i.transFile.MatchString(name) {
- continue
- }
- b, err := ioutil.ReadFile(file)
- if err != nil {
- return wrap(err, "read file failed")
- }
- var translations Messages
- if err := json.Unmarshal(b, &translations); err != nil {
- return wrap(err, "parsing translation file failed")
- }
- i.state.Translations = append(i.state.Translations, translations)
- }
- return nil
-}
-
-// Merge merges the extracted messages with the existing translations.
-func (s *State) Merge() error {
- if s.Messages != nil {
- panic("already merged")
- }
- // Create an index for each unique message.
- // Duplicates are okay as long as the substitution arguments are okay as
- // well.
- // Top-level messages are okay to appear in multiple substitution points.
-
- // Collect key equivalence.
- msgs := []*Message{}
- keyToIDs := map[string]*Message{}
- for _, m := range s.Extracted.Messages {
- m := m
- if prev, ok := keyToIDs[m.Key]; ok {
- if err := checkEquivalence(&m, prev); err != nil {
- warnf("Key %q matches conflicting messages: %v and %v", m.Key, prev.ID, m.ID)
- // TODO: track enough information so that the rewriter can
- // suggest/disambiguate messages.
- }
- // TODO: add position to message.
- continue
- }
- i := len(msgs)
- msgs = append(msgs, &m)
- keyToIDs[m.Key] = msgs[i]
- }
-
- // Messages with different keys may still refer to the same translated
- // message (e.g. different whitespace). Filter these.
- idMap := map[string]bool{}
- filtered := []*Message{}
- for _, m := range msgs {
- found := false
- for _, id := range m.ID {
- found = found || idMap[id]
- }
- if !found {
- filtered = append(filtered, m)
- }
- for _, id := range m.ID {
- idMap[id] = true
- }
- }
-
- // Build index of translations.
- translations := map[language.Tag]map[string]Message{}
- languages := append([]language.Tag{}, s.Config.Supported...)
-
- for _, t := range s.Translations {
- tag := t.Language
- if _, ok := translations[tag]; !ok {
- translations[tag] = map[string]Message{}
- languages = append(languages, tag)
- }
- for _, m := range t.Messages {
- if !m.Translation.IsEmpty() {
- for _, id := range m.ID {
- if _, ok := translations[tag][id]; ok {
- warnf("Duplicate translation in locale %q for message %q", tag, id)
- }
- translations[tag][id] = m
- }
- }
- }
- }
- languages = internal.UniqueTags(languages)
-
- for _, tag := range languages {
- ms := Messages{Language: tag}
- for _, orig := range filtered {
- m := *orig
- m.Key = ""
- m.Position = ""
-
- for _, id := range m.ID {
- if t, ok := translations[tag][id]; ok {
- m.Translation = t.Translation
- if t.TranslatorComment != "" {
- m.TranslatorComment = t.TranslatorComment
- m.Fuzzy = t.Fuzzy
- }
- break
- }
- }
- if tag == s.Config.SourceLanguage && m.Translation.IsEmpty() {
- m.Translation = m.Message
- if m.TranslatorComment == "" {
- m.TranslatorComment = "Copied from source."
- m.Fuzzy = true
- }
- }
- // TODO: if translation is empty: pre-expand based on available
- // linguistic features. This may also be done as a plugin.
- ms.Messages = append(ms.Messages, m)
- }
- s.Messages = append(s.Messages, ms)
- }
- return nil
-}
-
-// Export writes out the messages to translation out files.
-func (s *State) Export() error {
- path, err := outPattern(s)
- if err != nil {
- return wrap(err, "export failed")
- }
- for _, out := range s.Messages {
- // TODO: inject translations from existing files to avoid retranslation.
- data, err := json.MarshalIndent(out, "", " ")
- if err != nil {
- return wrap(err, "JSON marshal failed")
- }
- file := fmt.Sprintf(path, out.Language)
- if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
- return wrap(err, "dir create failed")
- }
- if err := ioutil.WriteFile(file, data, 0644); err != nil {
- return wrap(err, "write failed")
- }
- }
- return nil
-}
-
-var (
- ws = runes.In(unicode.White_Space).Contains
- notWS = runes.NotIn(unicode.White_Space).Contains
-)
-
-func trimWS(s string) (trimmed, leadWS, trailWS string) {
- trimmed = strings.TrimRightFunc(s, ws)
- trailWS = s[len(trimmed):]
- if i := strings.IndexFunc(trimmed, notWS); i > 0 {
- leadWS = trimmed[:i]
- trimmed = trimmed[i:]
- }
- return trimmed, leadWS, trailWS
-}
-
-// NOTE: The command line tool already prefixes with "gotext:".
-var (
- wrap = func(err error, msg string) error {
- if err == nil {
- return nil
- }
- return fmt.Errorf("%s: %v", msg, err)
- }
- wrapf = func(err error, msg string, args ...interface{}) error {
- if err == nil {
- return nil
- }
- return wrap(err, fmt.Sprintf(msg, args...))
- }
- errorf = fmt.Errorf
-)
-
-func warnf(format string, args ...interface{}) {
- // TODO: don't log.
- log.Printf(format, args...)
-}
-
-func loadPackages(conf *loader.Config, args []string) (*loader.Program, error) {
- if len(args) == 0 {
- args = []string{"."}
- }
-
- conf.Build = &build.Default
- conf.ParserMode = parser.ParseComments
-
- // Use the initial packages from the command line.
- args, err := conf.FromArgs(args, false)
- if err != nil {
- return nil, wrap(err, "loading packages failed")
- }
-
- // Load, parse and type-check the whole program.
- return conf.Load()
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/pipeline_test.go b/vendor/golang.org/x/text/message/pipeline/pipeline_test.go
deleted file mode 100644
index 293101b25..000000000
--- a/vendor/golang.org/x/text/message/pipeline/pipeline_test.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pipeline
-
-import (
- "bufio"
- "bytes"
- "encoding/json"
- "flag"
- "fmt"
- "io/ioutil"
- "os"
- "path"
- "path/filepath"
- "strings"
- "testing"
-
- "golang.org/x/text/language"
-)
-
-var genFiles = flag.Bool("gen", false, "generate output files instead of comparing")
-
-// setHelper is testing.T.Helper on Go 1.9+, overridden by go19_test.go.
-var setHelper = func(t *testing.T) {}
-
-func TestFullCycle(t *testing.T) {
- const path = "./testdata"
- dirs, err := ioutil.ReadDir(path)
- if err != nil {
- t.Fatal(err)
- }
- for _, f := range dirs {
- t.Run(f.Name(), func(t *testing.T) {
- chk := func(t *testing.T, err error) {
- setHelper(t)
- if err != nil {
- t.Fatal(err)
- }
- }
- dir := filepath.Join(path, f.Name())
- pkgPath := fmt.Sprintf("%s/%s", path, f.Name())
- config := Config{
- SourceLanguage: language.AmericanEnglish,
- Packages: []string{pkgPath},
- Dir: filepath.Join(dir, "locales"),
- GenFile: "catalog_gen.go",
- GenPackage: pkgPath,
- }
- // TODO: load config if available.
- s, err := Extract(&config)
- chk(t, err)
- chk(t, s.Import())
- chk(t, s.Merge())
- // TODO:
- // for range s.Config.Actions {
- // // TODO: do the actions.
- // }
- chk(t, s.Export())
- chk(t, s.Generate())
-
- writeJSON(t, filepath.Join(dir, "extracted.gotext.json"), s.Extracted)
- checkOutput(t, dir)
- })
- }
-}
-
-func checkOutput(t *testing.T, p string) {
- filepath.Walk(p, func(p string, f os.FileInfo, err error) error {
- if f.IsDir() {
- return nil
- }
- if filepath.Ext(p) != ".want" {
- return nil
- }
- gotFile := p[:len(p)-len(".want")]
- got, err := ioutil.ReadFile(gotFile)
- if err != nil {
- t.Errorf("failed to read %q", p)
- return nil
- }
- if *genFiles {
- if err := ioutil.WriteFile(p, got, 0644); err != nil {
- t.Fatal(err)
- }
- }
- want, err := ioutil.ReadFile(p)
- if err != nil {
- t.Errorf("failed to read %q", p)
- } else {
- scanGot := bufio.NewScanner(bytes.NewReader(got))
- scanWant := bufio.NewScanner(bytes.NewReader(want))
- line := 0
- clean := func(s string) string {
- if i := strings.LastIndex(s, "//"); i != -1 {
- s = s[:i]
- }
- return path.Clean(filepath.ToSlash(s))
- }
- for scanGot.Scan() && scanWant.Scan() {
- got := clean(scanGot.Text())
- want := clean(scanWant.Text())
- if got != want {
- t.Errorf("file %q differs from .want file at line %d:\n\t%s\n\t%s", gotFile, line, got, want)
- break
- }
- line++
- }
- if scanGot.Scan() || scanWant.Scan() {
- t.Errorf("file %q differs from .want file at line %d.", gotFile, line)
- }
- }
- return nil
- })
-}
-
-func writeJSON(t *testing.T, path string, x interface{}) {
- data, err := json.MarshalIndent(x, "", " ")
- if err != nil {
- t.Fatal(err)
- }
- if err := ioutil.WriteFile(path, data, 0644); err != nil {
- t.Fatal(err)
- }
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/rewrite.go b/vendor/golang.org/x/text/message/pipeline/rewrite.go
deleted file mode 100644
index cf1511f56..000000000
--- a/vendor/golang.org/x/text/message/pipeline/rewrite.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pipeline
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/constant"
- "go/format"
- "go/token"
- "io"
- "os"
- "strings"
-
- "golang.org/x/tools/go/loader"
-)
-
-const printerType = "golang.org/x/text/message.Printer"
-
-// Rewrite rewrites the Go files in a single package to use the localization
-// machinery and rewrites strings to adopt best practices when possible.
-// If w is not nil the generated files are written to it, each files with a
-// "--- <filename>" header. Otherwise the files are overwritten.
-func Rewrite(w io.Writer, args ...string) error {
- conf := &loader.Config{
- AllowErrors: true, // Allow unused instances of message.Printer.
- }
- prog, err := loadPackages(conf, args)
- if err != nil {
- return wrap(err, "")
- }
-
- for _, info := range prog.InitialPackages() {
- for _, f := range info.Files {
- // Associate comments with nodes.
-
- // Pick up initialized Printers at the package level.
- r := rewriter{info: info, conf: conf}
- for _, n := range info.InitOrder {
- if t := r.info.Types[n.Rhs].Type.String(); strings.HasSuffix(t, printerType) {
- r.printerVar = n.Lhs[0].Name()
- }
- }
-
- ast.Walk(&r, f)
-
- w := w
- if w == nil {
- var err error
- if w, err = os.Create(conf.Fset.File(f.Pos()).Name()); err != nil {
- return wrap(err, "open failed")
- }
- } else {
- fmt.Fprintln(w, "---", conf.Fset.File(f.Pos()).Name())
- }
-
- if err := format.Node(w, conf.Fset, f); err != nil {
- return wrap(err, "go format failed")
- }
- }
- }
-
- return nil
-}
-
-type rewriter struct {
- info *loader.PackageInfo
- conf *loader.Config
- printerVar string
-}
-
-// print returns Go syntax for the specified node.
-func (r *rewriter) print(n ast.Node) string {
- var buf bytes.Buffer
- format.Node(&buf, r.conf.Fset, n)
- return buf.String()
-}
-
-func (r *rewriter) Visit(n ast.Node) ast.Visitor {
- // Save the state by scope.
- if _, ok := n.(*ast.BlockStmt); ok {
- r := *r
- return &r
- }
- // Find Printers created by assignment.
- stmt, ok := n.(*ast.AssignStmt)
- if ok {
- for _, v := range stmt.Lhs {
- if r.printerVar == r.print(v) {
- r.printerVar = ""
- }
- }
- for i, v := range stmt.Rhs {
- if t := r.info.Types[v].Type.String(); strings.HasSuffix(t, printerType) {
- r.printerVar = r.print(stmt.Lhs[i])
- return r
- }
- }
- }
- // Find Printers created by variable declaration.
- spec, ok := n.(*ast.ValueSpec)
- if ok {
- for _, v := range spec.Names {
- if r.printerVar == r.print(v) {
- r.printerVar = ""
- }
- }
- for i, v := range spec.Values {
- if t := r.info.Types[v].Type.String(); strings.HasSuffix(t, printerType) {
- r.printerVar = r.print(spec.Names[i])
- return r
- }
- }
- }
- if r.printerVar == "" {
- return r
- }
- call, ok := n.(*ast.CallExpr)
- if !ok {
- return r
- }
-
- // TODO: Handle literal values?
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return r
- }
- meth := r.info.Selections[sel]
-
- source := r.print(sel.X)
- fun := r.print(sel.Sel)
- if meth != nil {
- source = meth.Recv().String()
- fun = meth.Obj().Name()
- }
-
- // TODO: remove cheap hack and check if the type either
- // implements some interface or is specifically of type
- // "golang.org/x/text/message".Printer.
- m, ok := rewriteFuncs[source]
- if !ok {
- return r
- }
-
- rewriteType, ok := m[fun]
- if !ok {
- return r
- }
- ident := ast.NewIdent(r.printerVar)
- ident.NamePos = sel.X.Pos()
- sel.X = ident
- if rewriteType.method != "" {
- sel.Sel.Name = rewriteType.method
- }
-
- // Analyze arguments.
- argn := rewriteType.arg
- if rewriteType.format || argn >= len(call.Args) {
- return r
- }
- hasConst := false
- for _, a := range call.Args[argn:] {
- if v := r.info.Types[a].Value; v != nil && v.Kind() == constant.String {
- hasConst = true
- break
- }
- }
- if !hasConst {
- return r
- }
- sel.Sel.Name = rewriteType.methodf
-
- // We are done if there is only a single string that does not need to be
- // escaped.
- if len(call.Args) == 1 {
- s, ok := constStr(r.info, call.Args[0])
- if ok && !strings.Contains(s, "%") && !rewriteType.newLine {
- return r
- }
- }
-
- // Rewrite arguments as format string.
- expr := &ast.BasicLit{
- ValuePos: call.Lparen,
- Kind: token.STRING,
- }
- newArgs := append(call.Args[:argn:argn], expr)
- newStr := []string{}
- for i, a := range call.Args[argn:] {
- if s, ok := constStr(r.info, a); ok {
- newStr = append(newStr, strings.Replace(s, "%", "%%", -1))
- } else {
- newStr = append(newStr, "%v")
- newArgs = append(newArgs, call.Args[argn+i])
- }
- }
- s := strings.Join(newStr, rewriteType.sep)
- if rewriteType.newLine {
- s += "\n"
- }
- expr.Value = fmt.Sprintf("%q", s)
-
- call.Args = newArgs
-
- // TODO: consider creating an expression instead of a constant string and
- // then wrapping it in an escape function or so:
- // call.Args[argn+i] = &ast.CallExpr{
- // Fun: &ast.SelectorExpr{
- // X: ast.NewIdent("message"),
- // Sel: ast.NewIdent("Lookup"),
- // },
- // Args: []ast.Expr{a},
- // }
- // }
-
- return r
-}
-
-type rewriteType struct {
- // method is the name of the equivalent method on a printer, or "" if it is
- // the same.
- method string
-
- // methodf is the method to use if the arguments can be rewritten as a
- // arguments to a printf-style call.
- methodf string
-
- // format is true if the method takes a formatting string followed by
- // substitution arguments.
- format bool
-
- // arg indicates the position of the argument to extract. If all is
- // positive, all arguments from this argument onwards needs to be extracted.
- arg int
-
- sep string
- newLine bool
-}
-
-// rewriteFuncs list functions that can be directly mapped to the printer
-// functions of the message package.
-var rewriteFuncs = map[string]map[string]rewriteType{
- // TODO: Printer -> *golang.org/x/text/message.Printer
- "fmt": {
- "Print": rewriteType{methodf: "Printf"},
- "Sprint": rewriteType{methodf: "Sprintf"},
- "Fprint": rewriteType{methodf: "Fprintf"},
-
- "Println": rewriteType{methodf: "Printf", sep: " ", newLine: true},
- "Sprintln": rewriteType{methodf: "Sprintf", sep: " ", newLine: true},
- "Fprintln": rewriteType{methodf: "Fprintf", sep: " ", newLine: true},
-
- "Printf": rewriteType{method: "Printf", format: true},
- "Sprintf": rewriteType{method: "Sprintf", format: true},
- "Fprintf": rewriteType{method: "Fprintf", format: true},
- },
-}
-
-func constStr(info *loader.PackageInfo, e ast.Expr) (s string, ok bool) {
- v := info.Types[e].Value
- if v == nil || v.Kind() != constant.String {
- return "", false
- }
- return constant.StringVal(v), true
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go b/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go
deleted file mode 100644
index 7d93f4868..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-package main
-
-import (
- "golang.org/x/text/language"
- "golang.org/x/text/message"
- "golang.org/x/text/message/catalog"
-)
-
-type dictionary struct {
- index []uint32
- data string
-}
-
-func (d *dictionary) Lookup(key string) (data string, ok bool) {
- p := messageKeyToIndex[key]
- start, end := d.index[p], d.index[p+1]
- if start == end {
- return "", false
- }
- return d.data[start:end], true
-}
-
-func init() {
- dict := map[string]catalog.Dictionary{
- "de": &dictionary{index: deIndex, data: deData},
- "en_US": &dictionary{index: en_USIndex, data: en_USData},
- "zh": &dictionary{index: zhIndex, data: zhData},
- }
- fallback := language.MustParse("en-US")
- cat, err := catalog.NewFromMap(dict, catalog.Fallback(fallback))
- if err != nil {
- panic(err)
- }
- message.DefaultCatalog = cat
-}
-
-var messageKeyToIndex = map[string]int{
- "%.2[1]f miles traveled (%[1]f)": 8,
- "%[1]s is visiting %[3]s!\n": 3,
- "%d files remaining!": 4,
- "%d more files remaining!": 5,
- "%s is out of order!": 7,
- "%s is visiting %s!\n": 2,
- "Hello %s!\n": 1,
- "Hello world!\n": 0,
- "Use the following code for your discount: %d\n": 6,
-}
-
-var deIndex = []uint32{ // 10 elements
- 0x00000000, 0x00000011, 0x00000023, 0x0000003d,
- 0x00000057, 0x00000075, 0x00000094, 0x00000094,
- 0x00000094, 0x00000094,
-} // Size: 64 bytes
-
-const deData string = "" + // Size: 148 bytes
- "\x04\x00\x01\x0a\x0c\x02Hallo Welt!\x04\x00\x01\x0a\x0d\x02Hallo %[1]s!" +
- "\x04\x00\x01\x0a\x15\x02%[1]s besucht %[2]s!\x04\x00\x01\x0a\x15\x02%[1]" +
- "s besucht %[3]s!\x02Noch zwei Bestände zu gehen!\x02Noch %[1]d Bestände " +
- "zu gehen!"
-
-var en_USIndex = []uint32{ // 10 elements
- 0x00000000, 0x00000012, 0x00000024, 0x00000042,
- 0x00000060, 0x00000077, 0x000000ba, 0x000000ef,
- 0x00000106, 0x00000125,
-} // Size: 64 bytes
-
-const en_USData string = "" + // Size: 293 bytes
- "\x04\x00\x01\x0a\x0d\x02Hello world!\x04\x00\x01\x0a\x0d\x02Hello %[1]s!" +
- "\x04\x00\x01\x0a\x19\x02%[1]s is visiting %[2]s!\x04\x00\x01\x0a\x19\x02" +
- "%[1]s is visiting %[3]s!\x02%[1]d files remaining!\x14\x01\x81\x01\x00" +
- "\x02\x14\x02One file remaining!\x00&\x02There are %[1]d more files remai" +
- "ning!\x04\x00\x01\x0a0\x02Use the following code for your discount: %[1]" +
- "d\x02%[1]s is out of order!\x02%.2[1]f miles traveled (%[1]f)"
-
-var zhIndex = []uint32{ // 10 elements
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000,
-} // Size: 64 bytes
-
-const zhData string = ""
-
-// Total table size 633 bytes (0KiB); checksum: 74B32E70
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go.want b/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go.want
deleted file mode 100644
index 7d93f4868..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go.want
+++ /dev/null
@@ -1,85 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-package main
-
-import (
- "golang.org/x/text/language"
- "golang.org/x/text/message"
- "golang.org/x/text/message/catalog"
-)
-
-type dictionary struct {
- index []uint32
- data string
-}
-
-func (d *dictionary) Lookup(key string) (data string, ok bool) {
- p := messageKeyToIndex[key]
- start, end := d.index[p], d.index[p+1]
- if start == end {
- return "", false
- }
- return d.data[start:end], true
-}
-
-func init() {
- dict := map[string]catalog.Dictionary{
- "de": &dictionary{index: deIndex, data: deData},
- "en_US": &dictionary{index: en_USIndex, data: en_USData},
- "zh": &dictionary{index: zhIndex, data: zhData},
- }
- fallback := language.MustParse("en-US")
- cat, err := catalog.NewFromMap(dict, catalog.Fallback(fallback))
- if err != nil {
- panic(err)
- }
- message.DefaultCatalog = cat
-}
-
-var messageKeyToIndex = map[string]int{
- "%.2[1]f miles traveled (%[1]f)": 8,
- "%[1]s is visiting %[3]s!\n": 3,
- "%d files remaining!": 4,
- "%d more files remaining!": 5,
- "%s is out of order!": 7,
- "%s is visiting %s!\n": 2,
- "Hello %s!\n": 1,
- "Hello world!\n": 0,
- "Use the following code for your discount: %d\n": 6,
-}
-
-var deIndex = []uint32{ // 10 elements
- 0x00000000, 0x00000011, 0x00000023, 0x0000003d,
- 0x00000057, 0x00000075, 0x00000094, 0x00000094,
- 0x00000094, 0x00000094,
-} // Size: 64 bytes
-
-const deData string = "" + // Size: 148 bytes
- "\x04\x00\x01\x0a\x0c\x02Hallo Welt!\x04\x00\x01\x0a\x0d\x02Hallo %[1]s!" +
- "\x04\x00\x01\x0a\x15\x02%[1]s besucht %[2]s!\x04\x00\x01\x0a\x15\x02%[1]" +
- "s besucht %[3]s!\x02Noch zwei Bestände zu gehen!\x02Noch %[1]d Bestände " +
- "zu gehen!"
-
-var en_USIndex = []uint32{ // 10 elements
- 0x00000000, 0x00000012, 0x00000024, 0x00000042,
- 0x00000060, 0x00000077, 0x000000ba, 0x000000ef,
- 0x00000106, 0x00000125,
-} // Size: 64 bytes
-
-const en_USData string = "" + // Size: 293 bytes
- "\x04\x00\x01\x0a\x0d\x02Hello world!\x04\x00\x01\x0a\x0d\x02Hello %[1]s!" +
- "\x04\x00\x01\x0a\x19\x02%[1]s is visiting %[2]s!\x04\x00\x01\x0a\x19\x02" +
- "%[1]s is visiting %[3]s!\x02%[1]d files remaining!\x14\x01\x81\x01\x00" +
- "\x02\x14\x02One file remaining!\x00&\x02There are %[1]d more files remai" +
- "ning!\x04\x00\x01\x0a0\x02Use the following code for your discount: %[1]" +
- "d\x02%[1]s is out of order!\x02%.2[1]f miles traveled (%[1]f)"
-
-var zhIndex = []uint32{ // 10 elements
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000,
-} // Size: 64 bytes
-
-const zhData string = ""
-
-// Total table size 633 bytes (0KiB); checksum: 74B32E70
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_test.go b/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_test.go
deleted file mode 100644
index eeb7c25f4..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_test.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "path"
- "testing"
-
- "golang.org/x/text/message"
-)
-
-func TestCatalog(t *testing.T) {
- args := func(a ...interface{}) []interface{} { return a }
- testCases := []struct {
- lang string
- key string
- args []interface{}
- want string
- }{{
- lang: "en",
- key: "Hello world!\n",
- want: "Hello world!\n",
- }, {
- lang: "de",
- key: "Hello world!\n",
- want: "Hallo Welt!\n",
- }, {
- lang: "en",
- key: "%d more files remaining!",
- args: args(1),
- want: "One file remaining!",
- }, {
- lang: "en-u-nu-fullwide",
- key: "%d more files remaining!",
- args: args(5),
- want: "There are 5 more files remaining!",
- }}
- for _, tc := range testCases {
- t.Run(path.Join(tc.lang, tc.key), func(t *testing.T) {
- p := message.NewPrinter(message.MatchLanguage(tc.lang))
- got := p.Sprintf(tc.key, tc.args...)
- if got != tc.want {
- t.Errorf("got %q; want %q", got, tc.want)
- }
- })
- }
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json b/vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json
deleted file mode 100644
index 4d317af59..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json
+++ /dev/null
@@ -1,188 +0,0 @@
-{
- "language": "en-US",
- "messages": [
- {
- "id": "Hello world!",
- "key": "Hello world!\n",
- "message": "Hello world!",
- "translation": "",
- "position": "testdata/test1/test1.go:19:10"
- },
- {
- "id": "Hello {City}!",
- "key": "Hello %s!\n",
- "message": "Hello {City}!",
- "translation": "",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "city"
- }
- ],
- "position": "testdata/test1/test1.go:24:10"
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%s is visiting %s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "person",
- "comment": "The person of matter."
- },
- {
- "id": "Place",
- "string": "%[2]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 2,
- "expr": "place",
- "comment": "Place the person is visiting."
- }
- ],
- "position": "testdata/test1/test1.go:30:10"
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%[1]s is visiting %[3]s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "",
- "comment": "Field names are placeholders.",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "pp.Person"
- },
- {
- "id": "Place",
- "string": "%[3]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 3,
- "expr": "pp.Place",
- "comment": "Place the person is visiting."
- },
- {
- "id": "Extra",
- "string": "%[2]v",
- "type": "int",
- "underlyingType": "int",
- "argNum": 2,
- "expr": "pp.extra"
- }
- ],
- "position": "testdata/test1/test1.go:44:10"
- },
- {
- "id": "{2} files remaining!",
- "key": "%d files remaining!",
- "message": "{2} files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "2"
- }
- ],
- "position": "testdata/test1/test1.go:51:10"
- },
- {
- "id": "{N} more files remaining!",
- "key": "%d more files remaining!",
- "message": "{N} more files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "n"
- }
- ],
- "position": "testdata/test1/test1.go:56:10"
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "key": "Use the following code for your discount: %d\n",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d",
- "type": "./testdata/test1.referralCode",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "c"
- }
- ],
- "position": "testdata/test1/test1.go:64:10"
- },
- {
- "id": [
- "msgOutOfOrder",
- "{Device} is out of order!"
- ],
- "key": "%s is out of order!",
- "message": "{Device} is out of order!",
- "translation": "",
- "comment": "This comment wins.\n",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "device"
- }
- ],
- "position": "testdata/test1/test1.go:70:10"
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "key": "%.2[1]f miles traveled (%[1]f)",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- }
- ],
- "position": "testdata/test1/test1.go:74:10"
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json.want b/vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json.want
deleted file mode 100644
index 4d317af59..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json.want
+++ /dev/null
@@ -1,188 +0,0 @@
-{
- "language": "en-US",
- "messages": [
- {
- "id": "Hello world!",
- "key": "Hello world!\n",
- "message": "Hello world!",
- "translation": "",
- "position": "testdata/test1/test1.go:19:10"
- },
- {
- "id": "Hello {City}!",
- "key": "Hello %s!\n",
- "message": "Hello {City}!",
- "translation": "",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "city"
- }
- ],
- "position": "testdata/test1/test1.go:24:10"
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%s is visiting %s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "person",
- "comment": "The person of matter."
- },
- {
- "id": "Place",
- "string": "%[2]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 2,
- "expr": "place",
- "comment": "Place the person is visiting."
- }
- ],
- "position": "testdata/test1/test1.go:30:10"
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%[1]s is visiting %[3]s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "",
- "comment": "Field names are placeholders.",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "pp.Person"
- },
- {
- "id": "Place",
- "string": "%[3]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 3,
- "expr": "pp.Place",
- "comment": "Place the person is visiting."
- },
- {
- "id": "Extra",
- "string": "%[2]v",
- "type": "int",
- "underlyingType": "int",
- "argNum": 2,
- "expr": "pp.extra"
- }
- ],
- "position": "testdata/test1/test1.go:44:10"
- },
- {
- "id": "{2} files remaining!",
- "key": "%d files remaining!",
- "message": "{2} files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "2"
- }
- ],
- "position": "testdata/test1/test1.go:51:10"
- },
- {
- "id": "{N} more files remaining!",
- "key": "%d more files remaining!",
- "message": "{N} more files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "n"
- }
- ],
- "position": "testdata/test1/test1.go:56:10"
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "key": "Use the following code for your discount: %d\n",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d",
- "type": "./testdata/test1.referralCode",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "c"
- }
- ],
- "position": "testdata/test1/test1.go:64:10"
- },
- {
- "id": [
- "msgOutOfOrder",
- "{Device} is out of order!"
- ],
- "key": "%s is out of order!",
- "message": "{Device} is out of order!",
- "translation": "",
- "comment": "This comment wins.\n",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "device"
- }
- ],
- "position": "testdata/test1/test1.go:70:10"
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "key": "%.2[1]f miles traveled (%[1]f)",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- }
- ],
- "position": "testdata/test1/test1.go:74:10"
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/messages.gotext.json b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/messages.gotext.json
deleted file mode 100755
index f92e4a1f5..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/messages.gotext.json
+++ /dev/null
@@ -1,123 +0,0 @@
-{
- "language": "de",
- "messages": [
- {
- "id": "Hello world!",
- "key": "Hello world!\n",
- "message": "Hello world!",
- "translation": "Hallo Welt!"
- },
- {
- "id": "Hello {City}!",
- "key": "Hello %s!\n",
- "message": "Hello {City}!",
- "translation": "Hallo {City}!",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%s is visiting %s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "{Person} besucht {Place}!",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s"
- },
- {
- "id": "Place",
- "string": "%[2]s"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%[1]s is visiting %[3]s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "{Person} besucht {Place}!",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s"
- },
- {
- "id": "Place",
- "string": "%[3]s"
- },
- {
- "id": "Extra",
- "string": "%[2]v"
- }
- ]
- },
- {
- "id": "{2} files remaining!",
- "key": "%d files remaining!",
- "message": "{N} files remaining!",
- "translation": "Noch zwei Bestände zu gehen!",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d"
- }
- ]
- },
- {
- "id": "{N} more files remaining!",
- "key": "%d more files remaining!",
- "message": "{N} more files remaining!",
- "translation": "Noch {N} Bestände zu gehen!",
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d"
- }
- ]
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "key": "Use the following code for your discount: %d\n",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d"
- }
- ]
- },
- {
- "id": [ "msgOutOfOrder", "{Device} is out of order!" ],
- "key": "%s is out of order!",
- "message": "{Device} is out of order!",
- "translation": "",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s"
- }
- ]
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "key": "%.2[1]f miles traveled (%[1]f)",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f"
- }
- ]
- }
- ]
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/out.gotext.json b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/out.gotext.json
deleted file mode 100755
index f19e21d72..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/out.gotext.json
+++ /dev/null
@@ -1,137 +0,0 @@
-{
- "language": "de",
- "messages": [
- {
- "id": "Hello world!",
- "message": "Hello world!",
- "translation": "Hallo Welt!"
- },
- {
- "id": "Hello {City}!",
- "message": "Hello {City}!",
- "translation": "Hallo {City}!",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "city"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "message": "{Person} is visiting {Place}!",
- "translation": "{Person} besucht {Place}!",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "person",
- "comment": "The person of matter."
- },
- {
- "id": "Place",
- "string": "%[2]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 2,
- "expr": "place",
- "comment": "Place the person is visiting."
- }
- ]
- },
- {
- "id": "{2} files remaining!",
- "message": "{2} files remaining!",
- "translation": "Noch zwei Bestände zu gehen!",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "2"
- }
- ]
- },
- {
- "id": "{N} more files remaining!",
- "message": "{N} more files remaining!",
- "translation": "Noch {N} Bestände zu gehen!",
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "n"
- }
- ]
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d",
- "type": "./testdata/test1.referralCode",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "c"
- }
- ]
- },
- {
- "id": [
- "msgOutOfOrder",
- "{Device} is out of order!"
- ],
- "message": "{Device} is out of order!",
- "translation": "",
- "comment": "This comment wins.\n",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "device"
- }
- ]
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/out.gotext.json.want b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/out.gotext.json.want
deleted file mode 100755
index f19e21d72..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/out.gotext.json.want
+++ /dev/null
@@ -1,137 +0,0 @@
-{
- "language": "de",
- "messages": [
- {
- "id": "Hello world!",
- "message": "Hello world!",
- "translation": "Hallo Welt!"
- },
- {
- "id": "Hello {City}!",
- "message": "Hello {City}!",
- "translation": "Hallo {City}!",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "city"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "message": "{Person} is visiting {Place}!",
- "translation": "{Person} besucht {Place}!",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "person",
- "comment": "The person of matter."
- },
- {
- "id": "Place",
- "string": "%[2]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 2,
- "expr": "place",
- "comment": "Place the person is visiting."
- }
- ]
- },
- {
- "id": "{2} files remaining!",
- "message": "{2} files remaining!",
- "translation": "Noch zwei Bestände zu gehen!",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "2"
- }
- ]
- },
- {
- "id": "{N} more files remaining!",
- "message": "{N} more files remaining!",
- "translation": "Noch {N} Bestände zu gehen!",
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "n"
- }
- ]
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d",
- "type": "./testdata/test1.referralCode",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "c"
- }
- ]
- },
- {
- "id": [
- "msgOutOfOrder",
- "{Device} is out of order!"
- ],
- "message": "{Device} is out of order!",
- "translation": "",
- "comment": "This comment wins.\n",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "device"
- }
- ]
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/messages.gotext.json b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/messages.gotext.json
deleted file mode 100755
index b984242f6..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/messages.gotext.json
+++ /dev/null
@@ -1,91 +0,0 @@
-{
- "language": "en-US",
- "messages": [
- {
- "id": "Hello world!",
- "key": "Hello world!\n",
- "message": "Hello world!",
- "translation": "Hello world!"
- },
- {
- "id": "Hello {City}!",
- "key": "Hello %s!\n",
- "message": "Hello {City}!",
- "translation": "Hello {City}!"
- },
- {
- "id": "Hello {Town}!",
- "key": "Hello %s!\n",
- "message": "Hello {Town}!",
- "translation": "Hello {Town}!",
- "placeholders": [
- {
- "id": "Town",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "town",
- "comment": "Town"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%s is visiting %s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "{Person} is visiting {Place}!"
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%[1]s is visiting %[3]s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "{Person} is visiting {Place}!"
- },
- {
- "id": "{2} files remaining!",
- "key": "%d files remaining!",
- "message": "{N} files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d"
- }
- ]
- },
- {
- "id": "{N} more files remaining!",
- "key": "%d more files remaining!",
- "message": "{N} more files remaining!",
- "translation": {
- "select": {
- "feature": "plural",
- "arg": "N",
- "cases": {
- "one": "One file remaining!",
- "other": "There are {N} more files remaining!"
- }
- }
- }
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "key": "Use the following code for your discount: %d\n",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": ""
- },
- {
- "id": [ "msgOutOfOrder", "{Device} is out of order!" ],
- "key": "%s is out of order!",
- "message": "{Device} is out of order!",
- "translation": "{Device} is out of order!"
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "key": "%.2[1]f miles traveled (%[1]f)",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "{Miles} miles traveled ({Miles_1})"
- }
- ]
-}
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/out.gotext.json b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/out.gotext.json
deleted file mode 100755
index 59f92a5a6..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/out.gotext.json
+++ /dev/null
@@ -1,154 +0,0 @@
-{
- "language": "en-US",
- "messages": [
- {
- "id": "Hello world!",
- "message": "Hello world!",
- "translation": "Hello world!"
- },
- {
- "id": "Hello {City}!",
- "message": "Hello {City}!",
- "translation": "Hello {City}!",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "city"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "message": "{Person} is visiting {Place}!",
- "translation": "{Person} is visiting {Place}!",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "person",
- "comment": "The person of matter."
- },
- {
- "id": "Place",
- "string": "%[2]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 2,
- "expr": "place",
- "comment": "Place the person is visiting."
- }
- ]
- },
- {
- "id": "{2} files remaining!",
- "message": "{2} files remaining!",
- "translation": "{2} files remaining!",
- "translatorComment": "Copied from source.",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "2"
- }
- ],
- "fuzzy": true
- },
- {
- "id": "{N} more files remaining!",
- "message": "{N} more files remaining!",
- "translation": {
- "select": {
- "feature": "plural",
- "arg": "N",
- "cases": {
- "one": {
- "msg": "One file remaining!"
- },
- "other": {
- "msg": "There are {N} more files remaining!"
- }
- }
- }
- },
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "n"
- }
- ]
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "Use the following code for your discount: {ReferralCode}",
- "translatorComment": "Copied from source.",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d",
- "type": "./testdata/test1.referralCode",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "c"
- }
- ],
- "fuzzy": true
- },
- {
- "id": [
- "msgOutOfOrder",
- "{Device} is out of order!"
- ],
- "message": "{Device} is out of order!",
- "translation": "{Device} is out of order!",
- "comment": "This comment wins.\n",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "device"
- }
- ]
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "{Miles} miles traveled ({Miles_1})",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/out.gotext.json.want b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/out.gotext.json.want
deleted file mode 100755
index 59f92a5a6..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/out.gotext.json.want
+++ /dev/null
@@ -1,154 +0,0 @@
-{
- "language": "en-US",
- "messages": [
- {
- "id": "Hello world!",
- "message": "Hello world!",
- "translation": "Hello world!"
- },
- {
- "id": "Hello {City}!",
- "message": "Hello {City}!",
- "translation": "Hello {City}!",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "city"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "message": "{Person} is visiting {Place}!",
- "translation": "{Person} is visiting {Place}!",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "person",
- "comment": "The person of matter."
- },
- {
- "id": "Place",
- "string": "%[2]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 2,
- "expr": "place",
- "comment": "Place the person is visiting."
- }
- ]
- },
- {
- "id": "{2} files remaining!",
- "message": "{2} files remaining!",
- "translation": "{2} files remaining!",
- "translatorComment": "Copied from source.",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "2"
- }
- ],
- "fuzzy": true
- },
- {
- "id": "{N} more files remaining!",
- "message": "{N} more files remaining!",
- "translation": {
- "select": {
- "feature": "plural",
- "arg": "N",
- "cases": {
- "one": {
- "msg": "One file remaining!"
- },
- "other": {
- "msg": "There are {N} more files remaining!"
- }
- }
- }
- },
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "n"
- }
- ]
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "Use the following code for your discount: {ReferralCode}",
- "translatorComment": "Copied from source.",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d",
- "type": "./testdata/test1.referralCode",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "c"
- }
- ],
- "fuzzy": true
- },
- {
- "id": [
- "msgOutOfOrder",
- "{Device} is out of order!"
- ],
- "message": "{Device} is out of order!",
- "translation": "{Device} is out of order!",
- "comment": "This comment wins.\n",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "device"
- }
- ]
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "{Miles} miles traveled ({Miles_1})",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/messages.gotext.json b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/messages.gotext.json
deleted file mode 100755
index c80d1d2a7..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/messages.gotext.json
+++ /dev/null
@@ -1,135 +0,0 @@
-{
- "language": "zh",
- "messages": [
- {
- "id": "Hello world!",
- "key": "Hello world!\n",
- "message": "Hello world!",
- "translation": ""
- },
- {
- "id": "Hello {City}!",
- "key": "Hello %s!\n",
- "message": "Hello {City}!",
- "translation": "",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s"
- }
- ]
- },
- {
- "id": "Hello {Town}!",
- "key": "Hello %s!\n",
- "message": "Hello {Town}!",
- "translation": "",
- "placeholders": [
- {
- "id": "Town",
- "string": "%[1]s"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%s is visiting %s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s"
- },
- {
- "id": "Place",
- "string": "%[2]s"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "key": "%[1]s is visiting %[3]s!\n",
- "message": "{Person} is visiting {Place}!",
- "translation": "",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s"
- },
- {
- "id": "Place",
- "string": "%[3]s"
- },
- {
- "id": "Extra",
- "string": "%[2]v"
- }
- ]
- },
- {
- "id": "{2} files remaining!",
- "key": "%d files remaining!",
- "message": "{2} files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "",
- "string": "%[1]d"
- }
- ]
- },
- {
- "id": "{N} more files remaining!",
- "key": "%d more files remaining!",
- "message": "{N} more files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d"
- }
- ]
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "key": "Use the following code for your discount: %d\n",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d"
- }
- ]
- },
- {
- "id": [ "{Device} is out of order!", "msgOutOfOrder" ],
- "key": "%s is out of order!",
- "message": "{Device} is out of order!",
- "translation": "",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s"
- }
- ]
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "key": "%.2[1]f miles traveled (%[1]f)",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/out.gotext.json b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/out.gotext.json
deleted file mode 100755
index 9bede65ee..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/out.gotext.json
+++ /dev/null
@@ -1,137 +0,0 @@
-{
- "language": "zh",
- "messages": [
- {
- "id": "Hello world!",
- "message": "Hello world!",
- "translation": ""
- },
- {
- "id": "Hello {City}!",
- "message": "Hello {City}!",
- "translation": "",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "city"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "message": "{Person} is visiting {Place}!",
- "translation": "",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "person",
- "comment": "The person of matter."
- },
- {
- "id": "Place",
- "string": "%[2]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 2,
- "expr": "place",
- "comment": "Place the person is visiting."
- }
- ]
- },
- {
- "id": "{2} files remaining!",
- "message": "{2} files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "2"
- }
- ]
- },
- {
- "id": "{N} more files remaining!",
- "message": "{N} more files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "n"
- }
- ]
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d",
- "type": "./testdata/test1.referralCode",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "c"
- }
- ]
- },
- {
- "id": [
- "msgOutOfOrder",
- "{Device} is out of order!"
- ],
- "message": "{Device} is out of order!",
- "translation": "",
- "comment": "This comment wins.\n",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "device"
- }
- ]
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/out.gotext.json.want b/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/out.gotext.json.want
deleted file mode 100755
index 9bede65ee..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/zh/out.gotext.json.want
+++ /dev/null
@@ -1,137 +0,0 @@
-{
- "language": "zh",
- "messages": [
- {
- "id": "Hello world!",
- "message": "Hello world!",
- "translation": ""
- },
- {
- "id": "Hello {City}!",
- "message": "Hello {City}!",
- "translation": "",
- "placeholders": [
- {
- "id": "City",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "city"
- }
- ]
- },
- {
- "id": "{Person} is visiting {Place}!",
- "message": "{Person} is visiting {Place}!",
- "translation": "",
- "placeholders": [
- {
- "id": "Person",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "person",
- "comment": "The person of matter."
- },
- {
- "id": "Place",
- "string": "%[2]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 2,
- "expr": "place",
- "comment": "Place the person is visiting."
- }
- ]
- },
- {
- "id": "{2} files remaining!",
- "message": "{2} files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "2",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "2"
- }
- ]
- },
- {
- "id": "{N} more files remaining!",
- "message": "{N} more files remaining!",
- "translation": "",
- "placeholders": [
- {
- "id": "N",
- "string": "%[1]d",
- "type": "int",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "n"
- }
- ]
- },
- {
- "id": "Use the following code for your discount: {ReferralCode}",
- "message": "Use the following code for your discount: {ReferralCode}",
- "translation": "",
- "placeholders": [
- {
- "id": "ReferralCode",
- "string": "%[1]d",
- "type": "./testdata/test1.referralCode",
- "underlyingType": "int",
- "argNum": 1,
- "expr": "c"
- }
- ]
- },
- {
- "id": [
- "msgOutOfOrder",
- "{Device} is out of order!"
- ],
- "message": "{Device} is out of order!",
- "translation": "",
- "comment": "This comment wins.\n",
- "placeholders": [
- {
- "id": "Device",
- "string": "%[1]s",
- "type": "string",
- "underlyingType": "string",
- "argNum": 1,
- "expr": "device"
- }
- ]
- },
- {
- "id": "{Miles} miles traveled ({Miles_1})",
- "message": "{Miles} miles traveled ({Miles_1})",
- "translation": "",
- "placeholders": [
- {
- "id": "Miles",
- "string": "%.2[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- },
- {
- "id": "Miles_1",
- "string": "%[1]f",
- "type": "float64",
- "underlyingType": "float64",
- "argNum": 1,
- "expr": "miles"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/vendor/golang.org/x/text/message/pipeline/testdata/test1/test1.go b/vendor/golang.org/x/text/message/pipeline/testdata/test1/test1.go
deleted file mode 100644
index 88051f932..000000000
--- a/vendor/golang.org/x/text/message/pipeline/testdata/test1/test1.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import "golang.org/x/text/message"
-
-func main() {
- p := message.NewPrinter(message.MatchLanguage("en"))
-
- // NOT EXTRACTED: strings passed to Println are not extracted.
- p.Println("Hello world!")
-
- // NOT EXTRACTED: strings passed to Print are not extracted.
- p.Print("Hello world!\n")
-
- // Extract and trim whitespace (TODO).
- p.Printf("Hello world!\n")
-
- // NOT EXTRACTED: city is not used as a pattern or passed to %m.
- city := "Amsterdam"
- // This comment is extracted.
- p.Printf("Hello %s!\n", city)
-
- person := "Sheila"
- place := "Zürich"
-
- // Substitutions replaced by variable names.
- p.Printf("%s is visiting %s!\n",
- person, // The person of matter.
- place, // Place the person is visiting.
- )
-
- pp := struct {
- Person string // The person of matter. // TODO: get this comment.
- Place string
- extra int
- }{
- person, place, 4,
- }
-
- // extract will drop this comment in favor of the one below.
- p.Printf("%[1]s is visiting %[3]s!\n", // Field names are placeholders.
- pp.Person,
- pp.extra,
- pp.Place, // Place the person is visiting.
- )
-
- // Numeric literal becomes placeholder.
- p.Printf("%d files remaining!", 2)
-
- const n = 2
-
- // Constant identifier becomes placeholder.
- p.Printf("%d more files remaining!", n)
-
- // Infer better names from type names.
- type referralCode int
-
- const c = referralCode(5)
-
- // Use type name as placeholder.
- p.Printf("Use the following code for your discount: %d\n", c)
-
- // Use constant name as message ID.
- const msgOutOfOrder = "%s is out of order!" // This comment wins.
- const device = "Soda machine"
- // This message has two IDs.
- p.Printf(msgOutOfOrder, device)
-
- // Multiple substitutions for same argument.
- miles := 1.2345
- p.Printf("%.2[1]f miles traveled (%[1]f)", miles)
-}
diff --git a/vendor/golang.org/x/text/message/print.go b/vendor/golang.org/x/text/message/print.go
deleted file mode 100644
index 777e1724a..000000000
--- a/vendor/golang.org/x/text/message/print.go
+++ /dev/null
@@ -1,979 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package message
-
-import (
- "bytes"
- "fmt" // TODO: consider copying interfaces from package fmt to avoid dependency.
- "math"
- "reflect"
- "sync"
- "unicode/utf8"
-
- "golang.org/x/text/internal/format"
- "golang.org/x/text/internal/number"
- "golang.org/x/text/language"
- "golang.org/x/text/message/catalog"
-)
-
-// Strings for use with buffer.WriteString.
-// This is less overhead than using buffer.Write with byte arrays.
-const (
- commaSpaceString = ", "
- nilAngleString = "<nil>"
- nilParenString = "(nil)"
- nilString = "nil"
- mapString = "map["
- percentBangString = "%!"
- missingString = "(MISSING)"
- badIndexString = "(BADINDEX)"
- panicString = "(PANIC="
- extraString = "%!(EXTRA "
- badWidthString = "%!(BADWIDTH)"
- badPrecString = "%!(BADPREC)"
- noVerbString = "%!(NOVERB)"
-
- invReflectString = "<invalid reflect.Value>"
-)
-
-var printerPool = sync.Pool{
- New: func() interface{} { return new(printer) },
-}
-
-// newPrinter allocates a new printer struct or grabs a cached one.
-func newPrinter(pp *Printer) *printer {
- p := printerPool.Get().(*printer)
- p.Printer = *pp
- // TODO: cache most of the following call.
- p.catContext = pp.cat.Context(pp.tag, p)
-
- p.panicking = false
- p.erroring = false
- p.fmt.init(&p.Buffer)
- return p
-}
-
-// free saves used printer structs in printerFree; avoids an allocation per invocation.
-func (p *printer) free() {
- p.Buffer.Reset()
- p.arg = nil
- p.value = reflect.Value{}
- printerPool.Put(p)
-}
-
-// printer is used to store a printer's state.
-// It implements "golang.org/x/text/internal/format".State.
-type printer struct {
- Printer
-
- // the context for looking up message translations
- catContext *catalog.Context
-
- // buffer for accumulating output.
- bytes.Buffer
-
- // arg holds the current item, as an interface{}.
- arg interface{}
- // value is used instead of arg for reflect values.
- value reflect.Value
-
- // fmt is used to format basic items such as integers or strings.
- fmt formatInfo
-
- // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
- panicking bool
- // erroring is set when printing an error string to guard against calling handleMethods.
- erroring bool
-}
-
-// Language implements "golang.org/x/text/internal/format".State.
-func (p *printer) Language() language.Tag { return p.tag }
-
-func (p *printer) Width() (wid int, ok bool) { return p.fmt.Width, p.fmt.WidthPresent }
-
-func (p *printer) Precision() (prec int, ok bool) { return p.fmt.Prec, p.fmt.PrecPresent }
-
-func (p *printer) Flag(b int) bool {
- switch b {
- case '-':
- return p.fmt.Minus
- case '+':
- return p.fmt.Plus || p.fmt.PlusV
- case '#':
- return p.fmt.Sharp || p.fmt.SharpV
- case ' ':
- return p.fmt.Space
- case '0':
- return p.fmt.Zero
- }
- return false
-}
-
-// getField gets the i'th field of the struct value.
-// If the field is itself is an interface, return a value for
-// the thing inside the interface, not the interface itself.
-func getField(v reflect.Value, i int) reflect.Value {
- val := v.Field(i)
- if val.Kind() == reflect.Interface && !val.IsNil() {
- val = val.Elem()
- }
- return val
-}
-
-func (p *printer) unknownType(v reflect.Value) {
- if !v.IsValid() {
- p.WriteString(nilAngleString)
- return
- }
- p.WriteByte('?')
- p.WriteString(v.Type().String())
- p.WriteByte('?')
-}
-
-func (p *printer) badVerb(verb rune) {
- p.erroring = true
- p.WriteString(percentBangString)
- p.WriteRune(verb)
- p.WriteByte('(')
- switch {
- case p.arg != nil:
- p.WriteString(reflect.TypeOf(p.arg).String())
- p.WriteByte('=')
- p.printArg(p.arg, 'v')
- case p.value.IsValid():
- p.WriteString(p.value.Type().String())
- p.WriteByte('=')
- p.printValue(p.value, 'v', 0)
- default:
- p.WriteString(nilAngleString)
- }
- p.WriteByte(')')
- p.erroring = false
-}
-
-func (p *printer) fmtBool(v bool, verb rune) {
- switch verb {
- case 't', 'v':
- p.fmt.fmt_boolean(v)
- default:
- p.badVerb(verb)
- }
-}
-
-// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
-// not, as requested, by temporarily setting the sharp flag.
-func (p *printer) fmt0x64(v uint64, leading0x bool) {
- sharp := p.fmt.Sharp
- p.fmt.Sharp = leading0x
- p.fmt.fmt_integer(v, 16, unsigned, ldigits)
- p.fmt.Sharp = sharp
-}
-
-// fmtInteger formats a signed or unsigned integer.
-func (p *printer) fmtInteger(v uint64, isSigned bool, verb rune) {
- switch verb {
- case 'v':
- if p.fmt.SharpV && !isSigned {
- p.fmt0x64(v, true)
- return
- }
- fallthrough
- case 'd':
- if p.fmt.Sharp || p.fmt.SharpV {
- p.fmt.fmt_integer(v, 10, isSigned, ldigits)
- } else {
- p.fmtDecimalInt(v, isSigned)
- }
- case 'b':
- p.fmt.fmt_integer(v, 2, isSigned, ldigits)
- case 'o':
- p.fmt.fmt_integer(v, 8, isSigned, ldigits)
- case 'x':
- p.fmt.fmt_integer(v, 16, isSigned, ldigits)
- case 'X':
- p.fmt.fmt_integer(v, 16, isSigned, udigits)
- case 'c':
- p.fmt.fmt_c(v)
- case 'q':
- if v <= utf8.MaxRune {
- p.fmt.fmt_qc(v)
- } else {
- p.badVerb(verb)
- }
- case 'U':
- p.fmt.fmt_unicode(v)
- default:
- p.badVerb(verb)
- }
-}
-
-// fmtFloat formats a float. The default precision for each verb
-// is specified as last argument in the call to fmt_float.
-func (p *printer) fmtFloat(v float64, size int, verb rune) {
- switch verb {
- case 'b':
- p.fmt.fmt_float(v, size, verb, -1)
- case 'v':
- verb = 'g'
- fallthrough
- case 'g', 'G':
- if p.fmt.Sharp || p.fmt.SharpV {
- p.fmt.fmt_float(v, size, verb, -1)
- } else {
- p.fmtVariableFloat(v, size)
- }
- case 'e', 'E':
- if p.fmt.Sharp || p.fmt.SharpV {
- p.fmt.fmt_float(v, size, verb, 6)
- } else {
- p.fmtScientific(v, size, 6)
- }
- case 'f', 'F':
- if p.fmt.Sharp || p.fmt.SharpV {
- p.fmt.fmt_float(v, size, verb, 6)
- } else {
- p.fmtDecimalFloat(v, size, 6)
- }
- default:
- p.badVerb(verb)
- }
-}
-
-func (p *printer) setFlags(f *number.Formatter) {
- f.Flags &^= number.ElideSign
- if p.fmt.Plus || p.fmt.Space {
- f.Flags |= number.AlwaysSign
- if !p.fmt.Plus {
- f.Flags |= number.ElideSign
- }
- } else {
- f.Flags &^= number.AlwaysSign
- }
-}
-
-func (p *printer) updatePadding(f *number.Formatter) {
- f.Flags &^= number.PadMask
- if p.fmt.Minus {
- f.Flags |= number.PadAfterSuffix
- } else {
- f.Flags |= number.PadBeforePrefix
- }
- f.PadRune = ' '
- f.FormatWidth = uint16(p.fmt.Width)
-}
-
-func (p *printer) initDecimal(minFrac, maxFrac int) {
- f := &p.toDecimal
- f.MinIntegerDigits = 1
- f.MaxIntegerDigits = 0
- f.MinFractionDigits = uint8(minFrac)
- f.MaxFractionDigits = int16(maxFrac)
- p.setFlags(f)
- f.PadRune = 0
- if p.fmt.WidthPresent {
- if p.fmt.Zero {
- wid := p.fmt.Width
- // Use significant integers for this.
- // TODO: this is not the same as width, but so be it.
- if f.MinFractionDigits > 0 {
- wid -= 1 + int(f.MinFractionDigits)
- }
- if p.fmt.Plus || p.fmt.Space {
- wid--
- }
- if wid > 0 && wid > int(f.MinIntegerDigits) {
- f.MinIntegerDigits = uint8(wid)
- }
- }
- p.updatePadding(f)
- }
-}
-
-func (p *printer) initScientific(minFrac, maxFrac int) {
- f := &p.toScientific
- if maxFrac < 0 {
- f.SetPrecision(maxFrac)
- } else {
- f.SetPrecision(maxFrac + 1)
- f.MinFractionDigits = uint8(minFrac)
- f.MaxFractionDigits = int16(maxFrac)
- }
- f.MinExponentDigits = 2
- p.setFlags(f)
- f.PadRune = 0
- if p.fmt.WidthPresent {
- f.Flags &^= number.PadMask
- if p.fmt.Zero {
- f.PadRune = f.Digit(0)
- f.Flags |= number.PadAfterPrefix
- } else {
- f.PadRune = ' '
- f.Flags |= number.PadBeforePrefix
- }
- p.updatePadding(f)
- }
-}
-
-func (p *printer) fmtDecimalInt(v uint64, isSigned bool) {
- var d number.Decimal
-
- f := &p.toDecimal
- if p.fmt.PrecPresent {
- p.setFlags(f)
- f.MinIntegerDigits = uint8(p.fmt.Prec)
- f.MaxIntegerDigits = 0
- f.MinFractionDigits = 0
- f.MaxFractionDigits = 0
- if p.fmt.WidthPresent {
- p.updatePadding(f)
- }
- } else {
- p.initDecimal(0, 0)
- }
- d.ConvertInt(p.toDecimal.RoundingContext, isSigned, v)
-
- out := p.toDecimal.Format([]byte(nil), &d)
- p.Buffer.Write(out)
-}
-
-func (p *printer) fmtDecimalFloat(v float64, size, prec int) {
- var d number.Decimal
- if p.fmt.PrecPresent {
- prec = p.fmt.Prec
- }
- p.initDecimal(prec, prec)
- d.ConvertFloat(p.toDecimal.RoundingContext, v, size)
-
- out := p.toDecimal.Format([]byte(nil), &d)
- p.Buffer.Write(out)
-}
-
-func (p *printer) fmtVariableFloat(v float64, size int) {
- prec := -1
- if p.fmt.PrecPresent {
- prec = p.fmt.Prec
- }
- var d number.Decimal
- p.initScientific(0, prec)
- d.ConvertFloat(p.toScientific.RoundingContext, v, size)
-
- // Copy logic of 'g' formatting from strconv. It is simplified a bit as
- // we don't have to mind having prec > len(d.Digits).
- shortest := prec < 0
- ePrec := prec
- if shortest {
- prec = len(d.Digits)
- ePrec = 6
- } else if prec == 0 {
- prec = 1
- ePrec = 1
- }
- exp := int(d.Exp) - 1
- if exp < -4 || exp >= ePrec {
- p.initScientific(0, prec)
-
- out := p.toScientific.Format([]byte(nil), &d)
- p.Buffer.Write(out)
- } else {
- if prec > int(d.Exp) {
- prec = len(d.Digits)
- }
- if prec -= int(d.Exp); prec < 0 {
- prec = 0
- }
- p.initDecimal(0, prec)
-
- out := p.toDecimal.Format([]byte(nil), &d)
- p.Buffer.Write(out)
- }
-}
-
-func (p *printer) fmtScientific(v float64, size, prec int) {
- var d number.Decimal
- if p.fmt.PrecPresent {
- prec = p.fmt.Prec
- }
- p.initScientific(prec, prec)
- rc := p.toScientific.RoundingContext
- d.ConvertFloat(rc, v, size)
-
- out := p.toScientific.Format([]byte(nil), &d)
- p.Buffer.Write(out)
-
-}
-
-// fmtComplex formats a complex number v with
-// r = real(v) and j = imag(v) as (r+ji) using
-// fmtFloat for r and j formatting.
-func (p *printer) fmtComplex(v complex128, size int, verb rune) {
- // Make sure any unsupported verbs are found before the
- // calls to fmtFloat to not generate an incorrect error string.
- switch verb {
- case 'v', 'b', 'g', 'G', 'f', 'F', 'e', 'E':
- p.WriteByte('(')
- p.fmtFloat(real(v), size/2, verb)
- // Imaginary part always has a sign.
- if math.IsNaN(imag(v)) {
- // By CLDR's rules, NaNs do not use patterns or signs. As this code
- // relies on AlwaysSign working for imaginary parts, we need to
- // manually handle NaNs.
- f := &p.toScientific
- p.setFlags(f)
- p.updatePadding(f)
- p.setFlags(f)
- nan := f.Symbol(number.SymNan)
- extra := 0
- if w, ok := p.Width(); ok {
- extra = w - utf8.RuneCountInString(nan) - 1
- }
- if f.Flags&number.PadAfterNumber == 0 {
- for ; extra > 0; extra-- {
- p.WriteRune(f.PadRune)
- }
- }
- p.WriteString(f.Symbol(number.SymPlusSign))
- p.WriteString(nan)
- for ; extra > 0; extra-- {
- p.WriteRune(f.PadRune)
- }
- p.WriteString("i)")
- return
- }
- oldPlus := p.fmt.Plus
- p.fmt.Plus = true
- p.fmtFloat(imag(v), size/2, verb)
- p.WriteString("i)") // TODO: use symbol?
- p.fmt.Plus = oldPlus
- default:
- p.badVerb(verb)
- }
-}
-
-func (p *printer) fmtString(v string, verb rune) {
- switch verb {
- case 'v':
- if p.fmt.SharpV {
- p.fmt.fmt_q(v)
- } else {
- p.fmt.fmt_s(v)
- }
- case 's':
- p.fmt.fmt_s(v)
- case 'x':
- p.fmt.fmt_sx(v, ldigits)
- case 'X':
- p.fmt.fmt_sx(v, udigits)
- case 'q':
- p.fmt.fmt_q(v)
- default:
- p.badVerb(verb)
- }
-}
-
-func (p *printer) fmtBytes(v []byte, verb rune, typeString string) {
- switch verb {
- case 'v', 'd':
- if p.fmt.SharpV {
- p.WriteString(typeString)
- if v == nil {
- p.WriteString(nilParenString)
- return
- }
- p.WriteByte('{')
- for i, c := range v {
- if i > 0 {
- p.WriteString(commaSpaceString)
- }
- p.fmt0x64(uint64(c), true)
- }
- p.WriteByte('}')
- } else {
- p.WriteByte('[')
- for i, c := range v {
- if i > 0 {
- p.WriteByte(' ')
- }
- p.fmt.fmt_integer(uint64(c), 10, unsigned, ldigits)
- }
- p.WriteByte(']')
- }
- case 's':
- p.fmt.fmt_s(string(v))
- case 'x':
- p.fmt.fmt_bx(v, ldigits)
- case 'X':
- p.fmt.fmt_bx(v, udigits)
- case 'q':
- p.fmt.fmt_q(string(v))
- default:
- p.printValue(reflect.ValueOf(v), verb, 0)
- }
-}
-
-func (p *printer) fmtPointer(value reflect.Value, verb rune) {
- var u uintptr
- switch value.Kind() {
- case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
- u = value.Pointer()
- default:
- p.badVerb(verb)
- return
- }
-
- switch verb {
- case 'v':
- if p.fmt.SharpV {
- p.WriteByte('(')
- p.WriteString(value.Type().String())
- p.WriteString(")(")
- if u == 0 {
- p.WriteString(nilString)
- } else {
- p.fmt0x64(uint64(u), true)
- }
- p.WriteByte(')')
- } else {
- if u == 0 {
- p.fmt.padString(nilAngleString)
- } else {
- p.fmt0x64(uint64(u), !p.fmt.Sharp)
- }
- }
- case 'p':
- p.fmt0x64(uint64(u), !p.fmt.Sharp)
- case 'b', 'o', 'd', 'x', 'X':
- if verb == 'd' {
- p.fmt.Sharp = true // Print as standard go. TODO: does this make sense?
- }
- p.fmtInteger(uint64(u), unsigned, verb)
- default:
- p.badVerb(verb)
- }
-}
-
-func (p *printer) catchPanic(arg interface{}, verb rune) {
- if err := recover(); err != nil {
- // If it's a nil pointer, just say "<nil>". The likeliest causes are a
- // Stringer that fails to guard against nil or a nil pointer for a
- // value receiver, and in either case, "<nil>" is a nice result.
- if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() {
- p.WriteString(nilAngleString)
- return
- }
- // Otherwise print a concise panic message. Most of the time the panic
- // value will print itself nicely.
- if p.panicking {
- // Nested panics; the recursion in printArg cannot succeed.
- panic(err)
- }
-
- oldFlags := p.fmt.Parser
- // For this output we want default behavior.
- p.fmt.ClearFlags()
-
- p.WriteString(percentBangString)
- p.WriteRune(verb)
- p.WriteString(panicString)
- p.panicking = true
- p.printArg(err, 'v')
- p.panicking = false
- p.WriteByte(')')
-
- p.fmt.Parser = oldFlags
- }
-}
-
-func (p *printer) handleMethods(verb rune) (handled bool) {
- if p.erroring {
- return
- }
- // Is it a Formatter?
- if formatter, ok := p.arg.(format.Formatter); ok {
- handled = true
- defer p.catchPanic(p.arg, verb)
- formatter.Format(p, verb)
- return
- }
- if formatter, ok := p.arg.(fmt.Formatter); ok {
- handled = true
- defer p.catchPanic(p.arg, verb)
- formatter.Format(p, verb)
- return
- }
-
- // If we're doing Go syntax and the argument knows how to supply it, take care of it now.
- if p.fmt.SharpV {
- if stringer, ok := p.arg.(fmt.GoStringer); ok {
- handled = true
- defer p.catchPanic(p.arg, verb)
- // Print the result of GoString unadorned.
- p.fmt.fmt_s(stringer.GoString())
- return
- }
- } else {
- // If a string is acceptable according to the format, see if
- // the value satisfies one of the string-valued interfaces.
- // Println etc. set verb to %v, which is "stringable".
- switch verb {
- case 'v', 's', 'x', 'X', 'q':
- // Is it an error or Stringer?
- // The duplication in the bodies is necessary:
- // setting handled and deferring catchPanic
- // must happen before calling the method.
- switch v := p.arg.(type) {
- case error:
- handled = true
- defer p.catchPanic(p.arg, verb)
- p.fmtString(v.Error(), verb)
- return
-
- case fmt.Stringer:
- handled = true
- defer p.catchPanic(p.arg, verb)
- p.fmtString(v.String(), verb)
- return
- }
- }
- }
- return false
-}
-
-func (p *printer) printArg(arg interface{}, verb rune) {
- p.arg = arg
- p.value = reflect.Value{}
-
- if arg == nil {
- switch verb {
- case 'T', 'v':
- p.fmt.padString(nilAngleString)
- default:
- p.badVerb(verb)
- }
- return
- }
-
- // Special processing considerations.
- // %T (the value's type) and %p (its address) are special; we always do them first.
- switch verb {
- case 'T':
- p.fmt.fmt_s(reflect.TypeOf(arg).String())
- return
- case 'p':
- p.fmtPointer(reflect.ValueOf(arg), 'p')
- return
- }
-
- // Some types can be done without reflection.
- switch f := arg.(type) {
- case bool:
- p.fmtBool(f, verb)
- case float32:
- p.fmtFloat(float64(f), 32, verb)
- case float64:
- p.fmtFloat(f, 64, verb)
- case complex64:
- p.fmtComplex(complex128(f), 64, verb)
- case complex128:
- p.fmtComplex(f, 128, verb)
- case int:
- p.fmtInteger(uint64(f), signed, verb)
- case int8:
- p.fmtInteger(uint64(f), signed, verb)
- case int16:
- p.fmtInteger(uint64(f), signed, verb)
- case int32:
- p.fmtInteger(uint64(f), signed, verb)
- case int64:
- p.fmtInteger(uint64(f), signed, verb)
- case uint:
- p.fmtInteger(uint64(f), unsigned, verb)
- case uint8:
- p.fmtInteger(uint64(f), unsigned, verb)
- case uint16:
- p.fmtInteger(uint64(f), unsigned, verb)
- case uint32:
- p.fmtInteger(uint64(f), unsigned, verb)
- case uint64:
- p.fmtInteger(f, unsigned, verb)
- case uintptr:
- p.fmtInteger(uint64(f), unsigned, verb)
- case string:
- p.fmtString(f, verb)
- case []byte:
- p.fmtBytes(f, verb, "[]byte")
- case reflect.Value:
- // Handle extractable values with special methods
- // since printValue does not handle them at depth 0.
- if f.IsValid() && f.CanInterface() {
- p.arg = f.Interface()
- if p.handleMethods(verb) {
- return
- }
- }
- p.printValue(f, verb, 0)
- default:
- // If the type is not simple, it might have methods.
- if !p.handleMethods(verb) {
- // Need to use reflection, since the type had no
- // interface methods that could be used for formatting.
- p.printValue(reflect.ValueOf(f), verb, 0)
- }
- }
-}
-
-// printValue is similar to printArg but starts with a reflect value, not an interface{} value.
-// It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
-func (p *printer) printValue(value reflect.Value, verb rune, depth int) {
- // Handle values with special methods if not already handled by printArg (depth == 0).
- if depth > 0 && value.IsValid() && value.CanInterface() {
- p.arg = value.Interface()
- if p.handleMethods(verb) {
- return
- }
- }
- p.arg = nil
- p.value = value
-
- switch f := value; value.Kind() {
- case reflect.Invalid:
- if depth == 0 {
- p.WriteString(invReflectString)
- } else {
- switch verb {
- case 'v':
- p.WriteString(nilAngleString)
- default:
- p.badVerb(verb)
- }
- }
- case reflect.Bool:
- p.fmtBool(f.Bool(), verb)
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p.fmtInteger(uint64(f.Int()), signed, verb)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p.fmtInteger(f.Uint(), unsigned, verb)
- case reflect.Float32:
- p.fmtFloat(f.Float(), 32, verb)
- case reflect.Float64:
- p.fmtFloat(f.Float(), 64, verb)
- case reflect.Complex64:
- p.fmtComplex(f.Complex(), 64, verb)
- case reflect.Complex128:
- p.fmtComplex(f.Complex(), 128, verb)
- case reflect.String:
- p.fmtString(f.String(), verb)
- case reflect.Map:
- if p.fmt.SharpV {
- p.WriteString(f.Type().String())
- if f.IsNil() {
- p.WriteString(nilParenString)
- return
- }
- p.WriteByte('{')
- } else {
- p.WriteString(mapString)
- }
- keys := f.MapKeys()
- for i, key := range keys {
- if i > 0 {
- if p.fmt.SharpV {
- p.WriteString(commaSpaceString)
- } else {
- p.WriteByte(' ')
- }
- }
- p.printValue(key, verb, depth+1)
- p.WriteByte(':')
- p.printValue(f.MapIndex(key), verb, depth+1)
- }
- if p.fmt.SharpV {
- p.WriteByte('}')
- } else {
- p.WriteByte(']')
- }
- case reflect.Struct:
- if p.fmt.SharpV {
- p.WriteString(f.Type().String())
- }
- p.WriteByte('{')
- for i := 0; i < f.NumField(); i++ {
- if i > 0 {
- if p.fmt.SharpV {
- p.WriteString(commaSpaceString)
- } else {
- p.WriteByte(' ')
- }
- }
- if p.fmt.PlusV || p.fmt.SharpV {
- if name := f.Type().Field(i).Name; name != "" {
- p.WriteString(name)
- p.WriteByte(':')
- }
- }
- p.printValue(getField(f, i), verb, depth+1)
- }
- p.WriteByte('}')
- case reflect.Interface:
- value := f.Elem()
- if !value.IsValid() {
- if p.fmt.SharpV {
- p.WriteString(f.Type().String())
- p.WriteString(nilParenString)
- } else {
- p.WriteString(nilAngleString)
- }
- } else {
- p.printValue(value, verb, depth+1)
- }
- case reflect.Array, reflect.Slice:
- switch verb {
- case 's', 'q', 'x', 'X':
- // Handle byte and uint8 slices and arrays special for the above verbs.
- t := f.Type()
- if t.Elem().Kind() == reflect.Uint8 {
- var bytes []byte
- if f.Kind() == reflect.Slice {
- bytes = f.Bytes()
- } else if f.CanAddr() {
- bytes = f.Slice(0, f.Len()).Bytes()
- } else {
- // We have an array, but we cannot Slice() a non-addressable array,
- // so we build a slice by hand. This is a rare case but it would be nice
- // if reflection could help a little more.
- bytes = make([]byte, f.Len())
- for i := range bytes {
- bytes[i] = byte(f.Index(i).Uint())
- }
- }
- p.fmtBytes(bytes, verb, t.String())
- return
- }
- }
- if p.fmt.SharpV {
- p.WriteString(f.Type().String())
- if f.Kind() == reflect.Slice && f.IsNil() {
- p.WriteString(nilParenString)
- return
- }
- p.WriteByte('{')
- for i := 0; i < f.Len(); i++ {
- if i > 0 {
- p.WriteString(commaSpaceString)
- }
- p.printValue(f.Index(i), verb, depth+1)
- }
- p.WriteByte('}')
- } else {
- p.WriteByte('[')
- for i := 0; i < f.Len(); i++ {
- if i > 0 {
- p.WriteByte(' ')
- }
- p.printValue(f.Index(i), verb, depth+1)
- }
- p.WriteByte(']')
- }
- case reflect.Ptr:
- // pointer to array or slice or struct? ok at top level
- // but not embedded (avoid loops)
- if depth == 0 && f.Pointer() != 0 {
- switch a := f.Elem(); a.Kind() {
- case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
- p.WriteByte('&')
- p.printValue(a, verb, depth+1)
- return
- }
- }
- fallthrough
- case reflect.Chan, reflect.Func, reflect.UnsafePointer:
- p.fmtPointer(f, verb)
- default:
- p.unknownType(f)
- }
-}
-
-func (p *printer) badArgNum(verb rune) {
- p.WriteString(percentBangString)
- p.WriteRune(verb)
- p.WriteString(badIndexString)
-}
-
-func (p *printer) missingArg(verb rune) {
- p.WriteString(percentBangString)
- p.WriteRune(verb)
- p.WriteString(missingString)
-}
-
-func (p *printer) doPrintf(fmt string) {
- for p.fmt.Parser.SetFormat(fmt); p.fmt.Scan(); {
- switch p.fmt.Status {
- case format.StatusText:
- p.WriteString(p.fmt.Text())
- case format.StatusSubstitution:
- p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb)
- case format.StatusBadWidthSubstitution:
- p.WriteString(badWidthString)
- p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb)
- case format.StatusBadPrecSubstitution:
- p.WriteString(badPrecString)
- p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb)
- case format.StatusNoVerb:
- p.WriteString(noVerbString)
- case format.StatusBadArgNum:
- p.badArgNum(p.fmt.Verb)
- case format.StatusMissingArg:
- p.missingArg(p.fmt.Verb)
- default:
- panic("unreachable")
- }
- }
-
- // Check for extra arguments, but only if there was at least one ordered
- // argument. Note that this behavior is necessarily different from fmt:
- // different variants of messages may opt to drop some or all of the
- // arguments.
- if !p.fmt.Reordered && p.fmt.ArgNum < len(p.fmt.Args) && p.fmt.ArgNum != 0 {
- p.fmt.ClearFlags()
- p.WriteString(extraString)
- for i, arg := range p.fmt.Args[p.fmt.ArgNum:] {
- if i > 0 {
- p.WriteString(commaSpaceString)
- }
- if arg == nil {
- p.WriteString(nilAngleString)
- } else {
- p.WriteString(reflect.TypeOf(arg).String())
- p.WriteString("=")
- p.printArg(arg, 'v')
- }
- }
- p.WriteByte(')')
- }
-}
-
-func (p *printer) doPrint(a []interface{}) {
- prevString := false
- for argNum, arg := range a {
- isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
- // Add a space between two non-string arguments.
- if argNum > 0 && !isString && !prevString {
- p.WriteByte(' ')
- }
- p.printArg(arg, 'v')
- prevString = isString
- }
-}
-
-// doPrintln is like doPrint but always adds a space between arguments
-// and a newline after the last argument.
-func (p *printer) doPrintln(a []interface{}) {
- for argNum, arg := range a {
- if argNum > 0 {
- p.WriteByte(' ')
- }
- p.printArg(arg, 'v')
- }
- p.WriteByte('\n')
-}