vendor files

This commit is contained in:
Serguei Bezverkhi
2018-01-09 13:57:14 -05:00
parent 558bc6c02a
commit 7b24313bd6
16547 changed files with 4527373 additions and 0 deletions

67
vendor/golang.org/x/text/currency/common.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
package currency
import (
"time"
"golang.org/x/text/language"
)
// This file contains code common to gen.go and the package code.
const (
cashShift = 3
roundMask = 0x7
nonTenderBit = 0x8000
)
// currencyInfo contains information about a currency.
// bits 0..2: index into roundings for standard rounding
// bits 3..5: index into roundings for cash rounding
type currencyInfo byte
// roundingType defines the scale (number of fractional decimals) and increments
// in terms of units of size 10^-scale. For example, for scale == 2 and
// increment == 1, the currency is rounded to units of 0.01.
type roundingType struct {
scale, increment uint8
}
// roundings contains rounding data for currencies. This struct is
// created by hand as it is very unlikely to change much.
var roundings = [...]roundingType{
{2, 1}, // default
{0, 1},
{1, 1},
{3, 1},
{4, 1},
{2, 5}, // cash rounding alternative
{2, 50},
}
// regionToCode returns a 16-bit region code. Only two-letter codes are
// supported. (Three-letter codes are not needed.)
func regionToCode(r language.Region) uint16 {
if s := r.String(); len(s) == 2 {
return uint16(s[0])<<8 | uint16(s[1])
}
return 0
}
func toDate(t time.Time) uint32 {
y := t.Year()
if y == 1 {
return 0
}
date := uint32(y) << 4
date |= uint32(t.Month())
date <<= 5
date |= uint32(t.Day())
return date
}
func fromDate(date uint32) time.Time {
return time.Date(int(date>>9), time.Month((date>>5)&0xf), int(date&0x1f), 0, 0, 0, 0, time.UTC)
}

185
vendor/golang.org/x/text/currency/currency.go generated vendored Normal file
View File

@ -0,0 +1,185 @@
// 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.
//go:generate go run gen.go gen_common.go -output tables.go
// Package currency contains currency-related functionality.
//
// NOTE: the formatting functionality is currently under development and may
// change without notice.
package currency // import "golang.org/x/text/currency"
import (
"errors"
"sort"
"golang.org/x/text/internal/tag"
"golang.org/x/text/language"
)
// TODO:
// - language-specific currency names.
// - currency formatting.
// - currency information per region
// - register currency code (there are no private use area)
// TODO: remove Currency type from package language.
// Kind determines the rounding and rendering properties of a currency value.
type Kind struct {
rounding rounding
// TODO: formatting type: standard, accounting. See CLDR.
}
type rounding byte
const (
standard rounding = iota
cash
)
var (
// Standard defines standard rounding and formatting for currencies.
Standard Kind = Kind{rounding: standard}
// Cash defines rounding and formatting standards for cash transactions.
Cash Kind = Kind{rounding: cash}
// Accounting defines rounding and formatting standards for accounting.
Accounting Kind = Kind{rounding: standard}
)
// Rounding reports the rounding characteristics for the given currency, where
// scale is the number of fractional decimals and increment is the number of
// units in terms of 10^(-scale) to which to round to.
func (k Kind) Rounding(cur Unit) (scale, increment int) {
info := currency.Elem(int(cur.index))[3]
switch k.rounding {
case standard:
info &= roundMask
case cash:
info >>= cashShift
}
return int(roundings[info].scale), int(roundings[info].increment)
}
// Unit is an ISO 4217 currency designator.
type Unit struct {
index uint16
}
// String returns the ISO code of u.
func (u Unit) String() string {
if u.index == 0 {
return "XXX"
}
return currency.Elem(int(u.index))[:3]
}
// Amount creates an Amount for the given currency unit and amount.
func (u Unit) Amount(amount interface{}) Amount {
// TODO: verify amount is a supported number type
return Amount{amount: amount, currency: u}
}
var (
errSyntax = errors.New("currency: tag is not well-formed")
errValue = errors.New("currency: tag is not a recognized currency")
)
// ParseISO parses a 3-letter ISO 4217 currency code. It returns an error if s
// is not well-formed or not a recognized currency code.
func ParseISO(s string) (Unit, error) {
var buf [4]byte // Take one byte more to detect oversize keys.
key := buf[:copy(buf[:], s)]
if !tag.FixCase("XXX", key) {
return Unit{}, errSyntax
}
if i := currency.Index(key); i >= 0 {
if i == xxx {
return Unit{}, nil
}
return Unit{uint16(i)}, nil
}
return Unit{}, errValue
}
// MustParseISO is like ParseISO, but panics if the given currency unit
// cannot be parsed. It simplifies safe initialization of Unit values.
func MustParseISO(s string) Unit {
c, err := ParseISO(s)
if err != nil {
panic(err)
}
return c
}
// FromRegion reports the currency unit that is currently legal tender in the
// given region according to CLDR. It will return false if region currently does
// not have a legal tender.
func FromRegion(r language.Region) (currency Unit, ok bool) {
x := regionToCode(r)
i := sort.Search(len(regionToCurrency), func(i int) bool {
return regionToCurrency[i].region >= x
})
if i < len(regionToCurrency) && regionToCurrency[i].region == x {
return Unit{regionToCurrency[i].code}, true
}
return Unit{}, false
}
// FromTag reports the most likely currency for the given tag. It considers the
// currency defined in the -u extension and infers the region if necessary.
func FromTag(t language.Tag) (Unit, language.Confidence) {
if cur := t.TypeForKey("cu"); len(cur) == 3 {
c, _ := ParseISO(cur)
return c, language.Exact
}
r, conf := t.Region()
if cur, ok := FromRegion(r); ok {
return cur, conf
}
return Unit{}, language.No
}
var (
// Undefined and testing.
XXX Unit = Unit{}
XTS Unit = Unit{xts}
// G10 currencies https://en.wikipedia.org/wiki/G10_currencies.
USD Unit = Unit{usd}
EUR Unit = Unit{eur}
JPY Unit = Unit{jpy}
GBP Unit = Unit{gbp}
CHF Unit = Unit{chf}
AUD Unit = Unit{aud}
NZD Unit = Unit{nzd}
CAD Unit = Unit{cad}
SEK Unit = Unit{sek}
NOK Unit = Unit{nok}
// Additional common currencies as defined by CLDR.
BRL Unit = Unit{brl}
CNY Unit = Unit{cny}
DKK Unit = Unit{dkk}
INR Unit = Unit{inr}
RUB Unit = Unit{rub}
HKD Unit = Unit{hkd}
IDR Unit = Unit{idr}
KRW Unit = Unit{krw}
MXN Unit = Unit{mxn}
PLN Unit = Unit{pln}
SAR Unit = Unit{sar}
THB Unit = Unit{thb}
TRY Unit = Unit{try}
TWD Unit = Unit{twd}
ZAR Unit = Unit{zar}
// Precious metals.
XAG Unit = Unit{xag}
XAU Unit = Unit{xau}
XPT Unit = Unit{xpt}
XPD Unit = Unit{xpd}
)

171
vendor/golang.org/x/text/currency/currency_test.go generated vendored Normal file
View File

@ -0,0 +1,171 @@
// 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 currency
import (
"fmt"
"testing"
"golang.org/x/text/internal/testtext"
"golang.org/x/text/language"
)
var (
cup = MustParseISO("CUP")
czk = MustParseISO("CZK")
xcd = MustParseISO("XCD")
zwr = MustParseISO("ZWR")
)
func TestParseISO(t *testing.T) {
testCases := []struct {
in string
out Unit
ok bool
}{
{"USD", USD, true},
{"xxx", XXX, true},
{"xts", XTS, true},
{"XX", XXX, false},
{"XXXX", XXX, false},
{"", XXX, false}, // not well-formed
{"UUU", XXX, false}, // unknown
{"\u22A9", XXX, false}, // non-ASCII, printable
{"aaa", XXX, false},
{"zzz", XXX, false},
{"000", XXX, false},
{"999", XXX, false},
{"---", XXX, false},
{"\x00\x00\x00", XXX, false},
{"\xff\xff\xff", XXX, false},
}
for i, tc := range testCases {
if x, err := ParseISO(tc.in); x != tc.out || err == nil != tc.ok {
t.Errorf("%d:%s: was %s, %v; want %s, %v", i, tc.in, x, err == nil, tc.out, tc.ok)
}
}
}
func TestFromRegion(t *testing.T) {
testCases := []struct {
region string
currency Unit
ok bool
}{
{"NL", EUR, true},
{"BE", EUR, true},
{"AG", xcd, true},
{"CH", CHF, true},
{"CU", cup, true}, // first of multiple
{"DG", USD, true}, // does not have M49 code
{"150", XXX, false}, // implicit false
{"CP", XXX, false}, // explicit false in CLDR
{"CS", XXX, false}, // all expired
{"ZZ", XXX, false}, // none match
}
for _, tc := range testCases {
cur, ok := FromRegion(language.MustParseRegion(tc.region))
if cur != tc.currency || ok != tc.ok {
t.Errorf("%s: got %v, %v; want %v, %v", tc.region, cur, ok, tc.currency, tc.ok)
}
}
}
func TestFromTag(t *testing.T) {
testCases := []struct {
tag string
currency Unit
conf language.Confidence
}{
{"nl", EUR, language.Low}, // nl also spoken outside Euro land.
{"nl-BE", EUR, language.Exact}, // region is known
{"pt", BRL, language.Low},
{"en", USD, language.Low},
{"en-u-cu-eur", EUR, language.Exact},
{"tlh", XXX, language.No}, // Klingon has no country.
{"es-419", XXX, language.No},
{"und", USD, language.Low},
}
for _, tc := range testCases {
cur, conf := FromTag(language.MustParse(tc.tag))
if cur != tc.currency || conf != tc.conf {
t.Errorf("%s: got %v, %v; want %v, %v", tc.tag, cur, conf, tc.currency, tc.conf)
}
}
}
func TestTable(t *testing.T) {
for i := 4; i < len(currency); i += 4 {
if a, b := currency[i-4:i-1], currency[i:i+3]; a >= b {
t.Errorf("currency unordered at element %d: %s >= %s", i, a, b)
}
}
// First currency has index 1, last is numCurrencies.
if c := currency.Elem(1)[:3]; c != "ADP" {
t.Errorf("first was %q; want ADP", c)
}
if c := currency.Elem(numCurrencies)[:3]; c != "ZWR" {
t.Errorf("last was %q; want ZWR", c)
}
}
func TestKindRounding(t *testing.T) {
testCases := []struct {
kind Kind
cur Unit
scale int
inc int
}{
{Standard, USD, 2, 1},
{Standard, CHF, 2, 1},
{Cash, CHF, 2, 5},
{Standard, TWD, 2, 1},
{Cash, TWD, 0, 1},
{Standard, czk, 2, 1},
{Cash, czk, 0, 1},
{Standard, zwr, 2, 1},
{Cash, zwr, 0, 1},
{Standard, KRW, 0, 1},
{Cash, KRW, 0, 1}, // Cash defaults to standard.
}
for i, tc := range testCases {
if scale, inc := tc.kind.Rounding(tc.cur); scale != tc.scale && inc != tc.inc {
t.Errorf("%d: got %d, %d; want %d, %d", i, scale, inc, tc.scale, tc.inc)
}
}
}
const body = `package main
import (
"fmt"
"golang.org/x/text/currency"
)
func main() {
%s
}
`
func TestLinking(t *testing.T) {
base := getSize(t, `fmt.Print(currency.CLDRVersion)`)
symbols := getSize(t, `fmt.Print(currency.Symbol(currency.USD))`)
if d := symbols - base; d < 2*1024 {
t.Errorf("size(symbols)-size(base) was %d; want > 2K", d)
}
}
func getSize(t *testing.T, main string) int {
size, err := testtext.CodeSize(fmt.Sprintf(body, main))
if err != nil {
t.Skipf("skipping link size test; binary size could not be determined: %v", err)
}
return size
}
func BenchmarkString(b *testing.B) {
for i := 0; i < b.N; i++ {
USD.String()
}
}

27
vendor/golang.org/x/text/currency/example_test.go generated vendored Normal file
View File

@ -0,0 +1,27 @@
// 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 currency_test
import (
"fmt"
"time"
"golang.org/x/text/currency"
)
func ExampleQuery() {
t1799, _ := time.Parse("2006-01-02", "1799-01-01")
for it := currency.Query(currency.Date(t1799)); it.Next(); {
from := ""
if t, ok := it.From(); ok {
from = t.Format("2006-01-02")
}
fmt.Printf("%v is used in %v since: %v\n", it.Unit(), it.Region(), from)
}
// Output:
// GBP is used in GB since: 1694-07-27
// GIP is used in GI since: 1713-01-01
// USD is used in US since: 1792-01-01
}

215
vendor/golang.org/x/text/currency/format.go generated vendored Normal file
View File

@ -0,0 +1,215 @@
// 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 currency
import (
"fmt"
"io"
"sort"
"golang.org/x/text/internal"
"golang.org/x/text/internal/format"
"golang.org/x/text/language"
)
// Amount is an amount-currency unit pair.
type Amount struct {
amount interface{} // Change to decimal(64|128).
currency Unit
}
// Currency reports the currency unit of this amount.
func (a Amount) Currency() Unit { return a.currency }
// TODO: based on decimal type, but may make sense to customize a bit.
// func (a Amount) Decimal()
// func (a Amount) Int() (int64, error)
// func (a Amount) Fraction() (int64, error)
// func (a Amount) Rat() *big.Rat
// func (a Amount) Float() (float64, error)
// func (a Amount) Scale() uint
// func (a Amount) Precision() uint
// func (a Amount) Sign() int
//
// Add/Sub/Div/Mul/Round.
var space = []byte(" ")
// Format implements fmt.Formatter. It accepts format.State for
// language-specific rendering.
func (a Amount) Format(s fmt.State, verb rune) {
v := formattedValue{
currency: a.currency,
amount: a.amount,
format: defaultFormat,
}
v.Format(s, verb)
}
// formattedValue is currency amount or unit that implements language-sensitive
// formatting.
type formattedValue struct {
currency Unit
amount interface{} // Amount, Unit, or number.
format *options
}
// Format implements fmt.Formatter. It accepts format.State for
// language-specific rendering.
func (v formattedValue) Format(s fmt.State, verb rune) {
var lang int
if state, ok := s.(format.State); ok {
lang, _ = language.CompactIndex(state.Language())
}
// Get the options. Use DefaultFormat if not present.
opt := v.format
if opt == nil {
opt = defaultFormat
}
cur := v.currency
if cur.index == 0 {
cur = opt.currency
}
// TODO: use pattern.
io.WriteString(s, opt.symbol(lang, cur))
if v.amount != nil {
s.Write(space)
// TODO: apply currency-specific rounding
scale, _ := opt.kind.Rounding(cur)
if _, ok := s.Precision(); !ok {
fmt.Fprintf(s, "%.*f", scale, v.amount)
} else {
fmt.Fprint(s, v.amount)
}
}
}
// Formatter decorates a given number, Unit or Amount with formatting options.
type Formatter func(amount interface{}) formattedValue
// func (f Formatter) Options(opts ...Option) Formatter
// TODO: call this a Formatter or FormatFunc?
var dummy = USD.Amount(0)
// adjust creates a new Formatter based on the adjustments of fn on f.
func (f Formatter) adjust(fn func(*options)) Formatter {
var o options = *(f(dummy).format)
fn(&o)
return o.format
}
// Default creates a new Formatter that defaults to currency unit c if a numeric
// value is passed that is not associated with a currency.
func (f Formatter) Default(currency Unit) Formatter {
return f.adjust(func(o *options) { o.currency = currency })
}
// Kind sets the kind of the underlying currency unit.
func (f Formatter) Kind(k Kind) Formatter {
return f.adjust(func(o *options) { o.kind = k })
}
var defaultFormat *options = ISO(dummy).format
var (
// Uses Narrow symbols. Overrides Symbol, if present.
NarrowSymbol Formatter = Formatter(formNarrow)
// Use Symbols instead of ISO codes, when available.
Symbol Formatter = Formatter(formSymbol)
// Use ISO code as symbol.
ISO Formatter = Formatter(formISO)
// TODO:
// // Use full name as symbol.
// Name Formatter
)
// options configures rendering and rounding options for an Amount.
type options struct {
currency Unit
kind Kind
symbol func(compactIndex int, c Unit) string
}
func (o *options) format(amount interface{}) formattedValue {
v := formattedValue{format: o}
switch x := amount.(type) {
case Amount:
v.amount = x.amount
v.currency = x.currency
case *Amount:
v.amount = x.amount
v.currency = x.currency
case Unit:
v.currency = x
case *Unit:
v.currency = *x
default:
if o.currency.index == 0 {
panic("cannot format number without a currency being set")
}
// TODO: Must be a number.
v.amount = x
v.currency = o.currency
}
return v
}
var (
optISO = options{symbol: lookupISO}
optSymbol = options{symbol: lookupSymbol}
optNarrow = options{symbol: lookupNarrow}
)
// These need to be functions, rather than curried methods, as curried methods
// are evaluated at init time, causing tables to be included unconditionally.
func formISO(x interface{}) formattedValue { return optISO.format(x) }
func formSymbol(x interface{}) formattedValue { return optSymbol.format(x) }
func formNarrow(x interface{}) formattedValue { return optNarrow.format(x) }
func lookupISO(x int, c Unit) string { return c.String() }
func lookupSymbol(x int, c Unit) string { return normalSymbol.lookup(x, c) }
func lookupNarrow(x int, c Unit) string { return narrowSymbol.lookup(x, c) }
type symbolIndex struct {
index []uint16 // position corresponds with compact index of language.
data []curToIndex
}
var (
normalSymbol = symbolIndex{normalLangIndex, normalSymIndex}
narrowSymbol = symbolIndex{narrowLangIndex, narrowSymIndex}
)
func (x *symbolIndex) lookup(lang int, c Unit) string {
for {
index := x.data[x.index[lang]:x.index[lang+1]]
i := sort.Search(len(index), func(i int) bool {
return index[i].cur >= c.index
})
if i < len(index) && index[i].cur == c.index {
x := index[i].idx
start := x + 1
end := start + uint16(symbols[x])
if start == end {
return c.String()
}
return symbols[start:end]
}
if lang == 0 {
break
}
lang = int(internal.Parent[lang])
}
return c.String()
}

70
vendor/golang.org/x/text/currency/format_test.go generated vendored Normal file
View File

@ -0,0 +1,70 @@
// 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 currency
import (
"testing"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
var (
en = language.English
fr = language.French
en_US = language.AmericanEnglish
en_GB = language.BritishEnglish
en_AU = language.MustParse("en-AU")
und = language.Und
)
func TestFormatting(t *testing.T) {
testCases := []struct {
tag language.Tag
value interface{}
format Formatter
want string
}{
0: {en, USD.Amount(0.1), nil, "USD 0.10"},
1: {en, XPT.Amount(1.0), Symbol, "XPT 1.00"},
2: {en, USD.Amount(2.0), ISO, "USD 2.00"},
3: {und, USD.Amount(3.0), Symbol, "US$ 3.00"},
4: {en, USD.Amount(4.0), Symbol, "$ 4.00"},
5: {en, USD.Amount(5.20), NarrowSymbol, "$ 5.20"},
6: {en, AUD.Amount(6.20), Symbol, "A$ 6.20"},
7: {en_AU, AUD.Amount(7.20), Symbol, "$ 7.20"},
8: {en_GB, USD.Amount(8.20), Symbol, "US$ 8.20"},
9: {en, 9.0, Symbol.Default(EUR), "€ 9.00"},
10: {en, 10.123, Symbol.Default(KRW), "₩ 10"},
11: {fr, 11.52, Symbol.Default(TWD), "TWD 11.52"},
12: {en, 12.123, Symbol.Default(czk), "CZK 12.12"},
13: {en, 13.123, Symbol.Default(czk).Kind(Cash), "CZK 13"},
14: {en, 14.12345, ISO.Default(MustParseISO("CLF")), "CLF 14.1235"},
15: {en, USD.Amount(15.00), ISO.Default(TWD), "USD 15.00"},
16: {en, KRW.Amount(16.00), ISO.Kind(Cash), "KRW 16"},
// TODO: support integers as well.
17: {en, USD, nil, "USD"},
18: {en, USD, ISO, "USD"},
19: {en, USD, Symbol, "$"},
20: {en_GB, USD, Symbol, "US$"},
21: {en_AU, USD, NarrowSymbol, "$"},
}
for i, tc := range testCases {
p := message.NewPrinter(tc.tag)
v := tc.value
if tc.format != nil {
v = tc.format(v)
}
if got := p.Sprint(v); got != tc.want {
t.Errorf("%d: got %q; want %q", i, got, tc.want)
}
}
}

400
vendor/golang.org/x/text/currency/gen.go generated vendored Normal file
View File

@ -0,0 +1,400 @@
// 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.
// +build ignore
// Generator for currency-related data.
package main
import (
"flag"
"fmt"
"log"
"os"
"sort"
"strconv"
"strings"
"time"
"golang.org/x/text/internal"
"golang.org/x/text/internal/gen"
"golang.org/x/text/internal/tag"
"golang.org/x/text/language"
"golang.org/x/text/unicode/cldr"
)
var (
test = flag.Bool("test", false,
"test existing tables; can be used to compare web data with package data.")
outputFile = flag.String("output", "tables.go", "output file")
draft = flag.String("draft",
"contributed",
`Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
)
func main() {
gen.Init()
gen.Repackage("gen_common.go", "common.go", "currency")
// Read the CLDR zip file.
r := gen.OpenCLDRCoreZip()
defer r.Close()
d := &cldr.Decoder{}
d.SetDirFilter("supplemental", "main")
d.SetSectionFilter("numbers")
data, err := d.DecodeZip(r)
if err != nil {
log.Fatalf("DecodeZip: %v", err)
}
w := gen.NewCodeWriter()
defer w.WriteGoFile(*outputFile, "currency")
fmt.Fprintln(w, `import "golang.org/x/text/internal/tag"`)
gen.WriteCLDRVersion(w)
b := &builder{}
b.genCurrencies(w, data.Supplemental())
b.genSymbols(w, data)
}
var constants = []string{
// Undefined and testing.
"XXX", "XTS",
// G11 currencies https://en.wikipedia.org/wiki/G10_currencies.
"USD", "EUR", "JPY", "GBP", "CHF", "AUD", "NZD", "CAD", "SEK", "NOK", "DKK",
// Precious metals.
"XAG", "XAU", "XPT", "XPD",
// Additional common currencies as defined by CLDR.
"BRL", "CNY", "INR", "RUB", "HKD", "IDR", "KRW", "MXN", "PLN", "SAR",
"THB", "TRY", "TWD", "ZAR",
}
type builder struct {
currencies tag.Index
numCurrencies int
}
func (b *builder) genCurrencies(w *gen.CodeWriter, data *cldr.SupplementalData) {
// 3-letter ISO currency codes
// Start with dummy to let index start at 1.
currencies := []string{"\x00\x00\x00\x00"}
// currency codes
for _, reg := range data.CurrencyData.Region {
for _, cur := range reg.Currency {
currencies = append(currencies, cur.Iso4217)
}
}
// Not included in the list for some reasons:
currencies = append(currencies, "MVP")
sort.Strings(currencies)
// Unique the elements.
k := 0
for i := 1; i < len(currencies); i++ {
if currencies[k] != currencies[i] {
currencies[k+1] = currencies[i]
k++
}
}
currencies = currencies[:k+1]
// Close with dummy for simpler and faster searching.
currencies = append(currencies, "\xff\xff\xff\xff")
// Write currency values.
fmt.Fprintln(w, "const (")
for _, c := range constants {
index := sort.SearchStrings(currencies, c)
fmt.Fprintf(w, "\t%s = %d\n", strings.ToLower(c), index)
}
fmt.Fprint(w, ")")
// Compute currency-related data that we merge into the table.
for _, info := range data.CurrencyData.Fractions[0].Info {
if info.Iso4217 == "DEFAULT" {
continue
}
standard := getRoundingIndex(info.Digits, info.Rounding, 0)
cash := getRoundingIndex(info.CashDigits, info.CashRounding, standard)
index := sort.SearchStrings(currencies, info.Iso4217)
currencies[index] += mkCurrencyInfo(standard, cash)
}
// Set default values for entries that weren't touched.
for i, c := range currencies {
if len(c) == 3 {
currencies[i] += mkCurrencyInfo(0, 0)
}
}
b.currencies = tag.Index(strings.Join(currencies, ""))
w.WriteComment(`
currency holds an alphabetically sorted list of canonical 3-letter currency
identifiers. Each identifier is followed by a byte of type currencyInfo,
defined in gen_common.go.`)
w.WriteConst("currency", b.currencies)
// Hack alert: gofmt indents a trailing comment after an indented string.
// Ensure that the next thing written is not a comment.
b.numCurrencies = (len(b.currencies) / 4) - 2
w.WriteConst("numCurrencies", b.numCurrencies)
// Create a table that maps regions to currencies.
regionToCurrency := []toCurrency{}
for _, reg := range data.CurrencyData.Region {
if len(reg.Iso3166) != 2 {
log.Fatalf("Unexpected group %q in region data", reg.Iso3166)
}
if len(reg.Currency) == 0 {
continue
}
cur := reg.Currency[0]
if cur.To != "" || cur.Tender == "false" {
continue
}
regionToCurrency = append(regionToCurrency, toCurrency{
region: regionToCode(language.MustParseRegion(reg.Iso3166)),
code: uint16(b.currencies.Index([]byte(cur.Iso4217))),
})
}
sort.Sort(byRegion(regionToCurrency))
w.WriteType(toCurrency{})
w.WriteVar("regionToCurrency", regionToCurrency)
// Create a table that maps regions to currencies.
regionData := []regionInfo{}
for _, reg := range data.CurrencyData.Region {
if len(reg.Iso3166) != 2 {
log.Fatalf("Unexpected group %q in region data", reg.Iso3166)
}
for _, cur := range reg.Currency {
from, _ := time.Parse("2006-01-02", cur.From)
to, _ := time.Parse("2006-01-02", cur.To)
code := uint16(b.currencies.Index([]byte(cur.Iso4217)))
if cur.Tender == "false" {
code |= nonTenderBit
}
regionData = append(regionData, regionInfo{
region: regionToCode(language.MustParseRegion(reg.Iso3166)),
code: code,
from: toDate(from),
to: toDate(to),
})
}
}
sort.Stable(byRegionCode(regionData))
w.WriteType(regionInfo{})
w.WriteVar("regionData", regionData)
}
type regionInfo struct {
region uint16
code uint16 // 0x8000 not legal tender
from uint32
to uint32
}
type byRegionCode []regionInfo
func (a byRegionCode) Len() int { return len(a) }
func (a byRegionCode) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byRegionCode) Less(i, j int) bool { return a[i].region < a[j].region }
type toCurrency struct {
region uint16
code uint16
}
type byRegion []toCurrency
func (a byRegion) Len() int { return len(a) }
func (a byRegion) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byRegion) Less(i, j int) bool { return a[i].region < a[j].region }
func mkCurrencyInfo(standard, cash int) string {
return string([]byte{byte(cash<<cashShift | standard)})
}
func getRoundingIndex(digits, rounding string, defIndex int) int {
round := roundings[defIndex] // default
if digits != "" {
round.scale = parseUint8(digits)
}
if rounding != "" && rounding != "0" { // 0 means 1 here in CLDR
round.increment = parseUint8(rounding)
}
// Will panic if the entry doesn't exist:
for i, r := range roundings {
if r == round {
return i
}
}
log.Fatalf("Rounding entry %#v does not exist.", round)
panic("unreachable")
}
// genSymbols generates the symbols used for currencies. Most symbols are
// defined in root and there is only very small variation per language.
// The following rules apply:
// - A symbol can be requested as normal or narrow.
// - If a symbol is not defined for a currency, it defaults to its ISO code.
func (b *builder) genSymbols(w *gen.CodeWriter, data *cldr.CLDR) {
d, err := cldr.ParseDraft(*draft)
if err != nil {
log.Fatalf("filter: %v", err)
}
const (
normal = iota
narrow
numTypes
)
// language -> currency -> type -> symbol
var symbols [language.NumCompactTags][][numTypes]*string
// Collect symbol information per language.
for _, lang := range data.Locales() {
ldml := data.RawLDML(lang)
if ldml.Numbers == nil || ldml.Numbers.Currencies == nil {
continue
}
langIndex, ok := language.CompactIndex(language.MustParse(lang))
if !ok {
log.Fatalf("No compact index for language %s", lang)
}
symbols[langIndex] = make([][numTypes]*string, b.numCurrencies+1)
for _, c := range ldml.Numbers.Currencies.Currency {
syms := cldr.MakeSlice(&c.Symbol)
syms.SelectDraft(d)
for _, sym := range c.Symbol {
v := sym.Data()
if v == c.Type {
// We define "" to mean the ISO symbol.
v = ""
}
cur := b.currencies.Index([]byte(c.Type))
// XXX gets reassigned to 0 in the package's code.
if c.Type == "XXX" {
cur = 0
}
if cur == -1 {
fmt.Println("Unsupported:", c.Type)
continue
}
switch sym.Alt {
case "":
symbols[langIndex][cur][normal] = &v
case "narrow":
symbols[langIndex][cur][narrow] = &v
}
}
}
}
// Remove values identical to the parent.
for langIndex, data := range symbols {
for curIndex, curs := range data {
for typ, sym := range curs {
if sym == nil {
continue
}
for p := uint16(langIndex); p != 0; {
p = internal.Parent[p]
x := symbols[p]
if x == nil {
continue
}
if v := x[curIndex][typ]; v != nil || p == 0 {
// Value is equal to the default value root value is undefined.
parentSym := ""
if v != nil {
parentSym = *v
}
if parentSym == *sym {
// Value is the same as parent.
data[curIndex][typ] = nil
}
break
}
}
}
}
}
// Create symbol index.
symbolData := []byte{0}
symbolLookup := map[string]uint16{"": 0} // 0 means default, so block that value.
for _, data := range symbols {
for _, curs := range data {
for _, sym := range curs {
if sym == nil {
continue
}
if _, ok := symbolLookup[*sym]; !ok {
symbolLookup[*sym] = uint16(len(symbolData))
symbolData = append(symbolData, byte(len(*sym)))
symbolData = append(symbolData, *sym...)
}
}
}
}
w.WriteComment(`
symbols holds symbol data of the form <n> <str>, where n is the length of
the symbol string str.`)
w.WriteConst("symbols", string(symbolData))
// Create index from language to currency lookup to symbol.
type curToIndex struct{ cur, idx uint16 }
w.WriteType(curToIndex{})
prefix := []string{"normal", "narrow"}
// Create data for regular and narrow symbol data.
for typ := normal; typ <= narrow; typ++ {
indexes := []curToIndex{} // maps currency to symbol index
languages := []uint16{}
for _, data := range symbols {
languages = append(languages, uint16(len(indexes)))
for curIndex, curs := range data {
if sym := curs[typ]; sym != nil {
indexes = append(indexes, curToIndex{uint16(curIndex), symbolLookup[*sym]})
}
}
}
languages = append(languages, uint16(len(indexes)))
w.WriteVar(prefix[typ]+"LangIndex", languages)
w.WriteVar(prefix[typ]+"SymIndex", indexes)
}
}
func parseUint8(str string) uint8 {
x, err := strconv.ParseUint(str, 10, 8)
if err != nil {
// Show line number of where this function was called.
log.New(os.Stderr, "", log.Lshortfile).Output(2, err.Error())
os.Exit(1)
}
return uint8(x)
}

71
vendor/golang.org/x/text/currency/gen_common.go generated vendored Normal file
View File

@ -0,0 +1,71 @@
// 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.
// +build ignore
package main
import (
"time"
"golang.org/x/text/language"
)
// This file contains code common to gen.go and the package code.
const (
cashShift = 3
roundMask = 0x7
nonTenderBit = 0x8000
)
// currencyInfo contains information about a currency.
// bits 0..2: index into roundings for standard rounding
// bits 3..5: index into roundings for cash rounding
type currencyInfo byte
// roundingType defines the scale (number of fractional decimals) and increments
// in terms of units of size 10^-scale. For example, for scale == 2 and
// increment == 1, the currency is rounded to units of 0.01.
type roundingType struct {
scale, increment uint8
}
// roundings contains rounding data for currencies. This struct is
// created by hand as it is very unlikely to change much.
var roundings = [...]roundingType{
{2, 1}, // default
{0, 1},
{1, 1},
{3, 1},
{4, 1},
{2, 5}, // cash rounding alternative
{2, 50},
}
// regionToCode returns a 16-bit region code. Only two-letter codes are
// supported. (Three-letter codes are not needed.)
func regionToCode(r language.Region) uint16 {
if s := r.String(); len(s) == 2 {
return uint16(s[0])<<8 | uint16(s[1])
}
return 0
}
func toDate(t time.Time) uint32 {
y := t.Year()
if y == 1 {
return 0
}
date := uint32(y) << 4
date |= uint32(t.Month())
date <<= 5
date |= uint32(t.Day())
return date
}
func fromDate(date uint32) time.Time {
return time.Date(int(date>>9), time.Month((date>>5)&0xf), int(date&0x1f), 0, 0, 0, 0, time.UTC)
}

152
vendor/golang.org/x/text/currency/query.go generated vendored Normal file
View File

@ -0,0 +1,152 @@
// 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 currency
import (
"sort"
"time"
"golang.org/x/text/language"
)
// QueryIter represents a set of Units. The default set includes all Units that
// are currently in use as legal tender in any Region.
type QueryIter interface {
// Next returns true if there is a next element available.
// It must be called before any of the other methods are called.
Next() bool
// Unit returns the unit of the current iteration.
Unit() Unit
// Region returns the Region for the current iteration.
Region() language.Region
// From returns the date from which the unit was used in the region.
// It returns false if this date is unknown.
From() (time.Time, bool)
// To returns the date up till which the unit was used in the region.
// It returns false if this date is unknown or if the unit is still in use.
To() (time.Time, bool)
// IsTender reports whether the unit is a legal tender in the region during
// the specified date range.
IsTender() bool
}
// Query represents a set of Units. The default set includes all Units that are
// currently in use as legal tender in any Region.
func Query(options ...QueryOption) QueryIter {
it := &iter{
end: len(regionData),
date: 0xFFFFFFFF,
}
for _, fn := range options {
fn(it)
}
return it
}
// NonTender returns a new query that also includes matching Units that are not
// legal tender.
var NonTender QueryOption = nonTender
func nonTender(i *iter) {
i.nonTender = true
}
// Historical selects the units for all dates.
var Historical QueryOption = historical
func historical(i *iter) {
i.date = hist
}
// A QueryOption can be used to change the set of unit information returned by
// a query.
type QueryOption func(*iter)
// Date queries the units that were in use at the given point in history.
func Date(t time.Time) QueryOption {
d := toDate(t)
return func(i *iter) {
i.date = d
}
}
// Region limits the query to only return entries for the given region.
func Region(r language.Region) QueryOption {
p, end := len(regionData), len(regionData)
x := regionToCode(r)
i := sort.Search(len(regionData), func(i int) bool {
return regionData[i].region >= x
})
if i < len(regionData) && regionData[i].region == x {
p = i
for i++; i < len(regionData) && regionData[i].region == x; i++ {
}
end = i
}
return func(i *iter) {
i.p, i.end = p, end
}
}
const (
hist = 0x00
now = 0xFFFFFFFF
)
type iter struct {
*regionInfo
p, end int
date uint32
nonTender bool
}
func (i *iter) Next() bool {
for ; i.p < i.end; i.p++ {
i.regionInfo = &regionData[i.p]
if !i.nonTender && !i.IsTender() {
continue
}
if i.date == hist || (i.from <= i.date && (i.to == 0 || i.date <= i.to)) {
i.p++
return true
}
}
return false
}
func (r *regionInfo) Region() language.Region {
// TODO: this could be much faster.
var buf [2]byte
buf[0] = uint8(r.region >> 8)
buf[1] = uint8(r.region)
return language.MustParseRegion(string(buf[:]))
}
func (r *regionInfo) Unit() Unit {
return Unit{r.code &^ nonTenderBit}
}
func (r *regionInfo) IsTender() bool {
return r.code&nonTenderBit == 0
}
func (r *regionInfo) From() (time.Time, bool) {
if r.from == 0 {
return time.Time{}, false
}
return fromDate(r.from), true
}
func (r *regionInfo) To() (time.Time, bool) {
if r.to == 0 {
return time.Time{}, false
}
return fromDate(r.to), true
}

107
vendor/golang.org/x/text/currency/query_test.go generated vendored Normal file
View File

@ -0,0 +1,107 @@
// 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 currency
import (
"testing"
"time"
"golang.org/x/text/language"
)
func TestQuery(t *testing.T) {
r := func(region string) language.Region {
return language.MustParseRegion(region)
}
t1800, _ := time.Parse("2006-01-02", "1800-01-01")
type result struct {
region language.Region
unit Unit
isTender bool
from, to string
}
testCases := []struct {
name string
opts []QueryOption
results []result
}{{
name: "XA",
opts: []QueryOption{Region(r("XA"))},
results: []result{},
}, {
name: "AC",
opts: []QueryOption{Region(r("AC"))},
results: []result{
{r("AC"), MustParseISO("SHP"), true, "1976-01-01", ""},
},
}, {
name: "US",
opts: []QueryOption{Region(r("US"))},
results: []result{
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
},
}, {
name: "US-hist",
opts: []QueryOption{Region(r("US")), Historical},
results: []result{
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
},
}, {
name: "US-non-tender",
opts: []QueryOption{Region(r("US")), NonTender},
results: []result{
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
{r("US"), MustParseISO("USN"), false, "", ""},
},
}, {
name: "US-historical+non-tender",
opts: []QueryOption{Region(r("US")), Historical, NonTender},
results: []result{
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
{r("US"), MustParseISO("USN"), false, "", ""},
{r("US"), MustParseISO("USS"), false, "", "2014-03-01"},
},
}, {
name: "1800",
opts: []QueryOption{Date(t1800)},
results: []result{
{r("CH"), MustParseISO("CHF"), true, "1799-03-17", ""},
{r("GB"), MustParseISO("GBP"), true, "1694-07-27", ""},
{r("GI"), MustParseISO("GIP"), true, "1713-01-01", ""},
// The date for IE and PR seem wrong, so these may be updated at
// some point causing the tests to fail.
{r("IE"), MustParseISO("GBP"), true, "1800-01-01", "1922-01-01"},
{r("PR"), MustParseISO("ESP"), true, "1800-01-01", "1898-12-10"},
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
},
}}
for _, tc := range testCases {
n := 0
for it := Query(tc.opts...); it.Next(); n++ {
if n < len(tc.results) {
got := result{
it.Region(),
it.Unit(),
it.IsTender(),
getTime(it.From()),
getTime(it.To()),
}
if got != tc.results[n] {
t.Errorf("%s:%d: got %v; want %v", tc.name, n, got, tc.results[n])
}
}
}
if n != len(tc.results) {
t.Errorf("%s: unexpected number of results: got %d; want %d", tc.name, n, len(tc.results))
}
}
}
func getTime(t time.Time, ok bool) string {
if !ok {
return ""
}
return t.Format("2006-01-02")
}

2629
vendor/golang.org/x/text/currency/tables.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

93
vendor/golang.org/x/text/currency/tables_test.go generated vendored Normal file
View File

@ -0,0 +1,93 @@
package currency
import (
"flag"
"strings"
"testing"
"time"
"golang.org/x/text/internal/gen"
"golang.org/x/text/internal/testtext"
"golang.org/x/text/language"
"golang.org/x/text/message"
"golang.org/x/text/unicode/cldr"
)
var draft = flag.String("draft",
"contributed",
`Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
func TestTables(t *testing.T) {
testtext.SkipIfNotLong(t)
// Read the CLDR zip file.
r := gen.OpenCLDRCoreZip()
defer r.Close()
d := &cldr.Decoder{}
d.SetDirFilter("supplemental", "main")
d.SetSectionFilter("numbers")
data, err := d.DecodeZip(r)
if err != nil {
t.Fatalf("DecodeZip: %v", err)
}
dr, err := cldr.ParseDraft(*draft)
if err != nil {
t.Fatalf("filter: %v", err)
}
for _, lang := range data.Locales() {
p := message.NewPrinter(language.MustParse(lang))
ldml := data.RawLDML(lang)
if ldml.Numbers == nil || ldml.Numbers.Currencies == nil {
continue
}
for _, c := range ldml.Numbers.Currencies.Currency {
syms := cldr.MakeSlice(&c.Symbol)
syms.SelectDraft(dr)
for _, sym := range c.Symbol {
cur, err := ParseISO(c.Type)
if err != nil {
continue
}
formatter := Symbol
switch sym.Alt {
case "":
case "narrow":
formatter = NarrowSymbol
default:
continue
}
want := sym.Data()
if got := p.Sprint(formatter(cur)); got != want {
t.Errorf("%s:%sSymbol(%s) = %s; want %s", lang, strings.Title(sym.Alt), c.Type, got, want)
}
}
}
}
for _, reg := range data.Supplemental().CurrencyData.Region {
i := 0
for ; regionData[i].Region().String() != reg.Iso3166; i++ {
}
it := Query(Historical, NonTender, Region(language.MustParseRegion(reg.Iso3166)))
for _, cur := range reg.Currency {
from, _ := time.Parse("2006-01-02", cur.From)
to, _ := time.Parse("2006-01-02", cur.To)
it.Next()
for j, r := range []QueryIter{&iter{regionInfo: &regionData[i]}, it} {
if got, _ := r.From(); from != got {
t.Errorf("%d:%s:%s:from: got %v; want %v", j, reg.Iso3166, cur.Iso4217, got, from)
}
if got, _ := r.To(); to != got {
t.Errorf("%d:%s:%s:to: got %v; want %v", j, reg.Iso3166, cur.Iso4217, got, to)
}
}
i++
}
}
}