mirror of
https://github.com/miniflux/v2.git
synced 2025-09-15 18:57:04 +00:00
Add FeedIcon API call and update dependencies
This commit is contained in:
parent
231ebf2daa
commit
27196589fb
262 changed files with 83830 additions and 30061 deletions
14
vendor/golang.org/x/text/README.md
generated
vendored
14
vendor/golang.org/x/text/README.md
generated
vendored
|
@ -9,16 +9,18 @@ This repo uses Semantic versioning (http://semver.org/), so
|
|||
and
|
||||
1. PATCH version when you make backwards-compatible bug fixes.
|
||||
|
||||
A Unicode major and minor version bump is mapped to a major version bump in
|
||||
x/text.
|
||||
A path version bump in Unicode is mapped to a minor version bump in x/text.
|
||||
Note that, consistent with the definitions in semver, until version 1.0.0 of
|
||||
x/text is reached, the minor version is considered a major version.
|
||||
So going from 0.1.0 to 0.2.0 is considered to be a major version bump.
|
||||
Until version 1.0.0 of x/text is reached, the minor version is considered a
|
||||
major version. So going from 0.1.0 to 0.2.0 is considered to be a major version
|
||||
bump.
|
||||
|
||||
A major new CLDR version is mapped to a minor version increase in x/text.
|
||||
Any other new CLDR version is mapped to a patch version increase in x/text.
|
||||
|
||||
It is important that the Unicode version used in `x/text` matches the one used
|
||||
by your Go compiler. The `x/text` repository supports multiple versions of
|
||||
Unicode and will match the version of Unicode to that of the Go compiler. At the
|
||||
moment this is supported for Go compilers from version 1.7.
|
||||
|
||||
## Download/Install
|
||||
|
||||
The easiest way to install is to run `go get -u golang.org/x/text`. You can
|
||||
|
|
4
vendor/golang.org/x/text/cases/gen.go
generated
vendored
4
vendor/golang.org/x/text/cases/gen.go
generated
vendored
|
@ -207,7 +207,7 @@ func genTables() {
|
|||
}
|
||||
|
||||
w := gen.NewCodeWriter()
|
||||
defer w.WriteGoFile("tables.go", "cases")
|
||||
defer w.WriteVersionedGoFile("tables.go", "cases")
|
||||
|
||||
gen.WriteUnicodeVersion(w)
|
||||
|
||||
|
@ -761,7 +761,7 @@ func genTablesTest() {
|
|||
|
||||
fmt.Fprintln(w, ")")
|
||||
|
||||
gen.WriteGoFile("tables_test.go", "cases", w.Bytes())
|
||||
gen.WriteVersionedGoFile("tables_test.go", "cases", w.Bytes())
|
||||
}
|
||||
|
||||
// These functions are just used for verification that their definition have not
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// +build go1.10
|
||||
|
||||
package cases
|
||||
|
||||
// UnicodeVersion is the Unicode version from which the tables in this package are derived.
|
|
@ -1,5 +1,7 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// +build go1.10
|
||||
|
||||
package cases
|
||||
|
||||
var (
|
2213
vendor/golang.org/x/text/cases/tables9.0.0.go
generated
vendored
Normal file
2213
vendor/golang.org/x/text/cases/tables9.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1156
vendor/golang.org/x/text/cases/tables9.0.0_test.go
generated
vendored
Normal file
1156
vendor/golang.org/x/text/cases/tables9.0.0_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
49
vendor/golang.org/x/text/cmd/gotext/common.go
generated
vendored
Normal file
49
vendor/golang.org/x/text/cmd/gotext/common.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// 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 (
|
||||
"fmt"
|
||||
"go/build"
|
||||
"go/parser"
|
||||
|
||||
"golang.org/x/tools/go/loader"
|
||||
)
|
||||
|
||||
const (
|
||||
extractFile = "extracted.gotext.json"
|
||||
outFile = "out.gotext.json"
|
||||
gotextSuffix = ".gotext.json"
|
||||
)
|
||||
|
||||
// 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)
|
||||
}
|
||||
errorf = fmt.Errorf
|
||||
)
|
||||
|
||||
// TODO: still used. Remove when possible.
|
||||
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()
|
||||
}
|
34
vendor/golang.org/x/text/cmd/gotext/doc.go
generated
vendored
34
vendor/golang.org/x/text/cmd/gotext/doc.go
generated
vendored
|
@ -1,9 +1,4 @@
|
|||
// 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.
|
||||
|
||||
// DO NOT EDIT THIS FILE. GENERATED BY go generate.
|
||||
// Edit the documentation in other files and rerun go generate to generate this one.
|
||||
// Code generated by go generate. DO NOT EDIT.
|
||||
|
||||
// gotext is a tool for managing text in Go source code.
|
||||
//
|
||||
|
@ -13,7 +8,9 @@
|
|||
//
|
||||
// The commands are:
|
||||
//
|
||||
// extract extract strings to be translated from code
|
||||
// extract extracts strings to be translated from code
|
||||
// rewrite rewrites fmt functions to use a message Printer
|
||||
// generate generates code to insert translated messages
|
||||
//
|
||||
// Use "go help [command]" for more information about a command.
|
||||
//
|
||||
|
@ -23,7 +20,7 @@
|
|||
// Use "gotext help [topic]" for more information about that topic.
|
||||
//
|
||||
//
|
||||
// Extract strings to be translated from code
|
||||
// Extracts strings to be translated from code
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
|
@ -32,4 +29,25 @@
|
|||
//
|
||||
//
|
||||
//
|
||||
// Rewrites fmt functions to use a message Printer
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// go rewrite <package>
|
||||
//
|
||||
// rewrite is typically done once for a project. It rewrites all usages of
|
||||
// fmt to use x/text's message package whenever a message.Printer is in scope.
|
||||
// It rewrites Print and Println calls with constant strings to the equivalent
|
||||
// using Printf to allow translators to reorder arguments.
|
||||
//
|
||||
//
|
||||
// Generates code to insert translated messages
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// go generate <package>
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
package main
|
||||
|
|
78
vendor/golang.org/x/text/cmd/gotext/examples/extract/catalog.go
generated
vendored
Normal file
78
vendor/golang.org/x/text/cmd/gotext/examples/extract/catalog.go
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
// 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)": 6,
|
||||
"%[1]s is visiting %[3]s!\n": 3,
|
||||
"%d more files remaining!": 4,
|
||||
"%s is out of order!": 5,
|
||||
"%s is visiting %s!\n": 2,
|
||||
"Hello %s!\n": 1,
|
||||
"Hello world!\n": 0,
|
||||
}
|
||||
|
||||
var deIndex = []uint32{ // 8 elements
|
||||
0x00000000, 0x00000011, 0x00000023, 0x0000003d,
|
||||
0x00000057, 0x00000076, 0x00000076, 0x00000076,
|
||||
} // Size: 56 bytes
|
||||
|
||||
const deData string = "" + // Size: 118 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 %[1]d Bestände zu gehen!"
|
||||
|
||||
var en_USIndex = []uint32{ // 8 elements
|
||||
0x00000000, 0x00000012, 0x00000024, 0x00000042,
|
||||
0x00000060, 0x000000a3, 0x000000ba, 0x000000d9,
|
||||
} // Size: 56 bytes
|
||||
|
||||
const en_USData string = "" + // Size: 217 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!\x14\x01\x81\x01\x00\x02\x14\x02One file remaini" +
|
||||
"ng!\x00&\x02There are %[1]d more files remaining!\x02%[1]s is out of ord" +
|
||||
"er!\x02%.2[1]f miles traveled (%[1]f)"
|
||||
|
||||
var zhIndex = []uint32{ // 8 elements
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
} // Size: 56 bytes
|
||||
|
||||
const zhData string = ""
|
||||
|
||||
// Total table size 503 bytes (0KiB); checksum: A968BD6
|
186
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/de/messages.gotext.json
generated
vendored
Executable file
186
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/de/messages.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,186 @@
|
|||
{
|
||||
"language": "de",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello world!",
|
||||
"key": "Hello world!\n",
|
||||
"message": "Hello world!",
|
||||
"translation": "Hallo Welt!",
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:27:10"
|
||||
},
|
||||
{
|
||||
"id": "Hello {City}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {City}!",
|
||||
"translation": "Hallo {City}!",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "City",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "city"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:31:10"
|
||||
},
|
||||
{
|
||||
"id": "Hello {Town}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {Town}!",
|
||||
"translation": "Hallo {Town}!",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Town",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "town",
|
||||
"comment": "Town"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:35:10"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:40:10"
|
||||
},
|
||||
{
|
||||
"id": "{Person} is visiting {Place}!",
|
||||
"key": "%[1]s is visiting %[3]s!\n",
|
||||
"message": "{Person} is visiting {Place}!",
|
||||
"translation": "{Person} besucht {Place}!",
|
||||
"comment": "Person visiting a place.",
|
||||
"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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:55:10"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"type": "int",
|
||||
"underlyingType": "int",
|
||||
"argNum": 1,
|
||||
"expr": "n"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:67: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": "golang.org/x/text/cmd/gotext/examples/extract.referralCode",
|
||||
"underlyingType": "int",
|
||||
"argNum": 1,
|
||||
"expr": "c"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:73:10"
|
||||
},
|
||||
{
|
||||
"id": [ "msgOutOfOrder", "{Device} is out of order!" ],
|
||||
"key": "%s is out of order!",
|
||||
"message": "{Device} is out of order!",
|
||||
"translation": "",
|
||||
"comment": "FOO\n",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Device",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "device"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:81: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:85:10"
|
||||
}
|
||||
]
|
||||
}
|
206
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/de/out.gotext.json
generated
vendored
Executable file
206
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/de/out.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,206 @@
|
|||
{
|
||||
"language": "de",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello world!",
|
||||
"key": "Hello world!\n",
|
||||
"message": "Hello world!",
|
||||
"translation": "",
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:28: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:32:10"
|
||||
},
|
||||
{
|
||||
"id": "Hello {Town}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {Town}!",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Town",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "town",
|
||||
"comment": "Town"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:36: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:41:10"
|
||||
},
|
||||
{
|
||||
"id": "{Person} is visiting {Place}!",
|
||||
"key": "%[1]s is visiting %[3]s!\n",
|
||||
"message": "{Person} is visiting {Place}!",
|
||||
"translation": "",
|
||||
"comment": "Person visiting a place.",
|
||||
"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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:56: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:63: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:68: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": "golang.org/x/text/cmd/gotext/examples/extract.referralCode",
|
||||
"underlyingType": "int",
|
||||
"argNum": 1,
|
||||
"expr": "c"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:74:10"
|
||||
},
|
||||
{
|
||||
"id": [
|
||||
"msgOutOfOrder",
|
||||
"{Device} is out of order!"
|
||||
],
|
||||
"key": "%s is out of order!",
|
||||
"message": "{Device} is out of order!",
|
||||
"translation": "",
|
||||
"comment": "FOO\n",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Device",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "device"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:82: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:86:10"
|
||||
}
|
||||
]
|
||||
}
|
82
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/en-US/messages.gotext.json
generated
vendored
Executable file
82
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/en-US/messages.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"language": "en-US",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello world!",
|
||||
"key": "Hello world!\n",
|
||||
"message": "Hello world!",
|
||||
"translation": "Hello world!",
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:27:10"
|
||||
},
|
||||
{
|
||||
"id": "Hello {City}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {City}!",
|
||||
"translation": "Hello {City}n"
|
||||
},
|
||||
{
|
||||
"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}!\n"
|
||||
},
|
||||
{
|
||||
"id": "{Person} is visiting {Place}!",
|
||||
"key": "%[1]s is visiting %[3]s!\n",
|
||||
"message": "{Person} is visiting {Place}!",
|
||||
"translation": "{Person} is visiting {Place}!",
|
||||
"comment": "Person visiting a place."
|
||||
},
|
||||
{
|
||||
"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!",
|
||||
"comment": "FOO\n"
|
||||
},
|
||||
{
|
||||
"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})"
|
||||
}
|
||||
]
|
||||
}
|
206
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/en-US/out.gotext.json
generated
vendored
Executable file
206
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/en-US/out.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,206 @@
|
|||
{
|
||||
"language": "en-US",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello world!",
|
||||
"key": "Hello world!\n",
|
||||
"message": "Hello world!",
|
||||
"translation": "",
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:28: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:32:10"
|
||||
},
|
||||
{
|
||||
"id": "Hello {Town}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {Town}!",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Town",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "town",
|
||||
"comment": "Town"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:36: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:41:10"
|
||||
},
|
||||
{
|
||||
"id": "{Person} is visiting {Place}!",
|
||||
"key": "%[1]s is visiting %[3]s!\n",
|
||||
"message": "{Person} is visiting {Place}!",
|
||||
"translation": "",
|
||||
"comment": "Person visiting a place.",
|
||||
"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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:56: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:63: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:68: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": "golang.org/x/text/cmd/gotext/examples/extract.referralCode",
|
||||
"underlyingType": "int",
|
||||
"argNum": 1,
|
||||
"expr": "c"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:74:10"
|
||||
},
|
||||
{
|
||||
"id": [
|
||||
"msgOutOfOrder",
|
||||
"{Device} is out of order!"
|
||||
],
|
||||
"key": "%s is out of order!",
|
||||
"message": "{Device} is out of order!",
|
||||
"translation": "",
|
||||
"comment": "FOO\n",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Device",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "device"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:82: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:86:10"
|
||||
}
|
||||
]
|
||||
}
|
203
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/zh/messages.gotext.json
generated
vendored
Executable file
203
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/zh/messages.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,203 @@
|
|||
{
|
||||
"language": "zh",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello world!",
|
||||
"key": "Hello world!\n",
|
||||
"message": "Hello world!",
|
||||
"translation": "",
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:27: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:31:10"
|
||||
},
|
||||
{
|
||||
"id": "Hello {Town}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {Town}!",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Town",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "town",
|
||||
"comment": "Town"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:35: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:40:10"
|
||||
},
|
||||
{
|
||||
"id": "{Person} is visiting {Place}!",
|
||||
"key": "%[1]s is visiting %[3]s!\n",
|
||||
"message": "{Person} is visiting {Place}!",
|
||||
"translation": "",
|
||||
"comment": "Person visiting a place.",
|
||||
"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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:55:10"
|
||||
},
|
||||
{
|
||||
"id": "{} files remaining!",
|
||||
"key": "%d files remaining!",
|
||||
"message": "{} files remaining!",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "",
|
||||
"string": "%[1]d",
|
||||
"type": "int",
|
||||
"underlyingType": "int",
|
||||
"argNum": 1,
|
||||
"expr": "2"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:62: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:67:10"
|
||||
},
|
||||
{
|
||||
"id": "Use the following code for your discount: {ReferralCode}\n",
|
||||
"key": "Use the following code for your discount: %d\n",
|
||||
"message": "Use the following code for your discount: {ReferralCode}\n",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "ReferralCode",
|
||||
"string": "%[1]d",
|
||||
"type": "golang.org/x/text/cmd/gotext/examples/extract.referralCode",
|
||||
"underlyingType": "int",
|
||||
"argNum": 1,
|
||||
"expr": "c"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:73:10"
|
||||
},
|
||||
{
|
||||
"id": [ "{Device} is out of order!", "msgOutOfOrder" ],
|
||||
"key": "%s is out of order!",
|
||||
"message": "{Device} is out of order!",
|
||||
"translation": "",
|
||||
"comment": "FOO\n",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Device",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "device"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:81: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:85:10"
|
||||
}
|
||||
]
|
||||
}
|
206
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/zh/out.gotext.json
generated
vendored
Executable file
206
vendor/golang.org/x/text/cmd/gotext/examples/extract/locales/zh/out.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,206 @@
|
|||
{
|
||||
"language": "zh",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello world!",
|
||||
"key": "Hello world!\n",
|
||||
"message": "Hello world!",
|
||||
"translation": "",
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:28: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:32:10"
|
||||
},
|
||||
{
|
||||
"id": "Hello {Town}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {Town}!",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Town",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "town",
|
||||
"comment": "Town"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:36: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:41:10"
|
||||
},
|
||||
{
|
||||
"id": "{Person} is visiting {Place}!",
|
||||
"key": "%[1]s is visiting %[3]s!\n",
|
||||
"message": "{Person} is visiting {Place}!",
|
||||
"translation": "",
|
||||
"comment": "Person visiting a place.",
|
||||
"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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:56: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:63: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:68: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": "golang.org/x/text/cmd/gotext/examples/extract.referralCode",
|
||||
"underlyingType": "int",
|
||||
"argNum": 1,
|
||||
"expr": "c"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:74:10"
|
||||
},
|
||||
{
|
||||
"id": [
|
||||
"msgOutOfOrder",
|
||||
"{Device} is out of order!"
|
||||
],
|
||||
"key": "%s is out of order!",
|
||||
"message": "{Device} is out of order!",
|
||||
"translation": "",
|
||||
"comment": "FOO\n",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "Device",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "device"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:82: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": "golang.org/x/text/cmd/gotext/examples/extract/main.go:86:10"
|
||||
}
|
||||
]
|
||||
}
|
87
vendor/golang.org/x/text/cmd/gotext/examples/extract/main.go
generated
vendored
Normal file
87
vendor/golang.org/x/text/cmd/gotext/examples/extract/main.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
// 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
|
||||
|
||||
//go:generate gotext extract --lang=de,zh
|
||||
//go:generate gotext generate -out catalog.go
|
||||
|
||||
import (
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
)
|
||||
|
||||
func main() {
|
||||
p := message.NewPrinter(language.English)
|
||||
|
||||
p.Print("Hello world!\n")
|
||||
|
||||
p.Println("Hello", "world!")
|
||||
|
||||
person := "Sheila"
|
||||
place := "Zürich"
|
||||
|
||||
p.Print("Hello ", person, " in ", place, "!\n")
|
||||
|
||||
// Greet everyone.
|
||||
p.Printf("Hello world!\n")
|
||||
|
||||
city := "Amsterdam"
|
||||
// Greet a city.
|
||||
p.Printf("Hello %s!\n", city)
|
||||
|
||||
town := "Amsterdam"
|
||||
// Greet a town.
|
||||
p.Printf("Hello %s!\n",
|
||||
town, // Town
|
||||
)
|
||||
|
||||
// Person visiting a place.
|
||||
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.
|
||||
// argument is added as a placeholder.
|
||||
p.Printf("%[1]s is visiting %[3]s!\n", // Person visiting a place.
|
||||
pp.Person,
|
||||
pp.extra,
|
||||
pp.Place, // Place the person is visiting.
|
||||
)
|
||||
|
||||
// Numeric literal
|
||||
p.Printf("%d files remaining!", 2)
|
||||
|
||||
const n = 2
|
||||
|
||||
// Numeric var
|
||||
p.Printf("%d more files remaining!", n)
|
||||
|
||||
// Infer better names from type names.
|
||||
type referralCode int
|
||||
|
||||
const c = referralCode(5)
|
||||
p.Printf("Use the following code for your discount: %d\n", c)
|
||||
|
||||
// Using a constant for a message will cause the constant name to be
|
||||
// added as an identifier, allowing for stable message identifiers.
|
||||
|
||||
// Explain that a device is out of order.
|
||||
const msgOutOfOrder = "%s is out of order!" // FOO
|
||||
const device = "Soda machine"
|
||||
p.Printf(msgOutOfOrder, device)
|
||||
|
||||
// Double arguments.
|
||||
miles := 1.2345
|
||||
p.Printf("%.2[1]f miles traveled (%[1]f)", miles)
|
||||
}
|
39
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/locales/de/out.gotext.json
generated
vendored
Executable file
39
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/locales/de/out.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"language": "de",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello {From}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {From}!",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "From",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "r.Header.Get(\"From\")"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go:22:11"
|
||||
},
|
||||
{
|
||||
"id": "Do you like your browser ({User_Agent})?",
|
||||
"key": "Do you like your browser (%s)?\n",
|
||||
"message": "Do you like your browser ({User_Agent})?",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "User_Agent",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "r.Header.Get(\"User-Agent\")"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go:24:11"
|
||||
}
|
||||
]
|
||||
}
|
39
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/locales/en-US/out.gotext.json
generated
vendored
Executable file
39
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/locales/en-US/out.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"language": "en-US",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello {From}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {From}!",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "From",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "r.Header.Get(\"From\")"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go:22:11"
|
||||
},
|
||||
{
|
||||
"id": "Do you like your browser ({User_Agent})?",
|
||||
"key": "Do you like your browser (%s)?\n",
|
||||
"message": "Do you like your browser ({User_Agent})?",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "User_Agent",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "r.Header.Get(\"User-Agent\")"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go:24:11"
|
||||
}
|
||||
]
|
||||
}
|
39
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/locales/zh/out.gotext.json
generated
vendored
Executable file
39
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/locales/zh/out.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"language": "zh",
|
||||
"messages": [
|
||||
{
|
||||
"id": "Hello {From}!",
|
||||
"key": "Hello %s!\n",
|
||||
"message": "Hello {From}!",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "From",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "r.Header.Get(\"From\")"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go:22:11"
|
||||
},
|
||||
{
|
||||
"id": "Do you like your browser ({User_Agent})?",
|
||||
"key": "Do you like your browser (%s)?\n",
|
||||
"message": "Do you like your browser ({User_Agent})?",
|
||||
"translation": "",
|
||||
"placeholders": [
|
||||
{
|
||||
"id": "User_Agent",
|
||||
"string": "%[1]s",
|
||||
"type": "string",
|
||||
"underlyingType": "string",
|
||||
"argNum": 1,
|
||||
"expr": "r.Header.Get(\"User-Agent\")"
|
||||
}
|
||||
],
|
||||
"position": "golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go:24:11"
|
||||
}
|
||||
]
|
||||
}
|
17
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/main.go
generated
vendored
Normal file
17
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/main.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// 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
|
||||
|
||||
//go:generate gotext extract --lang=de,zh
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/text/cmd/gotext/examples/extract_http/pkg"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.Handle("/generize", http.HandlerFunc(pkg.Generize))
|
||||
}
|
25
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go
generated
vendored
Normal file
25
vendor/golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
// 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 pkg
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
)
|
||||
|
||||
var matcher = language.NewMatcher(message.DefaultCatalog.Languages())
|
||||
|
||||
func Generize(w http.ResponseWriter, r *http.Request) {
|
||||
lang, _ := r.Cookie("lang")
|
||||
accept := r.Header.Get("Accept-Language")
|
||||
tag := message.MatchLanguage(lang.String(), accept)
|
||||
p := message.NewPrinter(tag)
|
||||
|
||||
p.Fprintf(w, "Hello %s!\n", r.Header.Get("From"))
|
||||
|
||||
p.Fprintf(w, "Do you like your browser (%s)?\n", r.Header.Get("User-Agent"))
|
||||
}
|
37
vendor/golang.org/x/text/cmd/gotext/examples/rewrite/main.go
generated
vendored
Normal file
37
vendor/golang.org/x/text/cmd/gotext/examples/rewrite/main.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
// 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 (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var nPizzas = 4
|
||||
// The following call gets replaced by a call to the globally
|
||||
// defined printer.
|
||||
fmt.Println("We ate", nPizzas, "pizzas.")
|
||||
|
||||
p := message.NewPrinter(language.English)
|
||||
|
||||
// Prevent build failure, although it is okay for gotext.
|
||||
p.Println(1024)
|
||||
|
||||
// Replaced by a call to p.
|
||||
fmt.Println("Example punctuation:", "$%^&!")
|
||||
|
||||
{
|
||||
q := message.NewPrinter(language.French)
|
||||
|
||||
const leaveAnIdentBe = "Don't expand me."
|
||||
fmt.Print(leaveAnIdentBe)
|
||||
q.Println() // Prevent build failure, although it is okay for gotext.
|
||||
}
|
||||
|
||||
fmt.Printf("Hello %s\n", "City")
|
||||
}
|
16
vendor/golang.org/x/text/cmd/gotext/examples/rewrite/printer.go
generated
vendored
Normal file
16
vendor/golang.org/x/text/cmd/gotext/examples/rewrite/printer.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
// 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 ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
)
|
||||
|
||||
// The printer defined here will be picked up by the first print statement
|
||||
// in main.go.
|
||||
var printer = message.NewPrinter(language.English)
|
192
vendor/golang.org/x/text/cmd/gotext/extract.go
generated
vendored
192
vendor/golang.org/x/text/cmd/gotext/extract.go
generated
vendored
|
@ -5,22 +5,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"go/constant"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/types"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/loader"
|
||||
"golang.org/x/text/internal"
|
||||
"golang.org/x/text/message/pipeline"
|
||||
)
|
||||
|
||||
// TODO:
|
||||
|
@ -29,167 +20,44 @@ import (
|
|||
// - handle features (gender, plural)
|
||||
// - message rewriting
|
||||
|
||||
var (
|
||||
lang *string
|
||||
)
|
||||
|
||||
func init() {
|
||||
lang = cmdExtract.Flag.String("lang", "en-US", "comma-separated list of languages to process")
|
||||
}
|
||||
|
||||
var cmdExtract = &Command{
|
||||
Run: runExtract,
|
||||
UsageLine: "extract <package>*",
|
||||
Short: "extract strings to be translated from code",
|
||||
Short: "extracts strings to be translated from code",
|
||||
}
|
||||
|
||||
func runExtract(cmd *Command, args []string) error {
|
||||
if len(args) == 0 {
|
||||
args = []string{"."}
|
||||
}
|
||||
|
||||
conf := loader.Config{
|
||||
Build: &build.Default,
|
||||
ParserMode: parser.ParseComments,
|
||||
}
|
||||
|
||||
// Use the initial packages from the command line.
|
||||
args, err := conf.FromArgs(args, false)
|
||||
func runExtract(cmd *Command, config *pipeline.Config, args []string) error {
|
||||
config.Packages = args
|
||||
state, err := pipeline.Extract(config)
|
||||
if err != nil {
|
||||
return err
|
||||
return wrap(err, "extract failed")
|
||||
}
|
||||
out := state.Extracted
|
||||
|
||||
// Load, parse and type-check the whole program.
|
||||
iprog, err := conf.Load()
|
||||
if err != nil {
|
||||
return 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 translations []Translation
|
||||
|
||||
for _, info := range iprog.InitialPackages() {
|
||||
for _, f := range info.Files {
|
||||
// Associate comments with nodes.
|
||||
cmap := ast.NewCommentMap(iprog.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
|
||||
}
|
||||
|
||||
// argn is the index of the format string.
|
||||
argn, ok := m[meth.Obj().Name()]
|
||||
if !ok || argn >= len(call.Args) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Skip calls with non-constant format string.
|
||||
fmtstr := info.Types[call.Args[argn]].Value
|
||||
if fmtstr == nil || fmtstr.Kind() != constant.String {
|
||||
return true
|
||||
}
|
||||
|
||||
posn := conf.Fset.Position(call.Lparen)
|
||||
filepos := fmt.Sprintf("%s:%d:%d", filepath.Base(posn.Filename), posn.Line, posn.Column)
|
||||
|
||||
// TODO: identify the type of the format argument. If it is not
|
||||
// a string, multiple keys may be defined.
|
||||
var key []string
|
||||
|
||||
// TODO: replace substitutions (%v) with a translator friendly
|
||||
// notation. For instance:
|
||||
// "%d files remaining" -> "{numFiles} files remaining", or
|
||||
// "%d files remaining" -> "{arg1} files remaining"
|
||||
// Alternatively, this could be done at a later stage.
|
||||
msg := constant.StringVal(fmtstr)
|
||||
|
||||
// Construct a Translation unit.
|
||||
c := Translation{
|
||||
Key: key,
|
||||
Position: filepath.Join(info.Pkg.Path(), filepos),
|
||||
Original: Text{Msg: msg},
|
||||
ExtractedComment: getComment(call.Args[0]),
|
||||
// TODO(fix): this doesn't get the before comment.
|
||||
// Comment: getComment(call),
|
||||
}
|
||||
|
||||
for i, arg := range call.Args[argn+1:] {
|
||||
var val string
|
||||
if v := info.Types[arg].Value; v != nil {
|
||||
val = v.ExactString()
|
||||
}
|
||||
posn := conf.Fset.Position(arg.Pos())
|
||||
filepos := fmt.Sprintf("%s:%d:%d", filepath.Base(posn.Filename), posn.Line, posn.Column)
|
||||
c.Args = append(c.Args, Argument{
|
||||
ID: i + 1,
|
||||
Type: info.Types[arg].Type.String(),
|
||||
UnderlyingType: info.Types[arg].Type.Underlying().String(),
|
||||
Expr: print(arg),
|
||||
Value: val,
|
||||
Comment: getComment(arg),
|
||||
Position: filepath.Join(info.Pkg.Path(), filepos),
|
||||
// TODO report whether it implements
|
||||
// interfaces plural.Interface,
|
||||
// gender.Interface.
|
||||
})
|
||||
}
|
||||
|
||||
translations = append(translations, c)
|
||||
return true
|
||||
})
|
||||
langs := append(getLangs(), config.SourceLanguage)
|
||||
langs = internal.UniqueTags(langs)
|
||||
for _, tag := range langs {
|
||||
// TODO: inject translations from existing files to avoid retranslation.
|
||||
out.Language = tag
|
||||
data, err := json.MarshalIndent(out, "", " ")
|
||||
if err != nil {
|
||||
return wrap(err, "JSON marshal failed")
|
||||
}
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(translations, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, tag := range getLangs() {
|
||||
// TODO: merge with existing files, don't overwrite.
|
||||
os.MkdirAll(*dir, 0744)
|
||||
file := filepath.Join(*dir, fmt.Sprintf("gotext_%v.out.json", tag))
|
||||
if err := ioutil.WriteFile(file, data, 0744); err != nil {
|
||||
return fmt.Errorf("could not create file: %v", err)
|
||||
file := filepath.Join(*dir, tag.String(), outFile)
|
||||
if err := os.MkdirAll(filepath.Dir(file), 0750); err != nil {
|
||||
return wrap(err, "dir create failed")
|
||||
}
|
||||
if err := ioutil.WriteFile(file, data, 0740); err != nil {
|
||||
return wrap(err, "write failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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]int{
|
||||
// TODO: Printer -> *golang.org/x/text/message.Printer
|
||||
"message.Printer": {
|
||||
"Printf": 0,
|
||||
"Sprintf": 0,
|
||||
"Fprintf": 1,
|
||||
},
|
||||
}
|
||||
|
|
35
vendor/golang.org/x/text/cmd/gotext/generate.go
generated
vendored
Normal file
35
vendor/golang.org/x/text/cmd/gotext/generate.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// 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/pipeline"
|
||||
)
|
||||
|
||||
func init() {
|
||||
out = cmdGenerate.Flag.String("out", "", "output file to write to")
|
||||
}
|
||||
|
||||
var (
|
||||
out *string
|
||||
)
|
||||
|
||||
var cmdGenerate = &Command{
|
||||
Run: runGenerate,
|
||||
UsageLine: "generate <package>",
|
||||
Short: "generates code to insert translated messages",
|
||||
}
|
||||
|
||||
func runGenerate(cmd *Command, config *pipeline.Config, args []string) error {
|
||||
config.Packages = args
|
||||
s, err := pipeline.Extract(config)
|
||||
if err != nil {
|
||||
return wrap(err, "extraction failed")
|
||||
}
|
||||
if err := s.Import(); err != nil {
|
||||
return wrap(err, "import failed")
|
||||
}
|
||||
return wrap(s.Generate(), "generation failed")
|
||||
}
|
51
vendor/golang.org/x/text/cmd/gotext/main.go
generated
vendored
51
vendor/golang.org/x/text/cmd/gotext/main.go
generated
vendored
|
@ -25,6 +25,8 @@ import (
|
|||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/text/message/pipeline"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/tools/go/buildutil"
|
||||
)
|
||||
|
@ -34,10 +36,22 @@ func init() {
|
|||
}
|
||||
|
||||
var (
|
||||
dir = flag.String("dir", "textdata", "default subdirectory to store translation files")
|
||||
langs = flag.String("lang", "en", "comma-separated list of languages to process")
|
||||
srcLang = flag.String("srclang", "en-US", "the source-code language")
|
||||
dir = flag.String("dir", "locales", "default subdirectory to store translation files")
|
||||
)
|
||||
|
||||
func config() (*pipeline.Config, error) {
|
||||
tag, err := language.Parse(*srcLang)
|
||||
if err != nil {
|
||||
return nil, wrap(err, "invalid srclang")
|
||||
}
|
||||
return &pipeline.Config{
|
||||
SourceLanguage: tag,
|
||||
TranslationsPattern: `messages\.(.*)\.json`,
|
||||
GenFile: *out,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NOTE: the Command struct is copied from the go tool in core.
|
||||
|
||||
// A Command is an implementation of a go command
|
||||
|
@ -45,7 +59,7 @@ var (
|
|||
type Command struct {
|
||||
// Run runs the command.
|
||||
// The args are the arguments after the command name.
|
||||
Run func(cmd *Command, args []string) error
|
||||
Run func(cmd *Command, c *pipeline.Config, args []string) error
|
||||
|
||||
// UsageLine is the one-line usage message.
|
||||
// The first word in the line is taken to be the command name.
|
||||
|
@ -87,8 +101,9 @@ func (c *Command) Runnable() bool {
|
|||
// The order here is the order in which they are printed by 'go help'.
|
||||
var commands = []*Command{
|
||||
cmdExtract,
|
||||
cmdRewrite,
|
||||
cmdGenerate,
|
||||
// TODO:
|
||||
// - generate code from translations.
|
||||
// - update: full-cycle update of extraction, sending, and integration
|
||||
// - report: report of freshness of translations
|
||||
}
|
||||
|
@ -126,8 +141,12 @@ func main() {
|
|||
cmd.Flag.Usage = func() { cmd.Usage() }
|
||||
cmd.Flag.Parse(args[1:])
|
||||
args = cmd.Flag.Args()
|
||||
if err := cmd.Run(cmd, args); err != nil {
|
||||
fatalf("gotext: %v", err)
|
||||
config, err := config()
|
||||
if err != nil {
|
||||
fatalf("gotext: %+v", err)
|
||||
}
|
||||
if err := cmd.Run(cmd, config, args); err != nil {
|
||||
fatalf("gotext: %+v", err)
|
||||
}
|
||||
exit()
|
||||
return
|
||||
|
@ -277,12 +296,7 @@ func help(args []string) {
|
|||
if strings.HasSuffix(arg, "documentation") {
|
||||
w := &bytes.Buffer{}
|
||||
|
||||
fmt.Fprintln(w, "// Copyright 2016 The Go Authors. All rights reserved.")
|
||||
fmt.Fprintln(w, "// Use of this source code is governed by a BSD-style")
|
||||
fmt.Fprintln(w, "// license that can be found in the LICENSE file.")
|
||||
fmt.Fprintln(w)
|
||||
fmt.Fprintln(w, "// DO NOT EDIT THIS FILE. GENERATED BY go generate.")
|
||||
fmt.Fprintln(w, "// Edit the documentation in other files and rerun go generate to generate this one.")
|
||||
fmt.Fprintln(w, "// Code generated by go generate. DO NOT EDIT.")
|
||||
fmt.Fprintln(w)
|
||||
buf := new(bytes.Buffer)
|
||||
printUsage(buf)
|
||||
|
@ -292,10 +306,10 @@ func help(args []string) {
|
|||
if arg == "gendocumentation" {
|
||||
b, err := format.Source(w.Bytes())
|
||||
if err != nil {
|
||||
errorf("Could not format generated docs: %v\n", err)
|
||||
logf("Could not format generated docs: %v\n", err)
|
||||
}
|
||||
if err := ioutil.WriteFile("doc.go", b, 0666); err != nil {
|
||||
errorf("Could not create file alldocs.go: %v\n", err)
|
||||
logf("Could not create file alldocs.go: %v\n", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Println(w.String())
|
||||
|
@ -316,7 +330,10 @@ func help(args []string) {
|
|||
}
|
||||
|
||||
func getLangs() (tags []language.Tag) {
|
||||
for _, t := range strings.Split(*langs, ",") {
|
||||
for _, t := range strings.Split(*lang, ",") {
|
||||
if t == "" {
|
||||
continue
|
||||
}
|
||||
tag, err := language.Parse(t)
|
||||
if err != nil {
|
||||
fatalf("gotext: could not parse language %q: %v", t, err)
|
||||
|
@ -340,11 +357,11 @@ func exit() {
|
|||
}
|
||||
|
||||
func fatalf(format string, args ...interface{}) {
|
||||
errorf(format, args...)
|
||||
logf(format, args...)
|
||||
exit()
|
||||
}
|
||||
|
||||
func errorf(format string, args ...interface{}) {
|
||||
func logf(format string, args ...interface{}) {
|
||||
log.Printf(format, args...)
|
||||
setExitStatus(1)
|
||||
}
|
||||
|
|
127
vendor/golang.org/x/text/cmd/gotext/message.go
generated
vendored
127
vendor/golang.org/x/text/cmd/gotext/message.go
generated
vendored
|
@ -1,127 +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 main
|
||||
|
||||
// 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". A completed translation, expressed
|
||||
// in JS, for this format string could look like:
|
||||
//
|
||||
// {
|
||||
// "Key": [
|
||||
// "\"%d files(s) remaining\""
|
||||
// ],
|
||||
// "Original": {
|
||||
// "Msg": "\"%d files(s) remaining\""
|
||||
// },
|
||||
// "Translation": {
|
||||
// "Select": {
|
||||
// "Feature": "plural",
|
||||
// "Arg": 1,
|
||||
// "Case": {
|
||||
// "one": { "Msg": "1 file remaining" },
|
||||
// "other": { "Msg": "%d files remaining" }
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// "Args": [
|
||||
// {
|
||||
// "ID": 2,
|
||||
// "Type": "int",
|
||||
// "UnderlyingType": "int",
|
||||
// "Expr": "nFiles",
|
||||
// "Comment": "number of files remaining",
|
||||
// "Position": "golang.org/x/text/cmd/gotext/demo.go:34:3"
|
||||
// }
|
||||
// ],
|
||||
// "Position": "golang.org/x/text/cmd/gotext/demo.go:33:10",
|
||||
// }
|
||||
//
|
||||
// Alternatively, the Translation section could be written as:
|
||||
//
|
||||
// "Translation": {
|
||||
// "Msg": "%d %[files]s remaining",
|
||||
// "Var": {
|
||||
// "files" : {
|
||||
// "Select": {
|
||||
// "Feature": "plural",
|
||||
// "Arg": 1,
|
||||
// "Case": {
|
||||
// "one": { "Msg": "file" },
|
||||
// "other": { "Msg": "files" }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// A Translation describes a translation for a single language for a single
|
||||
// message.
|
||||
type Translation struct {
|
||||
// Key contains a list of identifiers for the message. If this list is empty
|
||||
// Original is used as the key.
|
||||
Key []string `json:"key,omitempty"`
|
||||
Original Text `json:"original"`
|
||||
Translation Text `json:"translation"`
|
||||
ExtractedComment string `json:"extractedComment,omitempty"`
|
||||
TranslatorComment string `json:"translatorComment,omitempty"`
|
||||
|
||||
Args []Argument `json:"args,omitempty"`
|
||||
|
||||
// Extraction information.
|
||||
Position string `json:"position,omitempty"` // filePosition:line
|
||||
}
|
||||
|
||||
// An Argument contains information about the arguments passed to a message.
|
||||
type Argument struct {
|
||||
ID interface{} `json:"id"` // An int for printf-style calls, but could be a string.
|
||||
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"`
|
||||
|
||||
// Features contains the features that are available for the implementation
|
||||
// of this argument.
|
||||
Features []Feature `json:"features,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. Within a Text value
|
||||
// either Msg or Select is defined.
|
||||
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"`
|
||||
}
|
||||
|
||||
// Type 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 variable or Feature type
|
||||
Arg interface{} `json:"arg"` // The argument ID.
|
||||
Cases map[string]Text `json:"cases"`
|
||||
}
|
55
vendor/golang.org/x/text/cmd/gotext/rewrite.go
generated
vendored
Normal file
55
vendor/golang.org/x/text/cmd/gotext/rewrite.go
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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 (
|
||||
"os"
|
||||
|
||||
"golang.org/x/text/message/pipeline"
|
||||
)
|
||||
|
||||
const printerType = "golang.org/x/text/message.Printer"
|
||||
|
||||
// TODO:
|
||||
// - merge information into existing files
|
||||
// - handle different file formats (PO, XLIFF)
|
||||
// - handle features (gender, plural)
|
||||
// - message rewriting
|
||||
|
||||
func init() {
|
||||
overwrite = cmdRewrite.Flag.Bool("w", false, "write files in place")
|
||||
}
|
||||
|
||||
var (
|
||||
overwrite *bool
|
||||
)
|
||||
|
||||
var cmdRewrite = &Command{
|
||||
Run: runRewrite,
|
||||
UsageLine: "rewrite <package>",
|
||||
Short: "rewrites fmt functions to use a message Printer",
|
||||
Long: `
|
||||
rewrite is typically done once for a project. It rewrites all usages of
|
||||
fmt to use x/text's message package whenever a message.Printer is in scope.
|
||||
It rewrites Print and Println calls with constant strings to the equivalent
|
||||
using Printf to allow translators to reorder arguments.
|
||||
`,
|
||||
}
|
||||
|
||||
func runRewrite(cmd *Command, _ *pipeline.Config, args []string) error {
|
||||
w := os.Stdout
|
||||
if *overwrite {
|
||||
w = nil
|
||||
}
|
||||
pkg := "."
|
||||
switch len(args) {
|
||||
case 0:
|
||||
case 1:
|
||||
pkg = args[0]
|
||||
default:
|
||||
return errorf("can only specify at most one package")
|
||||
}
|
||||
return pipeline.Rewrite(w, pkg)
|
||||
}
|
20
vendor/golang.org/x/text/collate/tools/colcmp/darwin.go
generated
vendored
20
vendor/golang.org/x/text/collate/tools/colcmp/darwin.go
generated
vendored
|
@ -39,13 +39,13 @@ type osxCollator struct {
|
|||
|
||||
func (c *osxCollator) init(locale string) {
|
||||
l := C.CFStringCreateWithBytes(
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
osxUInt8P([]byte(locale)),
|
||||
C.CFIndex(len(locale)),
|
||||
C.kCFStringEncodingUTF8,
|
||||
C.Boolean(0),
|
||||
)
|
||||
c.loc = C.CFLocaleCreate(nil, l)
|
||||
c.loc = C.CFLocaleCreate(C.kCFAllocatorDefault, l)
|
||||
}
|
||||
|
||||
func newOSX8Collator(locale string) (Collator, error) {
|
||||
|
@ -74,16 +74,16 @@ type osx16Collator struct {
|
|||
|
||||
func (c osx16Collator) Compare(a, b Input) int {
|
||||
sa := C.CFStringCreateWithCharactersNoCopy(
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
osxCharP(a.UTF16),
|
||||
C.CFIndex(len(a.UTF16)),
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
)
|
||||
sb := C.CFStringCreateWithCharactersNoCopy(
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
osxCharP(b.UTF16),
|
||||
C.CFIndex(len(b.UTF16)),
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
)
|
||||
_range := C.CFRangeMake(0, C.CFStringGetLength(sa))
|
||||
return int(C.CFStringCompareWithOptionsAndLocale(sa, sb, _range, c.opt, c.loc))
|
||||
|
@ -91,20 +91,20 @@ func (c osx16Collator) Compare(a, b Input) int {
|
|||
|
||||
func (c osx8Collator) Compare(a, b Input) int {
|
||||
sa := C.CFStringCreateWithBytesNoCopy(
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
osxUInt8P(a.UTF8),
|
||||
C.CFIndex(len(a.UTF8)),
|
||||
C.kCFStringEncodingUTF8,
|
||||
C.Boolean(0),
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
)
|
||||
sb := C.CFStringCreateWithBytesNoCopy(
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
osxUInt8P(b.UTF8),
|
||||
C.CFIndex(len(b.UTF8)),
|
||||
C.kCFStringEncodingUTF8,
|
||||
C.Boolean(0),
|
||||
nil,
|
||||
C.kCFAllocatorDefault,
|
||||
)
|
||||
_range := C.CFRangeMake(0, C.CFStringGetLength(sa))
|
||||
return int(C.CFStringCompareWithOptionsAndLocale(sa, sb, _range, c.opt, c.loc))
|
||||
|
|
1
vendor/golang.org/x/text/currency/common.go
generated
vendored
1
vendor/golang.org/x/text/currency/common.go
generated
vendored
|
@ -38,6 +38,7 @@ var roundings = [...]roundingType{
|
|||
{3, 1},
|
||||
{4, 1},
|
||||
{2, 5}, // cash rounding alternative
|
||||
{2, 50},
|
||||
}
|
||||
|
||||
// regionToCode returns a 16-bit region code. Only two-letter codes are
|
||||
|
|
4
vendor/golang.org/x/text/currency/currency_test.go
generated
vendored
4
vendor/golang.org/x/text/currency/currency_test.go
generated
vendored
|
@ -105,10 +105,10 @@ func TestTable(t *testing.T) {
|
|||
}
|
||||
// First currency has index 1, last is numCurrencies.
|
||||
if c := currency.Elem(1)[:3]; c != "ADP" {
|
||||
t.Errorf("first was %c; want ADP", c)
|
||||
t.Errorf("first was %q; want ADP", c)
|
||||
}
|
||||
if c := currency.Elem(numCurrencies)[:3]; c != "ZWR" {
|
||||
t.Errorf("last was %c; want ZWR", c)
|
||||
t.Errorf("last was %q; want ZWR", c)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
vendor/golang.org/x/text/currency/gen_common.go
generated
vendored
1
vendor/golang.org/x/text/currency/gen_common.go
generated
vendored
|
@ -42,6 +42,7 @@ var roundings = [...]roundingType{
|
|||
{3, 1},
|
||||
{4, 1},
|
||||
{2, 5}, // cash rounding alternative
|
||||
{2, 50},
|
||||
}
|
||||
|
||||
// regionToCode returns a 16-bit region code. Only two-letter codes are
|
||||
|
|
4729
vendor/golang.org/x/text/currency/tables.go
generated
vendored
4729
vendor/golang.org/x/text/currency/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
115
vendor/golang.org/x/text/feature/plural/data_test.go
generated
vendored
115
vendor/golang.org/x/text/feature/plural/data_test.go
generated
vendored
|
@ -9,8 +9,8 @@ type pluralTest struct {
|
|||
decimal []string
|
||||
}
|
||||
|
||||
var ordinalTests = []pluralTest{ // 59 elements
|
||||
0: {locales: "af am ar bg bs ce cs da de dsb el es et eu fa fi fy gl gsw he hr hsb id in is iw ja km kn ko ky lt lv ml mn my nb nl pa pl prg pt root ru sh si sk sl sr sw ta te th tr ur uz yue zh zu", form: 0, integer: []string{"0~15", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
var ordinalTests = []pluralTest{ // 66 elements
|
||||
0: {locales: "af am ar bg bs ce cs da de dsb el es et eu fa fi fy gl gsw he hr hsb id in is iw ja km kn ko ky lt lv ml mn my nb nl pa pl prg ps pt root ru sd sh si sk sl sr sw ta te th tr ur uz yue zh zu", form: 0, integer: []string{"0~15", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
1: {locales: "sv", form: 2, integer: []string{"1", "2", "21", "22", "31", "32", "41", "42", "51", "52", "61", "62", "71", "72", "81", "82", "101", "1001"}, decimal: []string(nil)},
|
||||
2: {locales: "sv", form: 0, integer: []string{"0", "3~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
3: {locales: "fil fr ga hy lo mo ms ro tl vi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
|
@ -23,53 +23,60 @@ var ordinalTests = []pluralTest{ // 59 elements
|
|||
10: {locales: "be", form: 0, integer: []string{"0", "1", "4~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
11: {locales: "uk", form: 4, integer: []string{"3", "23", "33", "43", "53", "63", "73", "83", "103", "1003"}, decimal: []string(nil)},
|
||||
12: {locales: "uk", form: 0, integer: []string{"0~2", "4~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
13: {locales: "kk", form: 5, integer: []string{"6", "9", "10", "16", "19", "20", "26", "29", "30", "36", "39", "40", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
14: {locales: "kk", form: 0, integer: []string{"0~5", "7", "8", "11~15", "17", "18", "21", "101", "1001"}, decimal: []string(nil)},
|
||||
15: {locales: "it", form: 5, integer: []string{"8", "11", "80", "800"}, decimal: []string(nil)},
|
||||
16: {locales: "it", form: 0, integer: []string{"0~7", "9", "10", "12~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
17: {locales: "ka", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
18: {locales: "ka", form: 5, integer: []string{"0", "2~16", "102", "1002"}, decimal: []string(nil)},
|
||||
19: {locales: "ka", form: 0, integer: []string{"21~36", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
20: {locales: "sq", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
21: {locales: "sq", form: 5, integer: []string{"4", "24", "34", "44", "54", "64", "74", "84", "104", "1004"}, decimal: []string(nil)},
|
||||
22: {locales: "sq", form: 0, integer: []string{"0", "2", "3", "5~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
23: {locales: "en", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
|
||||
24: {locales: "en", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "72", "82", "102", "1002"}, decimal: []string(nil)},
|
||||
25: {locales: "en", form: 4, integer: []string{"3", "23", "33", "43", "53", "63", "73", "83", "103", "1003"}, decimal: []string(nil)},
|
||||
26: {locales: "en", form: 0, integer: []string{"0", "4~18", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
27: {locales: "mr", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
28: {locales: "mr", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
|
||||
29: {locales: "mr", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
30: {locales: "mr", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
31: {locales: "ca", form: 2, integer: []string{"1", "3"}, decimal: []string(nil)},
|
||||
32: {locales: "ca", form: 3, integer: []string{"2"}, decimal: []string(nil)},
|
||||
33: {locales: "ca", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
34: {locales: "ca", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
35: {locales: "mk", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
|
||||
36: {locales: "mk", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "72", "82", "102", "1002"}, decimal: []string(nil)},
|
||||
37: {locales: "mk", form: 5, integer: []string{"7", "8", "27", "28", "37", "38", "47", "48", "57", "58", "67", "68", "77", "78", "87", "88", "107", "1007"}, decimal: []string(nil)},
|
||||
38: {locales: "mk", form: 0, integer: []string{"0", "3~6", "9~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
39: {locales: "az", form: 2, integer: []string{"1", "2", "5", "7", "8", "11", "12", "15", "17", "18", "20~22", "25", "101", "1001"}, decimal: []string(nil)},
|
||||
40: {locales: "az", form: 4, integer: []string{"3", "4", "13", "14", "23", "24", "33", "34", "43", "44", "53", "54", "63", "64", "73", "74", "100", "1003"}, decimal: []string(nil)},
|
||||
41: {locales: "az", form: 5, integer: []string{"0", "6", "16", "26", "36", "40", "46", "56", "106", "1006"}, decimal: []string(nil)},
|
||||
42: {locales: "az", form: 0, integer: []string{"9", "10", "19", "29", "30", "39", "49", "59", "69", "79", "109", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
43: {locales: "gu hi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
44: {locales: "gu hi", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
|
||||
45: {locales: "gu hi", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
46: {locales: "gu hi", form: 5, integer: []string{"6"}, decimal: []string(nil)},
|
||||
47: {locales: "gu hi", form: 0, integer: []string{"0", "5", "7~20", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
48: {locales: "as bn", form: 2, integer: []string{"1", "5", "7~10"}, decimal: []string(nil)},
|
||||
49: {locales: "as bn", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
|
||||
50: {locales: "as bn", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
51: {locales: "as bn", form: 5, integer: []string{"6"}, decimal: []string(nil)},
|
||||
52: {locales: "as bn", form: 0, integer: []string{"0", "11~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
53: {locales: "cy", form: 1, integer: []string{"0", "7~9"}, decimal: []string(nil)},
|
||||
54: {locales: "cy", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
55: {locales: "cy", form: 3, integer: []string{"2"}, decimal: []string(nil)},
|
||||
56: {locales: "cy", form: 4, integer: []string{"3", "4"}, decimal: []string(nil)},
|
||||
57: {locales: "cy", form: 5, integer: []string{"5", "6"}, decimal: []string(nil)},
|
||||
58: {locales: "cy", form: 0, integer: []string{"10~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
} // Size: 4272 bytes
|
||||
13: {locales: "tk", form: 4, integer: []string{"6", "9", "10", "16", "19", "26", "29", "36", "39", "106", "1006"}, decimal: []string(nil)},
|
||||
14: {locales: "tk", form: 0, integer: []string{"0~5", "7", "8", "11~15", "17", "18", "20", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
15: {locales: "kk", form: 5, integer: []string{"6", "9", "10", "16", "19", "20", "26", "29", "30", "36", "39", "40", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
16: {locales: "kk", form: 0, integer: []string{"0~5", "7", "8", "11~15", "17", "18", "21", "101", "1001"}, decimal: []string(nil)},
|
||||
17: {locales: "it", form: 5, integer: []string{"8", "11", "80", "800"}, decimal: []string(nil)},
|
||||
18: {locales: "it", form: 0, integer: []string{"0~7", "9", "10", "12~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
19: {locales: "ka", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
20: {locales: "ka", form: 5, integer: []string{"0", "2~16", "102", "1002"}, decimal: []string(nil)},
|
||||
21: {locales: "ka", form: 0, integer: []string{"21~36", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
22: {locales: "sq", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
23: {locales: "sq", form: 5, integer: []string{"4", "24", "34", "44", "54", "64", "74", "84", "104", "1004"}, decimal: []string(nil)},
|
||||
24: {locales: "sq", form: 0, integer: []string{"0", "2", "3", "5~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
25: {locales: "en", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
|
||||
26: {locales: "en", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "72", "82", "102", "1002"}, decimal: []string(nil)},
|
||||
27: {locales: "en", form: 4, integer: []string{"3", "23", "33", "43", "53", "63", "73", "83", "103", "1003"}, decimal: []string(nil)},
|
||||
28: {locales: "en", form: 0, integer: []string{"0", "4~18", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
29: {locales: "mr", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
30: {locales: "mr", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
|
||||
31: {locales: "mr", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
32: {locales: "mr", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
33: {locales: "ca", form: 2, integer: []string{"1", "3"}, decimal: []string(nil)},
|
||||
34: {locales: "ca", form: 3, integer: []string{"2"}, decimal: []string(nil)},
|
||||
35: {locales: "ca", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
36: {locales: "ca", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
37: {locales: "mk", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
|
||||
38: {locales: "mk", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "72", "82", "102", "1002"}, decimal: []string(nil)},
|
||||
39: {locales: "mk", form: 5, integer: []string{"7", "8", "27", "28", "37", "38", "47", "48", "57", "58", "67", "68", "77", "78", "87", "88", "107", "1007"}, decimal: []string(nil)},
|
||||
40: {locales: "mk", form: 0, integer: []string{"0", "3~6", "9~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
41: {locales: "az", form: 2, integer: []string{"1", "2", "5", "7", "8", "11", "12", "15", "17", "18", "20~22", "25", "101", "1001"}, decimal: []string(nil)},
|
||||
42: {locales: "az", form: 4, integer: []string{"3", "4", "13", "14", "23", "24", "33", "34", "43", "44", "53", "54", "63", "64", "73", "74", "100", "1003"}, decimal: []string(nil)},
|
||||
43: {locales: "az", form: 5, integer: []string{"0", "6", "16", "26", "36", "40", "46", "56", "106", "1006"}, decimal: []string(nil)},
|
||||
44: {locales: "az", form: 0, integer: []string{"9", "10", "19", "29", "30", "39", "49", "59", "69", "79", "109", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
45: {locales: "gu hi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
46: {locales: "gu hi", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
|
||||
47: {locales: "gu hi", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
48: {locales: "gu hi", form: 5, integer: []string{"6"}, decimal: []string(nil)},
|
||||
49: {locales: "gu hi", form: 0, integer: []string{"0", "5", "7~20", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
50: {locales: "as bn", form: 2, integer: []string{"1", "5", "7~10"}, decimal: []string(nil)},
|
||||
51: {locales: "as bn", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
|
||||
52: {locales: "as bn", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
53: {locales: "as bn", form: 5, integer: []string{"6"}, decimal: []string(nil)},
|
||||
54: {locales: "as bn", form: 0, integer: []string{"0", "11~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
55: {locales: "or", form: 2, integer: []string{"1", "5", "7~9"}, decimal: []string(nil)},
|
||||
56: {locales: "or", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
|
||||
57: {locales: "or", form: 4, integer: []string{"4"}, decimal: []string(nil)},
|
||||
58: {locales: "or", form: 5, integer: []string{"6"}, decimal: []string(nil)},
|
||||
59: {locales: "or", form: 0, integer: []string{"0", "10~24", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
60: {locales: "cy", form: 1, integer: []string{"0", "7~9"}, decimal: []string(nil)},
|
||||
61: {locales: "cy", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
62: {locales: "cy", form: 3, integer: []string{"2"}, decimal: []string(nil)},
|
||||
63: {locales: "cy", form: 4, integer: []string{"3", "4"}, decimal: []string(nil)},
|
||||
64: {locales: "cy", form: 5, integer: []string{"5", "6"}, decimal: []string(nil)},
|
||||
65: {locales: "cy", form: 0, integer: []string{"10~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
|
||||
} // Size: 4776 bytes
|
||||
|
||||
var cardinalTests = []pluralTest{ // 113 elements
|
||||
0: {locales: "bm bo dz id ig ii in ja jbo jv jw kde kea km ko lkt lo ms my nqo root sah ses sg th to vi wo yo yue zh", form: 0, integer: []string{"0~15", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
|
@ -79,16 +86,16 @@ var cardinalTests = []pluralTest{ // 113 elements
|
|||
4: {locales: "ff fr hy kab", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"2.0~3.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
5: {locales: "pt", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0~1.5"}},
|
||||
6: {locales: "pt", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"2.0~3.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
7: {locales: "ast ca de en et fi fy gl it ji nl sv sw ur yi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
8: {locales: "ast ca de en et fi fy gl it ji nl sv sw ur yi", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
7: {locales: "ast ca de en et fi fy gl io it ji nl pt_PT sv sw ur yi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
|
||||
8: {locales: "ast ca de en et fi fy gl io it ji nl pt_PT sv sw ur yi", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
9: {locales: "si", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0", "0.1", "1.0", "0.00", "0.01", "1.00", "0.000", "0.001", "1.000", "0.0000", "0.0001", "1.0000"}},
|
||||
10: {locales: "si", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.2~0.9", "1.1~1.8", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
11: {locales: "ak bh guw ln mg nso pa ti wa", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0", "1.0", "0.00", "1.00", "0.000", "1.000", "0.0000", "1.0000"}},
|
||||
12: {locales: "ak bh guw ln mg nso pa ti wa", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
13: {locales: "tzm", form: 2, integer: []string{"0", "1", "11~24"}, decimal: []string{"0.0", "1.0", "11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "19.0", "20.0", "21.0", "22.0", "23.0", "24.0"}},
|
||||
14: {locales: "tzm", form: 0, integer: []string{"2~10", "100~106", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
15: {locales: "af asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
|
||||
16: {locales: "af asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
15: {locales: "af asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sd sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
|
||||
16: {locales: "af asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sd sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
17: {locales: "da", form: 2, integer: []string{"1"}, decimal: []string{"0.1~1.6"}},
|
||||
18: {locales: "da", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "2.0~3.4", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
19: {locales: "is", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"0.1~1.6", "10.1", "100.1", "1000.1"}},
|
||||
|
@ -187,4 +194,4 @@ var cardinalTests = []pluralTest{ // 113 elements
|
|||
112: {locales: "cy", form: 0, integer: []string{"4", "5", "7~20", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
|
||||
} // Size: 8160 bytes
|
||||
|
||||
// Total table size 12432 bytes (12KiB); checksum: 166DAB71
|
||||
// Total table size 12936 bytes (12KiB); checksum: 8456DC5D
|
||||
|
|
0
vendor/golang.org/x/text/feature/plural/message.go
generated
vendored
Executable file → Normal file
0
vendor/golang.org/x/text/feature/plural/message.go
generated
vendored
Executable file → Normal file
398
vendor/golang.org/x/text/feature/plural/tables.go
generated
vendored
398
vendor/golang.org/x/text/feature/plural/tables.go
generated
vendored
|
@ -3,9 +3,9 @@
|
|||
package plural
|
||||
|
||||
// CLDRVersion is the CLDR version from which the tables in this package are derived.
|
||||
const CLDRVersion = "31"
|
||||
const CLDRVersion = "32"
|
||||
|
||||
var ordinalRules = []pluralCheck{ // 58 elements
|
||||
var ordinalRules = []pluralCheck{ // 64 elements
|
||||
0: {cat: 0x2f, setID: 0x4},
|
||||
1: {cat: 0x3a, setID: 0x5},
|
||||
2: {cat: 0x22, setID: 0x1},
|
||||
|
@ -15,148 +15,154 @@ var ordinalRules = []pluralCheck{ // 58 elements
|
|||
6: {cat: 0x3c, setID: 0x9},
|
||||
7: {cat: 0x2f, setID: 0xa},
|
||||
8: {cat: 0x3c, setID: 0xb},
|
||||
9: {cat: 0x2d, setID: 0xc},
|
||||
10: {cat: 0x2d, setID: 0xd},
|
||||
11: {cat: 0x2f, setID: 0xe},
|
||||
12: {cat: 0x35, setID: 0x3},
|
||||
13: {cat: 0xc5, setID: 0xf},
|
||||
14: {cat: 0x2, setID: 0x1},
|
||||
15: {cat: 0x5, setID: 0x3},
|
||||
16: {cat: 0xd, setID: 0x10},
|
||||
17: {cat: 0x22, setID: 0x1},
|
||||
18: {cat: 0x2f, setID: 0x11},
|
||||
19: {cat: 0x3d, setID: 0x12},
|
||||
9: {cat: 0x2c, setID: 0xc},
|
||||
10: {cat: 0x24, setID: 0xd},
|
||||
11: {cat: 0x2d, setID: 0xe},
|
||||
12: {cat: 0x2d, setID: 0xf},
|
||||
13: {cat: 0x2f, setID: 0x10},
|
||||
14: {cat: 0x35, setID: 0x3},
|
||||
15: {cat: 0xc5, setID: 0x11},
|
||||
16: {cat: 0x2, setID: 0x1},
|
||||
17: {cat: 0x5, setID: 0x3},
|
||||
18: {cat: 0xd, setID: 0x12},
|
||||
19: {cat: 0x22, setID: 0x1},
|
||||
20: {cat: 0x2f, setID: 0x13},
|
||||
21: {cat: 0x3a, setID: 0x14},
|
||||
21: {cat: 0x3d, setID: 0x14},
|
||||
22: {cat: 0x2f, setID: 0x15},
|
||||
23: {cat: 0x3b, setID: 0x16},
|
||||
24: {cat: 0x2f, setID: 0xa},
|
||||
25: {cat: 0x3c, setID: 0xb},
|
||||
26: {cat: 0x22, setID: 0x1},
|
||||
27: {cat: 0x23, setID: 0x17},
|
||||
28: {cat: 0x24, setID: 0x18},
|
||||
29: {cat: 0x22, setID: 0x19},
|
||||
30: {cat: 0x23, setID: 0x2},
|
||||
31: {cat: 0x24, setID: 0x18},
|
||||
32: {cat: 0xf, setID: 0x13},
|
||||
33: {cat: 0x1a, setID: 0x14},
|
||||
23: {cat: 0x3a, setID: 0x16},
|
||||
24: {cat: 0x2f, setID: 0x17},
|
||||
25: {cat: 0x3b, setID: 0x18},
|
||||
26: {cat: 0x2f, setID: 0xa},
|
||||
27: {cat: 0x3c, setID: 0xb},
|
||||
28: {cat: 0x22, setID: 0x1},
|
||||
29: {cat: 0x23, setID: 0x19},
|
||||
30: {cat: 0x24, setID: 0x1a},
|
||||
31: {cat: 0x22, setID: 0x1b},
|
||||
32: {cat: 0x23, setID: 0x2},
|
||||
33: {cat: 0x24, setID: 0x1a},
|
||||
34: {cat: 0xf, setID: 0x15},
|
||||
35: {cat: 0x1b, setID: 0x16},
|
||||
36: {cat: 0xf, setID: 0x1a},
|
||||
37: {cat: 0x1d, setID: 0x1b},
|
||||
38: {cat: 0xa, setID: 0x1c},
|
||||
39: {cat: 0xa, setID: 0x1d},
|
||||
40: {cat: 0xc, setID: 0x1e},
|
||||
41: {cat: 0xe4, setID: 0x0},
|
||||
42: {cat: 0x5, setID: 0x3},
|
||||
43: {cat: 0xd, setID: 0xc},
|
||||
44: {cat: 0xd, setID: 0x1f},
|
||||
45: {cat: 0x22, setID: 0x1},
|
||||
46: {cat: 0x23, setID: 0x17},
|
||||
47: {cat: 0x24, setID: 0x18},
|
||||
48: {cat: 0x25, setID: 0x20},
|
||||
49: {cat: 0x22, setID: 0x21},
|
||||
50: {cat: 0x23, setID: 0x17},
|
||||
51: {cat: 0x24, setID: 0x18},
|
||||
52: {cat: 0x25, setID: 0x20},
|
||||
53: {cat: 0x21, setID: 0x22},
|
||||
54: {cat: 0x22, setID: 0x1},
|
||||
55: {cat: 0x23, setID: 0x2},
|
||||
56: {cat: 0x24, setID: 0x23},
|
||||
57: {cat: 0x25, setID: 0x24},
|
||||
} // Size: 140 bytes
|
||||
35: {cat: 0x1a, setID: 0x16},
|
||||
36: {cat: 0xf, setID: 0x17},
|
||||
37: {cat: 0x1b, setID: 0x18},
|
||||
38: {cat: 0xf, setID: 0x1c},
|
||||
39: {cat: 0x1d, setID: 0x1d},
|
||||
40: {cat: 0xa, setID: 0x1e},
|
||||
41: {cat: 0xa, setID: 0x1f},
|
||||
42: {cat: 0xc, setID: 0x20},
|
||||
43: {cat: 0xe4, setID: 0x0},
|
||||
44: {cat: 0x5, setID: 0x3},
|
||||
45: {cat: 0xd, setID: 0xe},
|
||||
46: {cat: 0xd, setID: 0x21},
|
||||
47: {cat: 0x22, setID: 0x1},
|
||||
48: {cat: 0x23, setID: 0x19},
|
||||
49: {cat: 0x24, setID: 0x1a},
|
||||
50: {cat: 0x25, setID: 0x22},
|
||||
51: {cat: 0x22, setID: 0x23},
|
||||
52: {cat: 0x23, setID: 0x19},
|
||||
53: {cat: 0x24, setID: 0x1a},
|
||||
54: {cat: 0x25, setID: 0x22},
|
||||
55: {cat: 0x22, setID: 0x24},
|
||||
56: {cat: 0x23, setID: 0x19},
|
||||
57: {cat: 0x24, setID: 0x1a},
|
||||
58: {cat: 0x25, setID: 0x22},
|
||||
59: {cat: 0x21, setID: 0x25},
|
||||
60: {cat: 0x22, setID: 0x1},
|
||||
61: {cat: 0x23, setID: 0x2},
|
||||
62: {cat: 0x24, setID: 0x26},
|
||||
63: {cat: 0x25, setID: 0x27},
|
||||
} // Size: 152 bytes
|
||||
|
||||
var ordinalIndex = []uint8{ // 20 elements
|
||||
var ordinalIndex = []uint8{ // 22 elements
|
||||
0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x07, 0x09,
|
||||
0x0d, 0x0e, 0x11, 0x14, 0x1a, 0x1d, 0x20, 0x26,
|
||||
0x2d, 0x31, 0x35, 0x3a,
|
||||
} // Size: 44 bytes
|
||||
0x0b, 0x0f, 0x10, 0x13, 0x16, 0x1c, 0x1f, 0x22,
|
||||
0x28, 0x2f, 0x33, 0x37, 0x3b, 0x40,
|
||||
} // Size: 46 bytes
|
||||
|
||||
var ordinalLangToIndex = []uint8{ // 754 elements
|
||||
var ordinalLangToIndex = []uint8{ // 768 elements
|
||||
// Entry 0 - 3F
|
||||
0x00, 0x0d, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x05,
|
||||
0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x05,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 40 - 7F
|
||||
0x00, 0x00, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x00, 0x00,
|
||||
0x00, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 80 - BF
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
// Entry C0 - FF
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
// Entry C0 - FF
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 100 - 13F
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
|
||||
0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
// Entry 140 - 17F
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x02,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x03, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 180 - 1BF
|
||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09,
|
||||
0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 1C0 - 1FF
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x02, 0x02,
|
||||
0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0d, 0x0d, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 200 - 23F
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 240 - 27F
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -164,57 +170,58 @@ var ordinalLangToIndex = []uint8{ // 754 elements
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 280 - 2BF
|
||||
0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
|
||||
0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00,
|
||||
// Entry 2C0 - 2FF
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
} // Size: 778 bytes
|
||||
} // Size: 792 bytes
|
||||
|
||||
var ordinalInclusionMasks = []uint64{ // 100 elements
|
||||
// Entry 0 - 1F
|
||||
0x0000000400004009, 0x00000002120800d3, 0x0000000010a10195, 0x0000000842810581,
|
||||
0x0000000841030081, 0x0000001210010041, 0x0000001100011001, 0x0000000614010001,
|
||||
0x0000000614018001, 0x0000000600012001, 0x0000000200014001, 0x0000000010198031,
|
||||
0x0000000010610331, 0x0000000040010f01, 0x0000000040070001, 0x0000000010010001,
|
||||
0x0000000000011001, 0x000000001c010001, 0x000000001c010001, 0x0000000000012001,
|
||||
0x0000000020014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
|
||||
0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
|
||||
0x0000000014000001, 0x0000000000002001, 0x0000000000004001, 0x0000000010080011,
|
||||
0x0000002000010009, 0x00000018482000d3, 0x0000000042840195, 0x000000410a040581,
|
||||
0x00000041040c0081, 0x0000009840040041, 0x0000008400045001, 0x0000003850040001,
|
||||
0x0000003850060001, 0x0000003800049001, 0x0000000800052001, 0x0000000040660031,
|
||||
0x0000000041840331, 0x0000000100040f01, 0x00000001001c0001, 0x0000000040040001,
|
||||
0x0000000000045001, 0x0000000070040001, 0x0000000070040001, 0x0000000000049001,
|
||||
0x0000000080050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501,
|
||||
0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001,
|
||||
0x0000000050000001, 0x0000000000009001, 0x0000000000010001, 0x0000000040200011,
|
||||
// Entry 20 - 3F
|
||||
0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
|
||||
0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
|
||||
0x0000000080014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
|
||||
0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
|
||||
0x0000000014000001, 0x0000000000002001, 0x0000000020004001, 0x0000000010080011,
|
||||
0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
|
||||
0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
|
||||
0x0000000080014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
|
||||
0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001,
|
||||
0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001,
|
||||
0x0000000200050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501,
|
||||
0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001,
|
||||
0x0000000050000001, 0x0000000000009001, 0x0000000080010001, 0x0000000040200011,
|
||||
0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001,
|
||||
0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001,
|
||||
0x0000000200050001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501,
|
||||
// Entry 40 - 5F
|
||||
0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
|
||||
0x0000000014000001, 0x0000000000002001, 0x0000000020004001, 0x0000000010080011,
|
||||
0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
|
||||
0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
|
||||
0x000000002001c001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
|
||||
0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
|
||||
0x0000000014000001, 0x0000000000002001, 0x0000000080004001, 0x0000000010080011,
|
||||
0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
|
||||
0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001,
|
||||
0x0000000050000001, 0x0000000000009001, 0x0000000080010001, 0x0000000040200011,
|
||||
0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001,
|
||||
0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001,
|
||||
0x0000000080070001, 0x0000000040200011, 0x0000000040800111, 0x0000000100000501,
|
||||
0x0000000100080001, 0x0000000040000001, 0x0000000000005001, 0x0000000050000001,
|
||||
0x0000000050000001, 0x0000000000009001, 0x0000000200010001, 0x0000000040200011,
|
||||
0x0000000040800111, 0x0000000100000501, 0x0000000100080001, 0x0000000040000001,
|
||||
// Entry 60 - 7F
|
||||
0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
|
||||
0x0000000000005001, 0x0000000050000001, 0x0000000050000001, 0x0000000000009001,
|
||||
} // Size: 824 bytes
|
||||
|
||||
// Slots used for ordinal: 3A of 0xFF rules; 14 of 0xFF indexes; 37 of 64 sets
|
||||
// Slots used for ordinal: 40 of 0xFF rules; 16 of 0xFF indexes; 40 of 64 sets
|
||||
|
||||
var cardinalRules = []pluralCheck{ // 166 elements
|
||||
0: {cat: 0x2, setID: 0x3},
|
||||
|
@ -393,7 +400,7 @@ var cardinalIndex = []uint8{ // 36 elements
|
|||
0x95, 0x9c, 0xa1, 0xa6,
|
||||
} // Size: 60 bytes
|
||||
|
||||
var cardinalLangToIndex = []uint8{ // 754 elements
|
||||
var cardinalLangToIndex = []uint8{ // 768 elements
|
||||
// Entry 0 - 3F
|
||||
0x00, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
0x06, 0x06, 0x01, 0x01, 0x21, 0x21, 0x21, 0x21,
|
||||
|
@ -406,14 +413,14 @@ var cardinalLangToIndex = []uint8{ // 754 elements
|
|||
// Entry 40 - 7F
|
||||
0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||
0x1e, 0x1e, 0x08, 0x08, 0x13, 0x00, 0x00, 0x13,
|
||||
0x13, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18,
|
||||
0x18, 0x00, 0x00, 0x22, 0x22, 0x09, 0x09, 0x09,
|
||||
0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x00, 0x00, 0x16, 0x16, 0x00, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x13, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
|
||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x18, 0x18, 0x00, 0x00, 0x22, 0x22,
|
||||
0x09, 0x09, 0x09, 0x00, 0x00, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x16,
|
||||
0x16, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 80 - BF
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
|
@ -427,81 +434,82 @@ var cardinalLangToIndex = []uint8{ // 754 elements
|
|||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
// Entry 100 - 13F
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x08,
|
||||
0x08, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x04, 0x04, 0x0c, 0x0c, 0x08,
|
||||
0x08, 0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x04, 0x04, 0x08, 0x08, 0x00, 0x00, 0x01, 0x01,
|
||||
0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04,
|
||||
0x0c, 0x0c, 0x08, 0x08, 0x08, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
// Entry 140 - 17F
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x08, 0x08, 0x04, 0x04, 0x1f, 0x1f, 0x14,
|
||||
0x14, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x01,
|
||||
0x01, 0x06, 0x00, 0x00, 0x20, 0x20, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x17, 0x17, 0x01, 0x01,
|
||||
0x13, 0x13, 0x13, 0x16, 0x16, 0x08, 0x08, 0x02,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
|
||||
0x02, 0x02, 0x02, 0x02, 0x08, 0x08, 0x04, 0x04,
|
||||
0x1f, 0x1f, 0x14, 0x14, 0x04, 0x04, 0x08, 0x08,
|
||||
0x08, 0x08, 0x01, 0x01, 0x06, 0x00, 0x00, 0x20,
|
||||
0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x17,
|
||||
0x17, 0x01, 0x01, 0x13, 0x13, 0x13, 0x16, 0x16,
|
||||
0x08, 0x08, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
// Entry 180 - 1BF
|
||||
0x0a, 0x04, 0x04, 0x04, 0x04, 0x04, 0x10, 0x00,
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08,
|
||||
0x08, 0x02, 0x02, 0x08, 0x00, 0x00, 0x08, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0f, 0x0f,
|
||||
0x08, 0x10, 0x10, 0x08, 0x08, 0x0e, 0x0e, 0x08,
|
||||
0x00, 0x00, 0x04, 0x0a, 0x0a, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08,
|
||||
0x08, 0x08, 0x00, 0x08, 0x08, 0x02, 0x02, 0x08,
|
||||
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x0f, 0x0f, 0x08, 0x10, 0x10, 0x08,
|
||||
// Entry 1C0 - 1FF
|
||||
0x08, 0x08, 0x08, 0x00, 0x00, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
|
||||
0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x0d, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x06, 0x00, 0x00, 0x08, 0x08, 0x0b, 0x0b,
|
||||
0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x08, 0x10, 0x10, 0x08, 0x08, 0x08,
|
||||
0x08, 0x0e, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x00,
|
||||
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0d, 0x0d, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00,
|
||||
0x08, 0x08, 0x0b, 0x0b, 0x08, 0x08, 0x08, 0x08,
|
||||
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
|
||||
// Entry 200 - 23F
|
||||
0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
|
||||
0x08, 0x06, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x06,
|
||||
0x00, 0x00, 0x06, 0x06, 0x08, 0x19, 0x19, 0x0d,
|
||||
0x0d, 0x08, 0x08, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
0x00, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x00, 0x08, 0x06, 0x00, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x06, 0x00, 0x00, 0x06, 0x06,
|
||||
0x08, 0x19, 0x19, 0x0d, 0x0d, 0x08, 0x08, 0x03,
|
||||
0x04, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
// Entry 240 - 27F
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
|
||||
0x12, 0x12, 0x12, 0x08, 0x08, 0x1d, 0x1d, 0x1d,
|
||||
0x1d, 0x1d, 0x1d, 0x1d, 0x00, 0x00, 0x08, 0x08,
|
||||
0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x10,
|
||||
0x10, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x11, 0x00, 0x00, 0x11, 0x11, 0x05, 0x05,
|
||||
0x18, 0x18, 0x15, 0x15, 0x10, 0x10, 0x10, 0x10,
|
||||
0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x08, 0x00, 0x00, 0x12, 0x12, 0x12, 0x08,
|
||||
0x08, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
|
||||
0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08,
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10,
|
||||
0x10, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x11,
|
||||
0x00, 0x00, 0x11, 0x11, 0x05, 0x05, 0x18, 0x18,
|
||||
0x15, 0x15, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
// Entry 280 - 2BF
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x13, 0x13, 0x13,
|
||||
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
|
||||
0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x13, 0x13, 0x13, 0x13, 0x13,
|
||||
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x08, 0x08,
|
||||
0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x06, 0x06, 0x06, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
0x07, 0x07, 0x08, 0x08, 0x1d, 0x1d, 0x04, 0x04,
|
||||
// Entry 2C0 - 2FF
|
||||
0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x00,
|
||||
0x08, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00,
|
||||
0x00, 0x00, 0x07, 0x07, 0x08, 0x08, 0x1d, 0x1d,
|
||||
0x04, 0x04, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08,
|
||||
0x08, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01,
|
||||
} // Size: 778 bytes
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
|
||||
} // Size: 792 bytes
|
||||
|
||||
var cardinalInclusionMasks = []uint64{ // 100 elements
|
||||
// Entry 0 - 1F
|
||||
|
@ -537,4 +545,4 @@ var cardinalInclusionMasks = []uint64{ // 100 elements
|
|||
|
||||
// Slots used for cardinal: A6 of 0xFF rules; 24 of 0xFF indexes; 37 of 64 sets
|
||||
|
||||
// Total table size 3804 bytes (3KiB); checksum: FFC009FC
|
||||
// Total table size 3846 bytes (3KiB); checksum: B8556665
|
||||
|
|
9
vendor/golang.org/x/text/gen.go
generated
vendored
9
vendor/golang.org/x/text/gen.go
generated
vendored
|
@ -117,14 +117,15 @@ pkg unicode, var <new script or property> *RangeTable
|
|||
width = generate("./width", unicode)
|
||||
bidi = generate("./unicode/bidi", unicode, norm, rangetable)
|
||||
mib = generate("./encoding/internal/identifier", unicode)
|
||||
number = generate("./internal/number", unicode, cldr, language, internal)
|
||||
_ = generate("./encoding/htmlindex", unicode, language, mib)
|
||||
_ = generate("./encoding/ianaindex", unicode, language, mib)
|
||||
_ = generate("./secure/precis", unicode, norm, rangetable, cases, width, bidi)
|
||||
_ = generate("./currency", unicode, cldr, language, internal)
|
||||
_ = generate("./internal/number", unicode, cldr, language, internal)
|
||||
_ = generate("./feature/plural", unicode, cldr, language, internal)
|
||||
_ = generate("./internal/cldrtree", language)
|
||||
_ = generate("./currency", unicode, cldr, language, internal, number)
|
||||
_ = generate("./feature/plural", unicode, cldr, language, internal, number)
|
||||
_ = generate("./internal/export/idna", unicode, bidi, norm)
|
||||
_ = generate("./language/display", unicode, cldr, language, internal)
|
||||
_ = generate("./language/display", unicode, cldr, language, internal, number)
|
||||
_ = generate("./collate", unicode, norm, cldr, language, rangetable)
|
||||
_ = generate("./search", unicode, norm, cldr, language, rangetable)
|
||||
)
|
||||
|
|
67
vendor/golang.org/x/text/internal/catmsg/catmsg.go
generated
vendored
67
vendor/golang.org/x/text/internal/catmsg/catmsg.go
generated
vendored
|
@ -74,13 +74,6 @@ import (
|
|||
// A Handle refers to a registered message type.
|
||||
type Handle int
|
||||
|
||||
// First is used as a Handle to EncodeMessageType, followed by a series of calls
|
||||
// to EncodeMessage, to implement selecting the first matching Message.
|
||||
//
|
||||
// TODO: this can be removed once we either can use type aliases or if the
|
||||
// internals of this package are merged with the catalog package.
|
||||
var First Handle = msgFirst
|
||||
|
||||
// A Handler decodes and evaluates data compiled by a Message and sends the
|
||||
// result to the Decoder. The output may depend on the value of the substitution
|
||||
// arguments, accessible by the Decoder's Arg method. The Handler returns false
|
||||
|
@ -111,20 +104,24 @@ const (
|
|||
msgFirst
|
||||
msgRaw
|
||||
msgString
|
||||
numFixed
|
||||
msgAffix
|
||||
// Leave some arbitrary room for future expansion: 20 should suffice.
|
||||
numInternal = 20
|
||||
)
|
||||
|
||||
const prefix = "golang.org/x/text/internal/catmsg."
|
||||
|
||||
var (
|
||||
// TODO: find a more stable way to link handles to message types.
|
||||
mutex sync.Mutex
|
||||
names = map[string]Handle{
|
||||
prefix + "Vars": msgVars,
|
||||
prefix + "First": msgFirst,
|
||||
prefix + "Raw": msgRaw,
|
||||
prefix + "String": msgString,
|
||||
prefix + "Affix": msgAffix,
|
||||
}
|
||||
handlers = make([]Handler, numFixed)
|
||||
handlers = make([]Handler, numInternal)
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -168,6 +165,20 @@ func init() {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
handlers[msgAffix] = func(d *Decoder) bool {
|
||||
// TODO: use an alternative method for common cases.
|
||||
prefix := d.DecodeString()
|
||||
suffix := d.DecodeString()
|
||||
if prefix != "" {
|
||||
d.Render(prefix)
|
||||
}
|
||||
ret := d.ExecuteMessage()
|
||||
if suffix != "" {
|
||||
d.Render(suffix)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -236,6 +247,23 @@ func Compile(tag language.Tag, macros Dictionary, m Message) (data string, err e
|
|||
return string(buf), err
|
||||
}
|
||||
|
||||
// FirstOf is a message type that prints the first message in the sequence that
|
||||
// resolves to a match for the given substitution arguments.
|
||||
type FirstOf []Message
|
||||
|
||||
// Compile implements Message.
|
||||
func (s FirstOf) Compile(e *Encoder) error {
|
||||
e.EncodeMessageType(msgFirst)
|
||||
err := ErrIncomplete
|
||||
for i, m := range s {
|
||||
if err == nil {
|
||||
return fmt.Errorf("catalog: message argument %d is complete and blocks subsequent messages", i-1)
|
||||
}
|
||||
err = e.EncodeMessage(m)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Var defines a message that can be substituted for a placeholder of the same
|
||||
// name. If an expression does not result in a string after evaluation, Name is
|
||||
// used as the substitution. For example:
|
||||
|
@ -364,3 +392,24 @@ func (s String) Compile(e *Encoder) (err error) {
|
|||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Affix is a message that adds a prefix and suffix to another message.
|
||||
// This is mostly used add back whitespace to a translation that was stripped
|
||||
// before sending it out.
|
||||
type Affix struct {
|
||||
Message Message
|
||||
Prefix string
|
||||
Suffix string
|
||||
}
|
||||
|
||||
// Compile implements Message.
|
||||
func (a Affix) Compile(e *Encoder) (err error) {
|
||||
// TODO: consider adding a special message type that just adds a single
|
||||
// return. This is probably common enough to handle the majority of cases.
|
||||
// Get some stats first, though.
|
||||
e.EncodeMessageType(msgAffix)
|
||||
e.EncodeString(a.Prefix)
|
||||
e.EncodeString(a.Suffix)
|
||||
e.EncodeMessage(a.Message)
|
||||
return nil
|
||||
}
|
||||
|
|
15
vendor/golang.org/x/text/internal/catmsg/catmsg_test.go
generated
vendored
15
vendor/golang.org/x/text/internal/catmsg/catmsg_test.go
generated
vendored
|
@ -70,6 +70,10 @@ func TestCodec(t *testing.T) {
|
|||
desc: "simple string",
|
||||
m: String("foo"),
|
||||
tests: single("foo", ""),
|
||||
}, {
|
||||
desc: "affix",
|
||||
m: &Affix{String("foo"), "\t", "\n"},
|
||||
tests: single("\t|foo|\n", ""),
|
||||
}, {
|
||||
desc: "missing var",
|
||||
m: String("foo${bar}"),
|
||||
|
@ -100,6 +104,13 @@ func TestCodec(t *testing.T) {
|
|||
String("foo${bar}"),
|
||||
},
|
||||
tests: single("foo|baz", ""),
|
||||
}, {
|
||||
desc: "affix with substitution",
|
||||
m: &Affix{seq{
|
||||
&Var{"bar", String("baz")},
|
||||
String("foo${bar}"),
|
||||
}, "\t", "\n"},
|
||||
tests: single("\t|foo|baz|\n", ""),
|
||||
}, {
|
||||
desc: "shadowed variable",
|
||||
m: seq{
|
||||
|
@ -140,7 +151,7 @@ func TestCodec(t *testing.T) {
|
|||
&Var{"bar", incomplete{}},
|
||||
String("${bar}"),
|
||||
},
|
||||
enc: "\x00\t\b\x01\x01\x04\x04\x02bar\x03\x00\x00\x00",
|
||||
enc: "\x00\t\b\x01\x01\x14\x04\x02bar\x03\x00\x00\x00",
|
||||
// TODO: recognize that it is cheaper to substitute bar.
|
||||
tests: single("bar", ""),
|
||||
}, {
|
||||
|
@ -246,7 +257,7 @@ type seq []Message
|
|||
|
||||
func (s seq) Compile(e *Encoder) (err error) {
|
||||
err = ErrIncomplete
|
||||
e.EncodeMessageType(First)
|
||||
e.EncodeMessageType(msgFirst)
|
||||
for _, m := range s {
|
||||
// Pass only the last error, but allow erroneous or complete messages
|
||||
// here to allow testing different scenarios.
|
||||
|
|
2
vendor/golang.org/x/text/internal/catmsg/codec.go
generated
vendored
Executable file → Normal file
2
vendor/golang.org/x/text/internal/catmsg/codec.go
generated
vendored
Executable file → Normal file
|
@ -169,7 +169,7 @@ func (e *Encoder) addVar(key string, m Message) error {
|
|||
case err == ErrIncomplete:
|
||||
if Handle(e.buf[0]) != msgFirst {
|
||||
seq := &Encoder{root: e.root, parent: e}
|
||||
seq.EncodeMessageType(First)
|
||||
seq.EncodeMessageType(msgFirst)
|
||||
e.flushTo(seq)
|
||||
e = seq
|
||||
}
|
||||
|
|
2
vendor/golang.org/x/text/internal/cldrtree/cldrtree.go
generated
vendored
2
vendor/golang.org/x/text/internal/cldrtree/cldrtree.go
generated
vendored
|
@ -7,6 +7,8 @@
|
|||
//
|
||||
package cldrtree
|
||||
|
||||
//go:generate go test -gen
|
||||
|
||||
// cldrtree stores CLDR data in a tree-like structure called Tree. In the CLDR
|
||||
// data each branch in the tree is indicated by either an element name or an
|
||||
// attribute value. A Tree does not distinguish between these two cases, but
|
||||
|
|
2
vendor/golang.org/x/text/internal/cldrtree/cldrtree_test.go
generated
vendored
2
vendor/golang.org/x/text/internal/cldrtree/cldrtree_test.go
generated
vendored
|
@ -448,7 +448,7 @@ func loadTestdata(t *testing.T, test string) (tree *Tree, file []byte) {
|
|||
generate(b, tree, w)
|
||||
generateTestData(b, w)
|
||||
buf := &bytes.Buffer{}
|
||||
if _, err = w.WriteGo(buf, "test"); err != nil {
|
||||
if _, err = w.WriteGo(buf, "test", ""); err != nil {
|
||||
t.Log(buf.String())
|
||||
t.Fatal("error generating code:", err)
|
||||
}
|
||||
|
|
9
vendor/golang.org/x/text/internal/cldrtree/testdata/test1/output.go
generated
vendored
Executable file → Normal file
9
vendor/golang.org/x/text/internal/cldrtree/testdata/test1/output.go
generated
vendored
Executable file → Normal file
|
@ -58,7 +58,7 @@ const (
|
|||
leap7 month = 0 // leap7
|
||||
)
|
||||
|
||||
var locales = []uint32{ // 754 elements
|
||||
var locales = []uint32{ // 768 elements
|
||||
// Entry 0 - 1F
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
|
@ -271,7 +271,10 @@ var locales = []uint32{ // 754 elements
|
|||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
} // Size: xxxx bytes
|
||||
|
||||
var indices = []uint16{ // 86 elements
|
||||
|
@ -344,4 +347,4 @@ var enumMap = map[string]uint16{
|
|||
"leap7": 0,
|
||||
}
|
||||
|
||||
// Total table size: xxxx bytes (4KiB); checksum: DFE9E450
|
||||
// Total table size: xxxx bytes (4KiB); checksum: EB82B0F5
|
||||
|
|
37
vendor/golang.org/x/text/internal/cldrtree/testdata/test2/output.go
generated
vendored
Executable file → Normal file
37
vendor/golang.org/x/text/internal/cldrtree/testdata/test2/output.go
generated
vendored
Executable file → Normal file
|
@ -149,7 +149,7 @@ const (
|
|||
two = 2 // two
|
||||
)
|
||||
|
||||
var locales = []uint32{ // 754 elements
|
||||
var locales = []uint32{ // 768 elements
|
||||
// Entry 0 - 1F
|
||||
0x00000000, 0x00000000, 0x0000027a, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
|
@ -188,37 +188,37 @@ var locales = []uint32{ // 754 elements
|
|||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
// Entry 80 - 9F
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x0000027a, 0x0000037f, 0x0000037f,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x0000027a, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000027a, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000027a, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000027a,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
// Entry A0 - BF
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x000003dd, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000027a, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x000003dd,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000027a, 0x0000037f, 0x0000027a, 0x0000037f,
|
||||
// Entry C0 - DF
|
||||
0x0000037f, 0x0000027a, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000027a,
|
||||
// Entry C0 - DF
|
||||
0x0000037f, 0x0000027a, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000027a, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
// Entry E0 - FF
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000027a, 0x0000027a, 0x0000037f, 0x0000037f,
|
||||
0x0000027a, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x0000037f, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000027a,
|
||||
0x0000027a, 0x0000037f, 0x0000037f, 0x0000027a,
|
||||
0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
|
||||
0x0000037f, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
|
@ -362,7 +362,10 @@ var locales = []uint32{ // 754 elements
|
|||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
} // Size: xxxx bytes
|
||||
|
||||
var indices = []uint16{ // 1070 elements
|
||||
|
@ -883,4 +886,4 @@ var enumMap = map[string]uint16{
|
|||
"two": 2,
|
||||
}
|
||||
|
||||
// Total table size: xxxx bytes (14KiB); checksum: FE165D0A
|
||||
// Total table size: xxxx bytes (14KiB); checksum: 4BFC5D9
|
||||
|
|
2
vendor/golang.org/x/text/internal/export/idna/gen.go
generated
vendored
2
vendor/golang.org/x/text/internal/export/idna/gen.go
generated
vendored
|
@ -100,7 +100,7 @@ func genTables() {
|
|||
})
|
||||
|
||||
w := gen.NewCodeWriter()
|
||||
defer w.WriteGoFile("tables.go", "idna")
|
||||
defer w.WriteVersionedGoFile("tables.go", "idna")
|
||||
|
||||
gen.WriteUnicodeVersion(w)
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.10
|
||||
|
||||
package idna
|
||||
|
||||
import (
|
84
vendor/golang.org/x/text/internal/export/idna/gen9.0.0_test.go
generated
vendored
Normal file
84
vendor/golang.org/x/text/internal/export/idna/gen9.0.0_test.go
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
// 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.
|
||||
|
||||
// +build !go1.10
|
||||
|
||||
package idna
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/text/internal/gen"
|
||||
"golang.org/x/text/internal/testtext"
|
||||
"golang.org/x/text/internal/ucd"
|
||||
)
|
||||
|
||||
func TestTables(t *testing.T) {
|
||||
testtext.SkipIfNotLong(t)
|
||||
|
||||
lookup := func(r rune) info {
|
||||
v, _ := trie.lookupString(string(r))
|
||||
return info(v)
|
||||
}
|
||||
|
||||
ucd.Parse(gen.OpenUnicodeFile("idna", "", "IdnaMappingTable.txt"), func(p *ucd.Parser) {
|
||||
r := p.Rune(0)
|
||||
x := lookup(r)
|
||||
if got, want := x.category(), catFromEntry(p); got != want {
|
||||
t.Errorf("%U:category: got %x; want %x", r, got, want)
|
||||
}
|
||||
|
||||
mapped := false
|
||||
switch p.String(1) {
|
||||
case "mapped", "disallowed_STD3_mapped", "deviation":
|
||||
mapped = true
|
||||
}
|
||||
if x.isMapped() != mapped {
|
||||
t.Errorf("%U:isMapped: got %v; want %v", r, x.isMapped(), mapped)
|
||||
}
|
||||
if !mapped {
|
||||
return
|
||||
}
|
||||
want := string(p.Runes(2))
|
||||
got := string(x.appendMapping(nil, string(r)))
|
||||
if got != want {
|
||||
t.Errorf("%U:mapping: got %+q; want %+q", r, got, want)
|
||||
}
|
||||
|
||||
if x.isMapped() {
|
||||
return
|
||||
}
|
||||
wantMark := unicode.In(r, unicode.Mark)
|
||||
gotMark := x.isModifier()
|
||||
if gotMark != wantMark {
|
||||
t.Errorf("IsMark(%U) = %v; want %v", r, gotMark, wantMark)
|
||||
}
|
||||
})
|
||||
|
||||
ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) {
|
||||
r := p.Rune(0)
|
||||
x := lookup(r)
|
||||
got := x.isViramaModifier()
|
||||
|
||||
const cccVirama = 9
|
||||
want := p.Int(ucd.CanonicalCombiningClass) == cccVirama
|
||||
if got != want {
|
||||
t.Errorf("IsVirama(%U) = %v; want %v", r, got, want)
|
||||
}
|
||||
})
|
||||
|
||||
ucd.Parse(gen.OpenUCDFile("extracted/DerivedJoiningType.txt"), func(p *ucd.Parser) {
|
||||
r := p.Rune(0)
|
||||
x := lookup(r)
|
||||
if x.isMapped() {
|
||||
return
|
||||
}
|
||||
got := x.joinType()
|
||||
want := joinType[p.String(1)]
|
||||
if got != want {
|
||||
t.Errorf("JoinType(%U) = %x; want %x", r, got, want)
|
||||
}
|
||||
})
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.10
|
||||
//go:generate go run gen.go gen_trieval.go gen_common.go
|
||||
|
||||
// Package idna implements IDNA2008 using the compatibility processing
|
140
vendor/golang.org/x/text/internal/export/idna/idna10.0.0_test.go
generated
vendored
Normal file
140
vendor/golang.org/x/text/internal/export/idna/idna10.0.0_test.go
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
|||
// 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.
|
||||
|
||||
// +build go1.10
|
||||
|
||||
package idna
|
||||
|
||||
import "testing"
|
||||
|
||||
// TestLabelErrors tests strings returned in case of error. All results should
|
||||
// be identical to the reference implementation and can be verified at
|
||||
// http://unicode.org/cldr/utility/idna.jsp. The reference implementation,
|
||||
// however, seems to not display Bidi and ContextJ errors.
|
||||
//
|
||||
// In some cases the behavior of browsers is added as a comment. In all cases,
|
||||
// whenever a resolve search returns an error here, Chrome will treat the input
|
||||
// string as a search string (including those for Bidi and Context J errors),
|
||||
// unless noted otherwise.
|
||||
func TestLabelErrors(t *testing.T) {
|
||||
encode := func(s string) string { s, _ = encode(acePrefix, s); return s }
|
||||
type kind struct {
|
||||
name string
|
||||
f func(string) (string, error)
|
||||
}
|
||||
punyA := kind{"PunycodeA", punycode.ToASCII}
|
||||
resolve := kind{"ResolveA", Lookup.ToASCII}
|
||||
display := kind{"ToUnicode", Display.ToUnicode}
|
||||
p := New(VerifyDNSLength(true), MapForLookup(), BidiRule())
|
||||
lengthU := kind{"CheckLengthU", p.ToUnicode}
|
||||
lengthA := kind{"CheckLengthA", p.ToASCII}
|
||||
p = New(MapForLookup(), StrictDomainName(false))
|
||||
std3 := kind{"STD3", p.ToASCII}
|
||||
|
||||
testCases := []struct {
|
||||
kind
|
||||
input string
|
||||
want string
|
||||
wantErr string
|
||||
}{
|
||||
{lengthU, "", "", "A4"}, // From UTS 46 conformance test.
|
||||
{lengthA, "", "", "A4"},
|
||||
|
||||
{lengthU, "xn--", "", "A4"},
|
||||
{lengthU, "foo.xn--", "foo.", "A4"}, // TODO: is dropping xn-- correct?
|
||||
{lengthU, "xn--.foo", ".foo", "A4"},
|
||||
{lengthU, "foo.xn--.bar", "foo..bar", "A4"},
|
||||
|
||||
{display, "xn--", "", ""},
|
||||
{display, "foo.xn--", "foo.", ""}, // TODO: is dropping xn-- correct?
|
||||
{display, "xn--.foo", ".foo", ""},
|
||||
{display, "foo.xn--.bar", "foo..bar", ""},
|
||||
|
||||
{lengthA, "a..b", "a..b", "A4"},
|
||||
{punyA, ".b", ".b", ""},
|
||||
// For backwards compatibility, the Punycode profile does not map runes.
|
||||
{punyA, "\u3002b", "xn--b-83t", ""},
|
||||
{punyA, "..b", "..b", ""},
|
||||
|
||||
{lengthA, ".b", ".b", "A4"},
|
||||
{lengthA, "\u3002b", ".b", "A4"},
|
||||
{lengthA, "..b", "..b", "A4"},
|
||||
{lengthA, "b..", "b..", ""},
|
||||
|
||||
// Sharpened Bidi rules for Unicode 10.0.0. Apply for ALL labels in ANY
|
||||
// of the labels is RTL.
|
||||
{lengthA, "\ufe05\u3002\u3002\U0002603e\u1ce0", "..xn--t6f5138v", "A4"},
|
||||
{lengthA, "FAX\u2a77\U0001d186\u3002\U0001e942\U000e0181\u180c", "", "B6"},
|
||||
|
||||
{resolve, "a..b", "a..b", ""},
|
||||
// Note that leading dots are not stripped. This is to be consistent
|
||||
// with the Punycode profile as well as the conformance test.
|
||||
{resolve, ".b", ".b", ""},
|
||||
{resolve, "\u3002b", ".b", ""},
|
||||
{resolve, "..b", "..b", ""},
|
||||
{resolve, "b..", "b..", ""},
|
||||
{resolve, "\xed", "", "P1"},
|
||||
|
||||
// Raw punycode
|
||||
{punyA, "", "", ""},
|
||||
{punyA, "*.foo.com", "*.foo.com", ""},
|
||||
{punyA, "Foo.com", "Foo.com", ""},
|
||||
|
||||
// STD3 rules
|
||||
{display, "*.foo.com", "*.foo.com", "P1"},
|
||||
{std3, "*.foo.com", "*.foo.com", ""},
|
||||
|
||||
// Don't map U+2490 (DIGIT NINE FULL STOP). This is the behavior of
|
||||
// Chrome, Safari, and IE. Firefox will first map ⒐ to 9. and return
|
||||
// lab9.be.
|
||||
{resolve, "lab⒐be", "xn--labbe-zh9b", "P1"}, // encode("lab⒐be")
|
||||
{display, "lab⒐be", "lab⒐be", "P1"},
|
||||
|
||||
{resolve, "plan⒐faß.de", "xn--planfass-c31e.de", "P1"}, // encode("plan⒐fass") + ".de"
|
||||
{display, "Plan⒐faß.de", "plan⒐faß.de", "P1"},
|
||||
|
||||
// Chrome 54.0 recognizes the error and treats this input verbatim as a
|
||||
// search string.
|
||||
// Safari 10.0 (non-conform spec) decomposes "⒈" and computes the
|
||||
// punycode on the result using transitional mapping.
|
||||
// Firefox 49.0.1 goes haywire on this string and prints a bunch of what
|
||||
// seems to be nested punycode encodings.
|
||||
{resolve, "日本⒈co.ßßß.de", "xn--co-wuw5954azlb.ssssss.de", "P1"},
|
||||
{display, "日本⒈co.ßßß.de", "日本⒈co.ßßß.de", "P1"},
|
||||
|
||||
{resolve, "a\u200Cb", "ab", ""},
|
||||
{display, "a\u200Cb", "a\u200Cb", "C"},
|
||||
|
||||
{resolve, encode("a\u200Cb"), encode("a\u200Cb"), "C"},
|
||||
{display, "a\u200Cb", "a\u200Cb", "C"},
|
||||
|
||||
{resolve, "grﻋﺮﺑﻲ.de", "xn--gr-gtd9a1b0g.de", "B"},
|
||||
{
|
||||
// Notice how the string gets transformed, even with an error.
|
||||
// Chrome will use the original string if it finds an error, so not
|
||||
// the transformed one.
|
||||
display,
|
||||
"gr\ufecb\ufeae\ufe91\ufef2.de",
|
||||
"gr\u0639\u0631\u0628\u064a.de",
|
||||
"B",
|
||||
},
|
||||
|
||||
{resolve, "\u0671.\u03c3\u07dc", "xn--qib.xn--4xa21s", "B"}, // ٱ.σߜ
|
||||
{display, "\u0671.\u03c3\u07dc", "\u0671.\u03c3\u07dc", "B"},
|
||||
|
||||
// normalize input
|
||||
{resolve, "a\u0323\u0322", "xn--jta191l", ""}, // ạ̢
|
||||
{display, "a\u0323\u0322", "\u1ea1\u0322", ""},
|
||||
|
||||
// Non-normalized strings are not normalized when they originate from
|
||||
// punycode. Despite the error, Chrome, Safari and Firefox will attempt
|
||||
// to look up the input punycode.
|
||||
{resolve, encode("a\u0323\u0322") + ".com", "xn--a-tdbc.com", "V1"},
|
||||
{display, encode("a\u0323\u0322") + ".com", "a\u0323\u0322.com", "V1"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
doTest(t, tc.f, tc.name, tc.input, tc.want, tc.wantErr)
|
||||
}
|
||||
}
|
681
vendor/golang.org/x/text/internal/export/idna/idna9.0.0.go
generated
vendored
Normal file
681
vendor/golang.org/x/text/internal/export/idna/idna9.0.0.go
generated
vendored
Normal file
|
@ -0,0 +1,681 @@
|
|||
// 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.
|
||||
|
||||
// +build !go1.10
|
||||
//go:generate go run gen.go gen_trieval.go gen_common.go
|
||||
|
||||
// Package idna implements IDNA2008 using the compatibility processing
|
||||
// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
|
||||
// deal with the transition from IDNA2003.
|
||||
//
|
||||
// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC
|
||||
// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.
|
||||
// UTS #46 is defined in http://www.unicode.org/reports/tr46.
|
||||
// See http://unicode.org/cldr/utility/idna.jsp for a visualization of the
|
||||
// differences between these two standards.
|
||||
package idna // import "golang.org/x/text/internal/export/idna"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/text/secure/bidirule"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
||||
// NOTE: Unlike common practice in Go APIs, the functions will return a
|
||||
// sanitized domain name in case of errors. Browsers sometimes use a partially
|
||||
// evaluated string as lookup.
|
||||
// TODO: the current error handling is, in my opinion, the least opinionated.
|
||||
// Other strategies are also viable, though:
|
||||
// Option 1) Return an empty string in case of error, but allow the user to
|
||||
// specify explicitly which errors to ignore.
|
||||
// Option 2) Return the partially evaluated string if it is itself a valid
|
||||
// string, otherwise return the empty string in case of error.
|
||||
// Option 3) Option 1 and 2.
|
||||
// Option 4) Always return an empty string for now and implement Option 1 as
|
||||
// needed, and document that the return string may not be empty in case of
|
||||
// error in the future.
|
||||
// I think Option 1 is best, but it is quite opinionated.
|
||||
|
||||
// ToASCII is a wrapper for Punycode.ToASCII.
|
||||
func ToASCII(s string) (string, error) {
|
||||
return Punycode.process(s, true)
|
||||
}
|
||||
|
||||
// ToUnicode is a wrapper for Punycode.ToUnicode.
|
||||
func ToUnicode(s string) (string, error) {
|
||||
return Punycode.process(s, false)
|
||||
}
|
||||
|
||||
// An Option configures a Profile at creation time.
|
||||
type Option func(*options)
|
||||
|
||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||
// compatibility. It is used by most browsers when resolving domain names. This
|
||||
// option is only meaningful if combined with MapForLookup.
|
||||
func Transitional(transitional bool) Option {
|
||||
return func(o *options) { o.transitional = true }
|
||||
}
|
||||
|
||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||
// are longer than allowed by the RFC.
|
||||
func VerifyDNSLength(verify bool) Option {
|
||||
return func(o *options) { o.verifyDNSLength = verify }
|
||||
}
|
||||
|
||||
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
||||
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
||||
//
|
||||
// This is the behavior suggested by the UTS #46 and is adopted by some
|
||||
// browsers.
|
||||
func RemoveLeadingDots(remove bool) Option {
|
||||
return func(o *options) { o.removeLeadingDots = remove }
|
||||
}
|
||||
|
||||
// ValidateLabels sets whether to check the mandatory label validation criteria
|
||||
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
||||
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
||||
func ValidateLabels(enable bool) Option {
|
||||
return func(o *options) {
|
||||
// Don't override existing mappings, but set one that at least checks
|
||||
// normalization if it is not set.
|
||||
if o.mapping == nil && enable {
|
||||
o.mapping = normalize
|
||||
}
|
||||
o.trie = trie
|
||||
o.validateLabels = enable
|
||||
o.fromPuny = validateFromPunycode
|
||||
}
|
||||
}
|
||||
|
||||
// StrictDomainName limits the set of permissable ASCII characters to those
|
||||
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
||||
// hyphen). This is set by default for MapForLookup and ValidateForRegistration.
|
||||
//
|
||||
// This option is useful, for instance, for browsers that allow characters
|
||||
// outside this range, for example a '_' (U+005F LOW LINE). See
|
||||
// http://www.rfc-editor.org/std/std3.txt for more details This option
|
||||
// corresponds to the UseSTD3ASCIIRules option in UTS #46.
|
||||
func StrictDomainName(use bool) Option {
|
||||
return func(o *options) {
|
||||
o.trie = trie
|
||||
o.useSTD3Rules = use
|
||||
o.fromPuny = validateFromPunycode
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: the following options pull in tables. The tables should not be linked
|
||||
// in as long as the options are not used.
|
||||
|
||||
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
||||
// that relies on proper validation of labels should include this rule.
|
||||
func BidiRule() Option {
|
||||
return func(o *options) { o.bidirule = bidirule.ValidString }
|
||||
}
|
||||
|
||||
// ValidateForRegistration sets validation options to verify that a given IDN is
|
||||
// properly formatted for registration as defined by Section 4 of RFC 5891.
|
||||
func ValidateForRegistration() Option {
|
||||
return func(o *options) {
|
||||
o.mapping = validateRegistration
|
||||
StrictDomainName(true)(o)
|
||||
ValidateLabels(true)(o)
|
||||
VerifyDNSLength(true)(o)
|
||||
BidiRule()(o)
|
||||
}
|
||||
}
|
||||
|
||||
// MapForLookup sets validation and mapping options such that a given IDN is
|
||||
// transformed for domain name lookup according to the requirements set out in
|
||||
// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,
|
||||
// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option
|
||||
// to add this check.
|
||||
//
|
||||
// The mappings include normalization and mapping case, width and other
|
||||
// compatibility mappings.
|
||||
func MapForLookup() Option {
|
||||
return func(o *options) {
|
||||
o.mapping = validateAndMap
|
||||
StrictDomainName(true)(o)
|
||||
ValidateLabels(true)(o)
|
||||
RemoveLeadingDots(true)(o)
|
||||
}
|
||||
}
|
||||
|
||||
type options struct {
|
||||
transitional bool
|
||||
useSTD3Rules bool
|
||||
validateLabels bool
|
||||
verifyDNSLength bool
|
||||
removeLeadingDots bool
|
||||
|
||||
trie *idnaTrie
|
||||
|
||||
// fromPuny calls validation rules when converting A-labels to U-labels.
|
||||
fromPuny func(p *Profile, s string) error
|
||||
|
||||
// mapping implements a validation and mapping step as defined in RFC 5895
|
||||
// or UTS 46, tailored to, for example, domain registration or lookup.
|
||||
mapping func(p *Profile, s string) (string, error)
|
||||
|
||||
// bidirule, if specified, checks whether s conforms to the Bidi Rule
|
||||
// defined in RFC 5893.
|
||||
bidirule func(s string) bool
|
||||
}
|
||||
|
||||
// A Profile defines the configuration of a IDNA mapper.
|
||||
type Profile struct {
|
||||
options
|
||||
}
|
||||
|
||||
func apply(o *options, opts []Option) {
|
||||
for _, f := range opts {
|
||||
f(o)
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new Profile.
|
||||
//
|
||||
// With no options, the returned Profile is the most permissive and equals the
|
||||
// Punycode Profile. Options can be passed to further restrict the Profile. The
|
||||
// MapForLookup and ValidateForRegistration options set a collection of options,
|
||||
// for lookup and registration purposes respectively, which can be tailored by
|
||||
// adding more fine-grained options, where later options override earlier
|
||||
// options.
|
||||
func New(o ...Option) *Profile {
|
||||
p := &Profile{}
|
||||
apply(&p.options, o)
|
||||
return p
|
||||
}
|
||||
|
||||
// ToASCII converts a domain or domain label to its ASCII form. For example,
|
||||
// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
|
||||
// ToASCII("golang") is "golang". If an error is encountered it will return
|
||||
// an error and a (partially) processed result.
|
||||
func (p *Profile) ToASCII(s string) (string, error) {
|
||||
return p.process(s, true)
|
||||
}
|
||||
|
||||
// ToUnicode converts a domain or domain label to its Unicode form. For example,
|
||||
// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
|
||||
// ToUnicode("golang") is "golang". If an error is encountered it will return
|
||||
// an error and a (partially) processed result.
|
||||
func (p *Profile) ToUnicode(s string) (string, error) {
|
||||
pp := *p
|
||||
pp.transitional = false
|
||||
return pp.process(s, false)
|
||||
}
|
||||
|
||||
// String reports a string with a description of the profile for debugging
|
||||
// purposes. The string format may change with different versions.
|
||||
func (p *Profile) String() string {
|
||||
s := ""
|
||||
if p.transitional {
|
||||
s = "Transitional"
|
||||
} else {
|
||||
s = "NonTransitional"
|
||||
}
|
||||
if p.useSTD3Rules {
|
||||
s += ":UseSTD3Rules"
|
||||
}
|
||||
if p.validateLabels {
|
||||
s += ":ValidateLabels"
|
||||
}
|
||||
if p.verifyDNSLength {
|
||||
s += ":VerifyDNSLength"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
var (
|
||||
// Punycode is a Profile that does raw punycode processing with a minimum
|
||||
// of validation.
|
||||
Punycode *Profile = punycode
|
||||
|
||||
// Lookup is the recommended profile for looking up domain names, according
|
||||
// to Section 5 of RFC 5891. The exact configuration of this profile may
|
||||
// change over time.
|
||||
Lookup *Profile = lookup
|
||||
|
||||
// Display is the recommended profile for displaying domain names.
|
||||
// The configuration of this profile may change over time.
|
||||
Display *Profile = display
|
||||
|
||||
// Registration is the recommended profile for checking whether a given
|
||||
// IDN is valid for registration, according to Section 4 of RFC 5891.
|
||||
Registration *Profile = registration
|
||||
|
||||
punycode = &Profile{}
|
||||
lookup = &Profile{options{
|
||||
transitional: true,
|
||||
useSTD3Rules: true,
|
||||
validateLabels: true,
|
||||
removeLeadingDots: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateAndMap,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
display = &Profile{options{
|
||||
useSTD3Rules: true,
|
||||
validateLabels: true,
|
||||
removeLeadingDots: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateAndMap,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
registration = &Profile{options{
|
||||
useSTD3Rules: true,
|
||||
validateLabels: true,
|
||||
verifyDNSLength: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateRegistration,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
|
||||
// TODO: profiles
|
||||
// Register: recommended for approving domain names: don't do any mappings
|
||||
// but rather reject on invalid input. Bundle or block deviation characters.
|
||||
)
|
||||
|
||||
type labelError struct{ label, code_ string }
|
||||
|
||||
func (e labelError) code() string { return e.code_ }
|
||||
func (e labelError) Error() string {
|
||||
return fmt.Sprintf("idna: invalid label %q", e.label)
|
||||
}
|
||||
|
||||
type runeError rune
|
||||
|
||||
func (e runeError) code() string { return "P1" }
|
||||
func (e runeError) Error() string {
|
||||
return fmt.Sprintf("idna: disallowed rune %U", e)
|
||||
}
|
||||
|
||||
// process implements the algorithm described in section 4 of UTS #46,
|
||||
// see http://www.unicode.org/reports/tr46.
|
||||
func (p *Profile) process(s string, toASCII bool) (string, error) {
|
||||
var err error
|
||||
if p.mapping != nil {
|
||||
s, err = p.mapping(p, s)
|
||||
}
|
||||
// Remove leading empty labels.
|
||||
if p.removeLeadingDots {
|
||||
for ; len(s) > 0 && s[0] == '.'; s = s[1:] {
|
||||
}
|
||||
}
|
||||
// It seems like we should only create this error on ToASCII, but the
|
||||
// UTS 46 conformance tests suggests we should always check this.
|
||||
if err == nil && p.verifyDNSLength && s == "" {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
labels := labelIter{orig: s}
|
||||
for ; !labels.done(); labels.next() {
|
||||
label := labels.label()
|
||||
if label == "" {
|
||||
// Empty labels are not okay. The label iterator skips the last
|
||||
// label if it is empty.
|
||||
if err == nil && p.verifyDNSLength {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(label, acePrefix) {
|
||||
u, err2 := decode(label[len(acePrefix):])
|
||||
if err2 != nil {
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
// Spec says keep the old label.
|
||||
continue
|
||||
}
|
||||
labels.set(u)
|
||||
if err == nil && p.validateLabels {
|
||||
err = p.fromPuny(p, u)
|
||||
}
|
||||
if err == nil {
|
||||
// This should be called on NonTransitional, according to the
|
||||
// spec, but that currently does not have any effect. Use the
|
||||
// original profile to preserve options.
|
||||
err = p.validateLabel(u)
|
||||
}
|
||||
} else if err == nil {
|
||||
err = p.validateLabel(label)
|
||||
}
|
||||
}
|
||||
if toASCII {
|
||||
for labels.reset(); !labels.done(); labels.next() {
|
||||
label := labels.label()
|
||||
if !ascii(label) {
|
||||
a, err2 := encode(acePrefix, label)
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
label = a
|
||||
labels.set(a)
|
||||
}
|
||||
n := len(label)
|
||||
if p.verifyDNSLength && err == nil && (n == 0 || n > 63) {
|
||||
err = &labelError{label, "A4"}
|
||||
}
|
||||
}
|
||||
}
|
||||
s = labels.result()
|
||||
if toASCII && p.verifyDNSLength && err == nil {
|
||||
// Compute the length of the domain name minus the root label and its dot.
|
||||
n := len(s)
|
||||
if n > 0 && s[n-1] == '.' {
|
||||
n--
|
||||
}
|
||||
if len(s) < 1 || n > 253 {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
|
||||
func normalize(p *Profile, s string) (string, error) {
|
||||
return norm.NFC.String(s), nil
|
||||
}
|
||||
|
||||
func validateRegistration(p *Profile, s string) (string, error) {
|
||||
if !norm.NFC.IsNormalString(s) {
|
||||
return s, &labelError{s, "V1"}
|
||||
}
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
// Copy bytes not copied so far.
|
||||
switch p.simplify(info(v).category()) {
|
||||
// TODO: handle the NV8 defined in the Unicode idna data set to allow
|
||||
// for strict conformance to IDNA2008.
|
||||
case valid, deviation:
|
||||
case disallowed, mapped, unknown, ignored:
|
||||
r, _ := utf8.DecodeRuneInString(s[i:])
|
||||
return s, runeError(r)
|
||||
}
|
||||
i += sz
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func validateAndMap(p *Profile, s string) (string, error) {
|
||||
var (
|
||||
err error
|
||||
b []byte
|
||||
k int
|
||||
)
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
start := i
|
||||
i += sz
|
||||
// Copy bytes not copied so far.
|
||||
switch p.simplify(info(v).category()) {
|
||||
case valid:
|
||||
continue
|
||||
case disallowed:
|
||||
if err == nil {
|
||||
r, _ := utf8.DecodeRuneInString(s[start:])
|
||||
err = runeError(r)
|
||||
}
|
||||
continue
|
||||
case mapped, deviation:
|
||||
b = append(b, s[k:start]...)
|
||||
b = info(v).appendMapping(b, s[start:i])
|
||||
case ignored:
|
||||
b = append(b, s[k:start]...)
|
||||
// drop the rune
|
||||
case unknown:
|
||||
b = append(b, s[k:start]...)
|
||||
b = append(b, "\ufffd"...)
|
||||
}
|
||||
k = i
|
||||
}
|
||||
if k == 0 {
|
||||
// No changes so far.
|
||||
s = norm.NFC.String(s)
|
||||
} else {
|
||||
b = append(b, s[k:]...)
|
||||
if norm.NFC.QuickSpan(b) != len(b) {
|
||||
b = norm.NFC.Bytes(b)
|
||||
}
|
||||
// TODO: the punycode converters require strings as input.
|
||||
s = string(b)
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
|
||||
// A labelIter allows iterating over domain name labels.
|
||||
type labelIter struct {
|
||||
orig string
|
||||
slice []string
|
||||
curStart int
|
||||
curEnd int
|
||||
i int
|
||||
}
|
||||
|
||||
func (l *labelIter) reset() {
|
||||
l.curStart = 0
|
||||
l.curEnd = 0
|
||||
l.i = 0
|
||||
}
|
||||
|
||||
func (l *labelIter) done() bool {
|
||||
return l.curStart >= len(l.orig)
|
||||
}
|
||||
|
||||
func (l *labelIter) result() string {
|
||||
if l.slice != nil {
|
||||
return strings.Join(l.slice, ".")
|
||||
}
|
||||
return l.orig
|
||||
}
|
||||
|
||||
func (l *labelIter) label() string {
|
||||
if l.slice != nil {
|
||||
return l.slice[l.i]
|
||||
}
|
||||
p := strings.IndexByte(l.orig[l.curStart:], '.')
|
||||
l.curEnd = l.curStart + p
|
||||
if p == -1 {
|
||||
l.curEnd = len(l.orig)
|
||||
}
|
||||
return l.orig[l.curStart:l.curEnd]
|
||||
}
|
||||
|
||||
// next sets the value to the next label. It skips the last label if it is empty.
|
||||
func (l *labelIter) next() {
|
||||
l.i++
|
||||
if l.slice != nil {
|
||||
if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" {
|
||||
l.curStart = len(l.orig)
|
||||
}
|
||||
} else {
|
||||
l.curStart = l.curEnd + 1
|
||||
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
|
||||
l.curStart = len(l.orig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *labelIter) set(s string) {
|
||||
if l.slice == nil {
|
||||
l.slice = strings.Split(l.orig, ".")
|
||||
}
|
||||
l.slice[l.i] = s
|
||||
}
|
||||
|
||||
// acePrefix is the ASCII Compatible Encoding prefix.
|
||||
const acePrefix = "xn--"
|
||||
|
||||
func (p *Profile) simplify(cat category) category {
|
||||
switch cat {
|
||||
case disallowedSTD3Mapped:
|
||||
if p.useSTD3Rules {
|
||||
cat = disallowed
|
||||
} else {
|
||||
cat = mapped
|
||||
}
|
||||
case disallowedSTD3Valid:
|
||||
if p.useSTD3Rules {
|
||||
cat = disallowed
|
||||
} else {
|
||||
cat = valid
|
||||
}
|
||||
case deviation:
|
||||
if !p.transitional {
|
||||
cat = valid
|
||||
}
|
||||
case validNV8, validXV8:
|
||||
// TODO: handle V2008
|
||||
cat = valid
|
||||
}
|
||||
return cat
|
||||
}
|
||||
|
||||
func validateFromPunycode(p *Profile, s string) error {
|
||||
if !norm.NFC.IsNormalString(s) {
|
||||
return &labelError{s, "V1"}
|
||||
}
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
if c := p.simplify(info(v).category()); c != valid && c != deviation {
|
||||
return &labelError{s, "V6"}
|
||||
}
|
||||
i += sz
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
zwnj = "\u200c"
|
||||
zwj = "\u200d"
|
||||
)
|
||||
|
||||
type joinState int8
|
||||
|
||||
const (
|
||||
stateStart joinState = iota
|
||||
stateVirama
|
||||
stateBefore
|
||||
stateBeforeVirama
|
||||
stateAfter
|
||||
stateFAIL
|
||||
)
|
||||
|
||||
var joinStates = [][numJoinTypes]joinState{
|
||||
stateStart: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateVirama,
|
||||
},
|
||||
stateVirama: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
},
|
||||
stateBefore: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateBefore,
|
||||
joinZWNJ: stateAfter,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateBeforeVirama,
|
||||
},
|
||||
stateBeforeVirama: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateBefore,
|
||||
},
|
||||
stateAfter: {
|
||||
joiningL: stateFAIL,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateAfter,
|
||||
joiningR: stateStart,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateAfter, // no-op as we can't accept joiners here
|
||||
},
|
||||
stateFAIL: {
|
||||
0: stateFAIL,
|
||||
joiningL: stateFAIL,
|
||||
joiningD: stateFAIL,
|
||||
joiningT: stateFAIL,
|
||||
joiningR: stateFAIL,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateFAIL,
|
||||
},
|
||||
}
|
||||
|
||||
// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
|
||||
// already implicitly satisfied by the overall implementation.
|
||||
func (p *Profile) validateLabel(s string) error {
|
||||
if s == "" {
|
||||
if p.verifyDNSLength {
|
||||
return &labelError{s, "A4"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if p.bidirule != nil && !p.bidirule(s) {
|
||||
return &labelError{s, "B"}
|
||||
}
|
||||
if !p.validateLabels {
|
||||
return nil
|
||||
}
|
||||
trie := p.trie // p.validateLabels is only set if trie is set.
|
||||
if len(s) > 4 && s[2] == '-' && s[3] == '-' {
|
||||
return &labelError{s, "V2"}
|
||||
}
|
||||
if s[0] == '-' || s[len(s)-1] == '-' {
|
||||
return &labelError{s, "V3"}
|
||||
}
|
||||
// TODO: merge the use of this in the trie.
|
||||
v, sz := trie.lookupString(s)
|
||||
x := info(v)
|
||||
if x.isModifier() {
|
||||
return &labelError{s, "V5"}
|
||||
}
|
||||
// Quickly return in the absence of zero-width (non) joiners.
|
||||
if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 {
|
||||
return nil
|
||||
}
|
||||
st := stateStart
|
||||
for i := 0; ; {
|
||||
jt := x.joinType()
|
||||
if s[i:i+sz] == zwj {
|
||||
jt = joinZWJ
|
||||
} else if s[i:i+sz] == zwnj {
|
||||
jt = joinZWNJ
|
||||
}
|
||||
st = joinStates[st][jt]
|
||||
if x.isViramaModifier() {
|
||||
st = joinStates[st][joinVirama]
|
||||
}
|
||||
if i += sz; i == len(s) {
|
||||
break
|
||||
}
|
||||
v, sz = trie.lookupString(s[i:])
|
||||
x = info(v)
|
||||
}
|
||||
if st == stateFAIL || st == stateAfter {
|
||||
return &labelError{s, "C"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ascii(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] >= utf8.RuneSelf {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
136
vendor/golang.org/x/text/internal/export/idna/idna9.0.0_test.go
generated
vendored
Normal file
136
vendor/golang.org/x/text/internal/export/idna/idna9.0.0_test.go
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
// 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.
|
||||
|
||||
// +build !go1.10
|
||||
|
||||
package idna
|
||||
|
||||
import "testing"
|
||||
|
||||
// TestLabelErrors tests strings returned in case of error. All results should
|
||||
// be identical to the reference implementation and can be verified at
|
||||
// http://unicode.org/cldr/utility/idna.jsp. The reference implementation,
|
||||
// however, seems to not display Bidi and ContextJ errors.
|
||||
//
|
||||
// In some cases the behavior of browsers is added as a comment. In all cases,
|
||||
// whenever a resolve search returns an error here, Chrome will treat the input
|
||||
// string as a search string (including those for Bidi and Context J errors),
|
||||
// unless noted otherwise.
|
||||
func TestLabelErrors(t *testing.T) {
|
||||
encode := func(s string) string { s, _ = encode(acePrefix, s); return s }
|
||||
type kind struct {
|
||||
name string
|
||||
f func(string) (string, error)
|
||||
}
|
||||
punyA := kind{"PunycodeA", punycode.ToASCII}
|
||||
resolve := kind{"ResolveA", Lookup.ToASCII}
|
||||
display := kind{"ToUnicode", Display.ToUnicode}
|
||||
p := New(VerifyDNSLength(true), MapForLookup(), BidiRule())
|
||||
lengthU := kind{"CheckLengthU", p.ToUnicode}
|
||||
lengthA := kind{"CheckLengthA", p.ToASCII}
|
||||
p = New(MapForLookup(), StrictDomainName(false))
|
||||
std3 := kind{"STD3", p.ToASCII}
|
||||
|
||||
testCases := []struct {
|
||||
kind
|
||||
input string
|
||||
want string
|
||||
wantErr string
|
||||
}{
|
||||
{lengthU, "", "", "A4"}, // From UTS 46 conformance test.
|
||||
{lengthA, "", "", "A4"},
|
||||
|
||||
{lengthU, "xn--", "", "A4"},
|
||||
{lengthU, "foo.xn--", "foo.", "A4"}, // TODO: is dropping xn-- correct?
|
||||
{lengthU, "xn--.foo", ".foo", "A4"},
|
||||
{lengthU, "foo.xn--.bar", "foo..bar", "A4"},
|
||||
|
||||
{display, "xn--", "", ""},
|
||||
{display, "foo.xn--", "foo.", ""}, // TODO: is dropping xn-- correct?
|
||||
{display, "xn--.foo", ".foo", ""},
|
||||
{display, "foo.xn--.bar", "foo..bar", ""},
|
||||
|
||||
{lengthA, "a..b", "a..b", "A4"},
|
||||
{punyA, ".b", ".b", ""},
|
||||
// For backwards compatibility, the Punycode profile does not map runes.
|
||||
{punyA, "\u3002b", "xn--b-83t", ""},
|
||||
{punyA, "..b", "..b", ""},
|
||||
// Only strip leading empty labels for certain profiles. Stripping
|
||||
// leading empty labels here but not for "empty" punycode above seems
|
||||
// inconsistent, but seems to be applied by both the conformance test
|
||||
// and Chrome. So we turn it off by default, support it as an option,
|
||||
// and enable it in profiles where it seems commonplace.
|
||||
{lengthA, ".b", "b", ""},
|
||||
{lengthA, "\u3002b", "b", ""},
|
||||
{lengthA, "..b", "b", ""},
|
||||
{lengthA, "b..", "b..", ""},
|
||||
|
||||
{resolve, "a..b", "a..b", ""},
|
||||
{resolve, ".b", "b", ""},
|
||||
{resolve, "\u3002b", "b", ""},
|
||||
{resolve, "..b", "b", ""},
|
||||
{resolve, "b..", "b..", ""},
|
||||
|
||||
// Raw punycode
|
||||
{punyA, "", "", ""},
|
||||
{punyA, "*.foo.com", "*.foo.com", ""},
|
||||
{punyA, "Foo.com", "Foo.com", ""},
|
||||
|
||||
// STD3 rules
|
||||
{display, "*.foo.com", "*.foo.com", "P1"},
|
||||
{std3, "*.foo.com", "*.foo.com", ""},
|
||||
|
||||
// Don't map U+2490 (DIGIT NINE FULL STOP). This is the behavior of
|
||||
// Chrome, Safari, and IE. Firefox will first map ⒐ to 9. and return
|
||||
// lab9.be.
|
||||
{resolve, "lab⒐be", "xn--labbe-zh9b", "P1"}, // encode("lab⒐be")
|
||||
{display, "lab⒐be", "lab⒐be", "P1"},
|
||||
|
||||
{resolve, "plan⒐faß.de", "xn--planfass-c31e.de", "P1"}, // encode("plan⒐fass") + ".de"
|
||||
{display, "Plan⒐faß.de", "plan⒐faß.de", "P1"},
|
||||
|
||||
// Chrome 54.0 recognizes the error and treats this input verbatim as a
|
||||
// search string.
|
||||
// Safari 10.0 (non-conform spec) decomposes "⒈" and computes the
|
||||
// punycode on the result using transitional mapping.
|
||||
// Firefox 49.0.1 goes haywire on this string and prints a bunch of what
|
||||
// seems to be nested punycode encodings.
|
||||
{resolve, "日本⒈co.ßßß.de", "xn--co-wuw5954azlb.ssssss.de", "P1"},
|
||||
{display, "日本⒈co.ßßß.de", "日本⒈co.ßßß.de", "P1"},
|
||||
|
||||
{resolve, "a\u200Cb", "ab", ""},
|
||||
{display, "a\u200Cb", "a\u200Cb", "C"},
|
||||
|
||||
{resolve, encode("a\u200Cb"), encode("a\u200Cb"), "C"},
|
||||
{display, "a\u200Cb", "a\u200Cb", "C"},
|
||||
|
||||
{resolve, "grﻋﺮﺑﻲ.de", "xn--gr-gtd9a1b0g.de", "B"},
|
||||
{
|
||||
// Notice how the string gets transformed, even with an error.
|
||||
// Chrome will use the original string if it finds an error, so not
|
||||
// the transformed one.
|
||||
display,
|
||||
"gr\ufecb\ufeae\ufe91\ufef2.de",
|
||||
"gr\u0639\u0631\u0628\u064a.de",
|
||||
"B",
|
||||
},
|
||||
|
||||
{resolve, "\u0671.\u03c3\u07dc", "xn--qib.xn--4xa21s", "B"}, // ٱ.σߜ
|
||||
{display, "\u0671.\u03c3\u07dc", "\u0671.\u03c3\u07dc", "B"},
|
||||
|
||||
// normalize input
|
||||
{resolve, "a\u0323\u0322", "xn--jta191l", ""}, // ạ̢
|
||||
{display, "a\u0323\u0322", "\u1ea1\u0322", ""},
|
||||
|
||||
// Non-normalized strings are not normalized when they originate from
|
||||
// punycode. Despite the error, Chrome, Safari and Firefox will attempt
|
||||
// to look up the input punycode.
|
||||
{resolve, encode("a\u0323\u0322") + ".com", "xn--a-tdbc.com", "V1"},
|
||||
{display, encode("a\u0323\u0322") + ".com", "a\u0323\u0322.com", "V1"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
doTest(t, tc.f, tc.name, tc.input, tc.want, tc.wantErr)
|
||||
}
|
||||
}
|
131
vendor/golang.org/x/text/internal/export/idna/idna_test.go
generated
vendored
131
vendor/golang.org/x/text/internal/export/idna/idna_test.go
generated
vendored
|
@ -101,137 +101,6 @@ func doTest(t *testing.T, f func(string) (string, error), name, input, want, err
|
|||
})
|
||||
}
|
||||
|
||||
// TestLabelErrors tests strings returned in case of error. All results should
|
||||
// be identical to the reference implementation and can be verified at
|
||||
// http://unicode.org/cldr/utility/idna.jsp. The reference implementation,
|
||||
// however, seems to not display Bidi and ContextJ errors.
|
||||
//
|
||||
// In some cases the behavior of browsers is added as a comment. In all cases,
|
||||
// whenever a resolve search returns an error here, Chrome will treat the input
|
||||
// string as a search string (including those for Bidi and Context J errors),
|
||||
// unless noted otherwise.
|
||||
func TestLabelErrors(t *testing.T) {
|
||||
encode := func(s string) string { s, _ = encode(acePrefix, s); return s }
|
||||
type kind struct {
|
||||
name string
|
||||
f func(string) (string, error)
|
||||
}
|
||||
punyA := kind{"PunycodeA", punycode.ToASCII}
|
||||
resolve := kind{"ResolveA", Lookup.ToASCII}
|
||||
display := kind{"ToUnicode", Display.ToUnicode}
|
||||
p := New(VerifyDNSLength(true), MapForLookup(), BidiRule())
|
||||
lengthU := kind{"CheckLengthU", p.ToUnicode}
|
||||
lengthA := kind{"CheckLengthA", p.ToASCII}
|
||||
p = New(MapForLookup(), StrictDomainName(false))
|
||||
std3 := kind{"STD3", p.ToASCII}
|
||||
|
||||
testCases := []struct {
|
||||
kind
|
||||
input string
|
||||
want string
|
||||
wantErr string
|
||||
}{
|
||||
{lengthU, "", "", "A4"}, // From UTS 46 conformance test.
|
||||
{lengthA, "", "", "A4"},
|
||||
|
||||
{lengthU, "xn--", "", "A4"},
|
||||
{lengthU, "foo.xn--", "foo.", "A4"}, // TODO: is dropping xn-- correct?
|
||||
{lengthU, "xn--.foo", ".foo", "A4"},
|
||||
{lengthU, "foo.xn--.bar", "foo..bar", "A4"},
|
||||
|
||||
{display, "xn--", "", ""},
|
||||
{display, "foo.xn--", "foo.", ""}, // TODO: is dropping xn-- correct?
|
||||
{display, "xn--.foo", ".foo", ""},
|
||||
{display, "foo.xn--.bar", "foo..bar", ""},
|
||||
|
||||
{lengthA, "a..b", "a..b", "A4"},
|
||||
{punyA, ".b", ".b", ""},
|
||||
// For backwards compatibility, the Punycode profile does not map runes.
|
||||
{punyA, "\u3002b", "xn--b-83t", ""},
|
||||
{punyA, "..b", "..b", ""},
|
||||
|
||||
{lengthA, ".b", ".b", "A4"},
|
||||
{lengthA, "\u3002b", ".b", "A4"},
|
||||
{lengthA, "..b", "..b", "A4"},
|
||||
{lengthA, "b..", "b..", ""},
|
||||
|
||||
// Sharpened Bidi rules for Unicode 10.0.0. Apply for ALL labels in ANY
|
||||
// of the labels is RTL.
|
||||
{lengthA, "\ufe05\u3002\u3002\U0002603e\u1ce0", "..xn--t6f5138v", "A4"},
|
||||
{lengthA, "FAX\u2a77\U0001d186\u3002\U0001e942\U000e0181\u180c", "", "B6"},
|
||||
|
||||
{resolve, "a..b", "a..b", ""},
|
||||
// Note that leading dots are not stripped. This is to be consistent
|
||||
// with the Punycode profile as well as the conformance test.
|
||||
{resolve, ".b", ".b", ""},
|
||||
{resolve, "\u3002b", ".b", ""},
|
||||
{resolve, "..b", "..b", ""},
|
||||
{resolve, "b..", "b..", ""},
|
||||
{resolve, "\xed", "", "P1"},
|
||||
|
||||
// Raw punycode
|
||||
{punyA, "", "", ""},
|
||||
{punyA, "*.foo.com", "*.foo.com", ""},
|
||||
{punyA, "Foo.com", "Foo.com", ""},
|
||||
|
||||
// STD3 rules
|
||||
{display, "*.foo.com", "*.foo.com", "P1"},
|
||||
{std3, "*.foo.com", "*.foo.com", ""},
|
||||
|
||||
// Don't map U+2490 (DIGIT NINE FULL STOP). This is the behavior of
|
||||
// Chrome, Safari, and IE. Firefox will first map ⒐ to 9. and return
|
||||
// lab9.be.
|
||||
{resolve, "lab⒐be", "xn--labbe-zh9b", "P1"}, // encode("lab⒐be")
|
||||
{display, "lab⒐be", "lab⒐be", "P1"},
|
||||
|
||||
{resolve, "plan⒐faß.de", "xn--planfass-c31e.de", "P1"}, // encode("plan⒐fass") + ".de"
|
||||
{display, "Plan⒐faß.de", "plan⒐faß.de", "P1"},
|
||||
|
||||
// Chrome 54.0 recognizes the error and treats this input verbatim as a
|
||||
// search string.
|
||||
// Safari 10.0 (non-conform spec) decomposes "⒈" and computes the
|
||||
// punycode on the result using transitional mapping.
|
||||
// Firefox 49.0.1 goes haywire on this string and prints a bunch of what
|
||||
// seems to be nested punycode encodings.
|
||||
{resolve, "日本⒈co.ßßß.de", "xn--co-wuw5954azlb.ssssss.de", "P1"},
|
||||
{display, "日本⒈co.ßßß.de", "日本⒈co.ßßß.de", "P1"},
|
||||
|
||||
{resolve, "a\u200Cb", "ab", ""},
|
||||
{display, "a\u200Cb", "a\u200Cb", "C"},
|
||||
|
||||
{resolve, encode("a\u200Cb"), encode("a\u200Cb"), "C"},
|
||||
{display, "a\u200Cb", "a\u200Cb", "C"},
|
||||
|
||||
{resolve, "grﻋﺮﺑﻲ.de", "xn--gr-gtd9a1b0g.de", "B"},
|
||||
{
|
||||
// Notice how the string gets transformed, even with an error.
|
||||
// Chrome will use the original string if it finds an error, so not
|
||||
// the transformed one.
|
||||
display,
|
||||
"gr\ufecb\ufeae\ufe91\ufef2.de",
|
||||
"gr\u0639\u0631\u0628\u064a.de",
|
||||
"B",
|
||||
},
|
||||
|
||||
{resolve, "\u0671.\u03c3\u07dc", "xn--qib.xn--4xa21s", "B"}, // ٱ.σߜ
|
||||
{display, "\u0671.\u03c3\u07dc", "\u0671.\u03c3\u07dc", "B"},
|
||||
|
||||
// normalize input
|
||||
{resolve, "a\u0323\u0322", "xn--jta191l", ""}, // ạ̢
|
||||
{display, "a\u0323\u0322", "\u1ea1\u0322", ""},
|
||||
|
||||
// Non-normalized strings are not normalized when they originate from
|
||||
// punycode. Despite the error, Chrome, Safari and Firefox will attempt
|
||||
// to look up the input punycode.
|
||||
{resolve, encode("a\u0323\u0322") + ".com", "xn--a-tdbc.com", "V1"},
|
||||
{display, encode("a\u0323\u0322") + ".com", "a\u0323\u0322.com", "V1"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
doTest(t, tc.f, tc.name, tc.input, tc.want, tc.wantErr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConformance(t *testing.T) {
|
||||
testtext.SkipIfNotLong(t)
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// +build go1.10
|
||||
|
||||
package idna
|
||||
|
||||
// UnicodeVersion is the Unicode version from which the tables in this package are derived.
|
4486
vendor/golang.org/x/text/internal/export/idna/tables9.0.0.go
generated
vendored
Normal file
4486
vendor/golang.org/x/text/internal/export/idna/tables9.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
357
vendor/golang.org/x/text/internal/format/parser.go
generated
vendored
Normal file
357
vendor/golang.org/x/text/internal/format/parser.go
generated
vendored
Normal file
|
@ -0,0 +1,357 @@
|
|||
// 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 format
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// A Parser parses a format string. The result from the parse are set in the
|
||||
// struct fields.
|
||||
type Parser struct {
|
||||
Verb rune
|
||||
|
||||
WidthPresent bool
|
||||
PrecPresent bool
|
||||
Minus bool
|
||||
Plus bool
|
||||
Sharp bool
|
||||
Space bool
|
||||
Zero bool
|
||||
|
||||
// For the formats %+v %#v, we set the plusV/sharpV flags
|
||||
// and clear the plus/sharp flags since %+v and %#v are in effect
|
||||
// different, flagless formats set at the top level.
|
||||
PlusV bool
|
||||
SharpV bool
|
||||
|
||||
HasIndex bool
|
||||
|
||||
Width int
|
||||
Prec int // precision
|
||||
|
||||
// retain arguments across calls.
|
||||
Args []interface{}
|
||||
// retain current argument number across calls
|
||||
ArgNum int
|
||||
|
||||
// reordered records whether the format string used argument reordering.
|
||||
Reordered bool
|
||||
// goodArgNum records whether the most recent reordering directive was valid.
|
||||
goodArgNum bool
|
||||
|
||||
// position info
|
||||
format string
|
||||
startPos int
|
||||
endPos int
|
||||
Status Status
|
||||
}
|
||||
|
||||
// Reset initializes a parser to scan format strings for the given args.
|
||||
func (p *Parser) Reset(args []interface{}) {
|
||||
p.Args = args
|
||||
p.ArgNum = 0
|
||||
p.startPos = 0
|
||||
p.Reordered = false
|
||||
}
|
||||
|
||||
// Text returns the part of the format string that was parsed by the last call
|
||||
// to Scan. It returns the original substitution clause if the current scan
|
||||
// parsed a substitution.
|
||||
func (p *Parser) Text() string { return p.format[p.startPos:p.endPos] }
|
||||
|
||||
// SetFormat sets a new format string to parse. It does not reset the argument
|
||||
// count.
|
||||
func (p *Parser) SetFormat(format string) {
|
||||
p.format = format
|
||||
p.startPos = 0
|
||||
p.endPos = 0
|
||||
}
|
||||
|
||||
// Status indicates the result type of a call to Scan.
|
||||
type Status int
|
||||
|
||||
const (
|
||||
StatusText Status = iota
|
||||
StatusSubstitution
|
||||
StatusBadWidthSubstitution
|
||||
StatusBadPrecSubstitution
|
||||
StatusNoVerb
|
||||
StatusBadArgNum
|
||||
StatusMissingArg
|
||||
)
|
||||
|
||||
// ClearFlags reset the parser to default behavior.
|
||||
func (p *Parser) ClearFlags() {
|
||||
p.WidthPresent = false
|
||||
p.PrecPresent = false
|
||||
p.Minus = false
|
||||
p.Plus = false
|
||||
p.Sharp = false
|
||||
p.Space = false
|
||||
p.Zero = false
|
||||
|
||||
p.PlusV = false
|
||||
p.SharpV = false
|
||||
|
||||
p.HasIndex = false
|
||||
}
|
||||
|
||||
// Scan scans the next part of the format string and sets the status to
|
||||
// indicate whether it scanned a string literal, substitution or error.
|
||||
func (p *Parser) Scan() bool {
|
||||
p.Status = StatusText
|
||||
format := p.format
|
||||
end := len(format)
|
||||
if p.endPos >= end {
|
||||
return false
|
||||
}
|
||||
afterIndex := false // previous item in format was an index like [3].
|
||||
|
||||
p.startPos = p.endPos
|
||||
p.goodArgNum = true
|
||||
i := p.startPos
|
||||
for i < end && format[i] != '%' {
|
||||
i++
|
||||
}
|
||||
if i > p.startPos {
|
||||
p.endPos = i
|
||||
return true
|
||||
}
|
||||
// Process one verb
|
||||
i++
|
||||
|
||||
p.Status = StatusSubstitution
|
||||
|
||||
// Do we have flags?
|
||||
p.ClearFlags()
|
||||
|
||||
simpleFormat:
|
||||
for ; i < end; i++ {
|
||||
c := p.format[i]
|
||||
switch c {
|
||||
case '#':
|
||||
p.Sharp = true
|
||||
case '0':
|
||||
p.Zero = !p.Minus // Only allow zero padding to the left.
|
||||
case '+':
|
||||
p.Plus = true
|
||||
case '-':
|
||||
p.Minus = true
|
||||
p.Zero = false // Do not pad with zeros to the right.
|
||||
case ' ':
|
||||
p.Space = true
|
||||
default:
|
||||
// Fast path for common case of ascii lower case simple verbs
|
||||
// without precision or width or argument indices.
|
||||
if 'a' <= c && c <= 'z' && p.ArgNum < len(p.Args) {
|
||||
if c == 'v' {
|
||||
// Go syntax
|
||||
p.SharpV = p.Sharp
|
||||
p.Sharp = false
|
||||
// Struct-field syntax
|
||||
p.PlusV = p.Plus
|
||||
p.Plus = false
|
||||
}
|
||||
p.Verb = rune(c)
|
||||
p.ArgNum++
|
||||
p.endPos = i + 1
|
||||
return true
|
||||
}
|
||||
// Format is more complex than simple flags and a verb or is malformed.
|
||||
break simpleFormat
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have an explicit argument index?
|
||||
i, afterIndex = p.updateArgNumber(format, i)
|
||||
|
||||
// Do we have width?
|
||||
if i < end && format[i] == '*' {
|
||||
i++
|
||||
p.Width, p.WidthPresent = p.intFromArg()
|
||||
|
||||
if !p.WidthPresent {
|
||||
p.Status = StatusBadWidthSubstitution
|
||||
}
|
||||
|
||||
// We have a negative width, so take its value and ensure
|
||||
// that the minus flag is set
|
||||
if p.Width < 0 {
|
||||
p.Width = -p.Width
|
||||
p.Minus = true
|
||||
p.Zero = false // Do not pad with zeros to the right.
|
||||
}
|
||||
afterIndex = false
|
||||
} else {
|
||||
p.Width, p.WidthPresent, i = parsenum(format, i, end)
|
||||
if afterIndex && p.WidthPresent { // "%[3]2d"
|
||||
p.goodArgNum = false
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have precision?
|
||||
if i+1 < end && format[i] == '.' {
|
||||
i++
|
||||
if afterIndex { // "%[3].2d"
|
||||
p.goodArgNum = false
|
||||
}
|
||||
i, afterIndex = p.updateArgNumber(format, i)
|
||||
if i < end && format[i] == '*' {
|
||||
i++
|
||||
p.Prec, p.PrecPresent = p.intFromArg()
|
||||
// Negative precision arguments don't make sense
|
||||
if p.Prec < 0 {
|
||||
p.Prec = 0
|
||||
p.PrecPresent = false
|
||||
}
|
||||
if !p.PrecPresent {
|
||||
p.Status = StatusBadPrecSubstitution
|
||||
}
|
||||
afterIndex = false
|
||||
} else {
|
||||
p.Prec, p.PrecPresent, i = parsenum(format, i, end)
|
||||
if !p.PrecPresent {
|
||||
p.Prec = 0
|
||||
p.PrecPresent = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !afterIndex {
|
||||
i, afterIndex = p.updateArgNumber(format, i)
|
||||
}
|
||||
p.HasIndex = afterIndex
|
||||
|
||||
if i >= end {
|
||||
p.endPos = i
|
||||
p.Status = StatusNoVerb
|
||||
return true
|
||||
}
|
||||
|
||||
verb, w := utf8.DecodeRuneInString(format[i:])
|
||||
p.endPos = i + w
|
||||
p.Verb = verb
|
||||
|
||||
switch {
|
||||
case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec.
|
||||
p.startPos = p.endPos - 1
|
||||
p.Status = StatusText
|
||||
case !p.goodArgNum:
|
||||
p.Status = StatusBadArgNum
|
||||
case p.ArgNum >= len(p.Args): // No argument left over to print for the current verb.
|
||||
p.Status = StatusMissingArg
|
||||
case verb == 'v':
|
||||
// Go syntax
|
||||
p.SharpV = p.Sharp
|
||||
p.Sharp = false
|
||||
// Struct-field syntax
|
||||
p.PlusV = p.Plus
|
||||
p.Plus = false
|
||||
fallthrough
|
||||
default:
|
||||
p.ArgNum++
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// intFromArg gets the ArgNumth element of Args. On return, isInt reports
|
||||
// whether the argument has integer type.
|
||||
func (p *Parser) intFromArg() (num int, isInt bool) {
|
||||
if p.ArgNum < len(p.Args) {
|
||||
arg := p.Args[p.ArgNum]
|
||||
num, isInt = arg.(int) // Almost always OK.
|
||||
if !isInt {
|
||||
// Work harder.
|
||||
switch v := reflect.ValueOf(arg); v.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
n := v.Int()
|
||||
if int64(int(n)) == n {
|
||||
num = int(n)
|
||||
isInt = true
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
n := v.Uint()
|
||||
if int64(n) >= 0 && uint64(int(n)) == n {
|
||||
num = int(n)
|
||||
isInt = true
|
||||
}
|
||||
default:
|
||||
// Already 0, false.
|
||||
}
|
||||
}
|
||||
p.ArgNum++
|
||||
if tooLarge(num) {
|
||||
num = 0
|
||||
isInt = false
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// parseArgNumber returns the value of the bracketed number, minus 1
|
||||
// (explicit argument numbers are one-indexed but we want zero-indexed).
|
||||
// The opening bracket is known to be present at format[0].
|
||||
// The returned values are the index, the number of bytes to consume
|
||||
// up to the closing paren, if present, and whether the number parsed
|
||||
// ok. The bytes to consume will be 1 if no closing paren is present.
|
||||
func parseArgNumber(format string) (index int, wid int, ok bool) {
|
||||
// There must be at least 3 bytes: [n].
|
||||
if len(format) < 3 {
|
||||
return 0, 1, false
|
||||
}
|
||||
|
||||
// Find closing bracket.
|
||||
for i := 1; i < len(format); i++ {
|
||||
if format[i] == ']' {
|
||||
width, ok, newi := parsenum(format, 1, i)
|
||||
if !ok || newi != i {
|
||||
return 0, i + 1, false
|
||||
}
|
||||
return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
|
||||
}
|
||||
}
|
||||
return 0, 1, false
|
||||
}
|
||||
|
||||
// updateArgNumber returns the next argument to evaluate, which is either the value of the passed-in
|
||||
// argNum or the value of the bracketed integer that begins format[i:]. It also returns
|
||||
// the new value of i, that is, the index of the next byte of the format to process.
|
||||
func (p *Parser) updateArgNumber(format string, i int) (newi int, found bool) {
|
||||
if len(format) <= i || format[i] != '[' {
|
||||
return i, false
|
||||
}
|
||||
p.Reordered = true
|
||||
index, wid, ok := parseArgNumber(format[i:])
|
||||
if ok && 0 <= index && index < len(p.Args) {
|
||||
p.ArgNum = index
|
||||
return i + wid, true
|
||||
}
|
||||
p.goodArgNum = false
|
||||
return i + wid, ok
|
||||
}
|
||||
|
||||
// tooLarge reports whether the magnitude of the integer is
|
||||
// too large to be used as a formatting width or precision.
|
||||
func tooLarge(x int) bool {
|
||||
const max int = 1e6
|
||||
return x > max || x < -max
|
||||
}
|
||||
|
||||
// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present.
|
||||
func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
|
||||
if start >= end {
|
||||
return 0, false, end
|
||||
}
|
||||
for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
|
||||
if tooLarge(num) {
|
||||
return 0, false, end // Overflow; crazy long number most likely.
|
||||
}
|
||||
num = num*10 + int(s[newi]-'0')
|
||||
isnum = true
|
||||
}
|
||||
return
|
||||
}
|
32
vendor/golang.org/x/text/internal/format/parser_test.go
generated
vendored
Normal file
32
vendor/golang.org/x/text/internal/format/parser_test.go
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
// 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 format
|
||||
|
||||
import "testing"
|
||||
|
||||
// TODO: most of Parser is tested in x/message. Move some tests here.
|
||||
|
||||
func TestParsenum(t *testing.T) {
|
||||
testCases := []struct {
|
||||
s string
|
||||
start, end int
|
||||
num int
|
||||
isnum bool
|
||||
newi int
|
||||
}{
|
||||
{"a123", 0, 4, 0, false, 0},
|
||||
{"1234", 1, 1, 0, false, 1},
|
||||
{"123a", 0, 4, 123, true, 3},
|
||||
{"12a3", 0, 4, 12, true, 2},
|
||||
{"1234", 0, 4, 1234, true, 4},
|
||||
{"1a234", 1, 3, 0, false, 1},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
num, isnum, newi := parsenum(tt.s, tt.start, tt.end)
|
||||
if num != tt.num || isnum != tt.isnum || newi != tt.newi {
|
||||
t.Errorf("parsenum(%q, %d, %d) = %d, %v, %d, want %d, %v, %d", tt.s, tt.start, tt.end, num, isnum, newi, tt.num, tt.isnum, tt.newi)
|
||||
}
|
||||
}
|
||||
}
|
24
vendor/golang.org/x/text/internal/gen/code.go
generated
vendored
24
vendor/golang.org/x/text/internal/gen/code.go
generated
vendored
|
@ -55,18 +55,36 @@ func (w *CodeWriter) WriteGoFile(filename, pkg string) {
|
|||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err = w.WriteGo(f, pkg); err != nil {
|
||||
if _, err = w.WriteGo(f, pkg, ""); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteVersionedGoFile appends the buffer with the total size of all created
|
||||
// structures and writes it as a Go file to the the given file with the given
|
||||
// package name and build tags for the current Unicode version,
|
||||
func (w *CodeWriter) WriteVersionedGoFile(filename, pkg string) {
|
||||
tags := buildTags()
|
||||
if tags != "" {
|
||||
filename = insertVersion(filename, UnicodeVersion())
|
||||
}
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err = w.WriteGo(f, pkg, tags); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteGo appends the buffer with the total size of all created structures and
|
||||
// writes it as a Go file to the the given writer with the given package name.
|
||||
func (w *CodeWriter) WriteGo(out io.Writer, pkg string) (n int, err error) {
|
||||
func (w *CodeWriter) WriteGo(out io.Writer, pkg, tags string) (n int, err error) {
|
||||
sz := w.Size
|
||||
w.WriteComment("Total table size %d bytes (%dKiB); checksum: %X\n", sz, sz/1024, w.Hash.Sum32())
|
||||
defer w.buf.Reset()
|
||||
return WriteGo(out, pkg, w.buf.Bytes())
|
||||
return WriteGo(out, pkg, tags, w.buf.Bytes())
|
||||
}
|
||||
|
||||
func (w *CodeWriter) printf(f string, x ...interface{}) {
|
||||
|
|
64
vendor/golang.org/x/text/internal/gen/gen.go
generated
vendored
64
vendor/golang.org/x/text/internal/gen/gen.go
generated
vendored
|
@ -31,6 +31,7 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
|
||||
|
@ -69,8 +70,6 @@ func Init() {
|
|||
|
||||
const header = `// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
package %s
|
||||
|
||||
`
|
||||
|
||||
// UnicodeVersion reports the requested Unicode version.
|
||||
|
@ -78,11 +77,33 @@ func UnicodeVersion() string {
|
|||
return *unicodeVersion
|
||||
}
|
||||
|
||||
// UnicodeVersion reports the requested CLDR version.
|
||||
// CLDRVersion reports the requested CLDR version.
|
||||
func CLDRVersion() string {
|
||||
return *cldrVersion
|
||||
}
|
||||
|
||||
var tags = []struct{ version, buildTags string }{
|
||||
{"10.0.0", "go1.10"},
|
||||
{"", "!go1.10"},
|
||||
}
|
||||
|
||||
// buildTags reports the build tags used for the current Unicode version.
|
||||
func buildTags() string {
|
||||
v := UnicodeVersion()
|
||||
for _, x := range tags {
|
||||
// We should do a numeric comparison, but including the collate package
|
||||
// would create an import cycle. We approximate it by assuming that
|
||||
// longer version strings are later.
|
||||
if len(x.version) <= len(v) {
|
||||
return x.buildTags
|
||||
}
|
||||
if len(x.version) == len(v) && x.version <= v {
|
||||
return x.buildTags
|
||||
}
|
||||
}
|
||||
return tags[0].buildTags
|
||||
}
|
||||
|
||||
// IsLocal reports whether data files are available locally.
|
||||
func IsLocal() bool {
|
||||
dir, err := localReadmeFile()
|
||||
|
@ -243,15 +264,46 @@ func WriteGoFile(filename, pkg string, b []byte) {
|
|||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer w.Close()
|
||||
if _, err = WriteGo(w, pkg, b); err != nil {
|
||||
if _, err = WriteGo(w, pkg, "", b); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
func insertVersion(filename, version string) string {
|
||||
suffix := ".go"
|
||||
if strings.HasSuffix(filename, "_test.go") {
|
||||
suffix = "_test.go"
|
||||
}
|
||||
return fmt.Sprint(filename[:len(filename)-len(suffix)], version, suffix)
|
||||
}
|
||||
|
||||
// WriteVersionedGoFile prepends a standard file comment, adds build tags to
|
||||
// version the file for the current Unicode version, and package statement to
|
||||
// the given bytes, applies gofmt, and writes them to a file with the given
|
||||
// name. It will call log.Fatal if there are any errors.
|
||||
func WriteVersionedGoFile(filename, pkg string, b []byte) {
|
||||
tags := buildTags()
|
||||
if tags != "" {
|
||||
filename = insertVersion(filename, UnicodeVersion())
|
||||
}
|
||||
w, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer w.Close()
|
||||
if _, err = WriteGo(w, pkg, tags, b); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteGo prepends a standard file comment and package statement to the given
|
||||
// bytes, applies gofmt, and writes them to w.
|
||||
func WriteGo(w io.Writer, pkg string, b []byte) (n int, err error) {
|
||||
src := []byte(fmt.Sprintf(header, pkg))
|
||||
func WriteGo(w io.Writer, pkg, tags string, b []byte) (n int, err error) {
|
||||
src := []byte(header)
|
||||
if tags != "" {
|
||||
src = append(src, fmt.Sprintf("// +build %s\n\n", tags)...)
|
||||
}
|
||||
src = append(src, fmt.Sprintf("package %s\n\n", pkg)...)
|
||||
src = append(src, b...)
|
||||
formatted, err := format.Source(src)
|
||||
if err != nil {
|
||||
|
|
13
vendor/golang.org/x/text/internal/number/common.go
generated
vendored
13
vendor/golang.org/x/text/internal/number/common.go
generated
vendored
|
@ -33,8 +33,19 @@ const (
|
|||
NumSymbolTypes
|
||||
)
|
||||
|
||||
const hasNonLatnMask = 0x8000
|
||||
|
||||
// symOffset is an offset into altSymData if the bit indicated by hasNonLatnMask
|
||||
// is not 0 (with this bit masked out), and an offset into symIndex otherwise.
|
||||
//
|
||||
// TODO: this type can be a byte again if we use an indirection into altsymData
|
||||
// and introduce an alt -> offset slice (the length of this will be number of
|
||||
// alternatives plus 1). This also allows getting rid of the compactTag field
|
||||
// in altSymData. In total this will save about 1K.
|
||||
type symOffset uint16
|
||||
|
||||
type altSymData struct {
|
||||
compactTag uint16
|
||||
symIndex symOffset
|
||||
system system
|
||||
symIndex byte
|
||||
}
|
||||
|
|
0
vendor/golang.org/x/text/internal/number/format.go
generated
vendored
Executable file → Normal file
0
vendor/golang.org/x/text/internal/number/format.go
generated
vendored
Executable file → Normal file
0
vendor/golang.org/x/text/internal/number/format_test.go
generated
vendored
Executable file → Normal file
0
vendor/golang.org/x/text/internal/number/format_test.go
generated
vendored
Executable file → Normal file
12
vendor/golang.org/x/text/internal/number/gen.go
generated
vendored
12
vendor/golang.org/x/text/internal/number/gen.go
generated
vendored
|
@ -255,10 +255,10 @@ func genSymbols(w *gen.CodeWriter, data *cldr.CLDR) {
|
|||
|
||||
// resolveSymbolIndex gets the index from the closest matching locale,
|
||||
// including the locale itself.
|
||||
resolveSymbolIndex := func(langIndex int, ns system) byte {
|
||||
resolveSymbolIndex := func(langIndex int, ns system) symOffset {
|
||||
for {
|
||||
if sym := symbolMap[key{langIndex, ns}]; sym != nil {
|
||||
return byte(m[*sym])
|
||||
return symOffset(m[*sym])
|
||||
}
|
||||
if langIndex == 0 {
|
||||
return 0 // und, latn
|
||||
|
@ -270,7 +270,7 @@ func genSymbols(w *gen.CodeWriter, data *cldr.CLDR) {
|
|||
// Create an index with the symbols for each locale for the latn numbering
|
||||
// system. If this is not the default, or the only one, for a locale, we
|
||||
// will overwrite the value later.
|
||||
var langToDefaults [language.NumCompactTags]byte
|
||||
var langToDefaults [language.NumCompactTags]symOffset
|
||||
for _, l := range data.Locales() {
|
||||
langIndex, _ := language.CompactIndex(language.MustParse(l))
|
||||
langToDefaults[langIndex] = resolveSymbolIndex(langIndex, 0)
|
||||
|
@ -300,8 +300,8 @@ func genSymbols(w *gen.CodeWriter, data *cldr.CLDR) {
|
|||
for _, l := range data.Locales() {
|
||||
langIndex, _ := language.CompactIndex(language.MustParse(l))
|
||||
start := len(langToAlt)
|
||||
if start > 0x7F {
|
||||
log.Fatal("Number of alternative assignments > 0x7F")
|
||||
if start >= hasNonLatnMask {
|
||||
log.Fatalf("Number of alternative assignments >= %x", hasNonLatnMask)
|
||||
}
|
||||
// Create the entry for the default value.
|
||||
def := defaults[langIndex]
|
||||
|
@ -328,7 +328,7 @@ func genSymbols(w *gen.CodeWriter, data *cldr.CLDR) {
|
|||
langToAlt = langToAlt[:start]
|
||||
} else {
|
||||
// Overwrite the entry in langToDefaults.
|
||||
langToDefaults[langIndex] = 0x80 | byte(start)
|
||||
langToDefaults[langIndex] = hasNonLatnMask | symOffset(start)
|
||||
}
|
||||
}
|
||||
w.WriteComment(`
|
||||
|
|
13
vendor/golang.org/x/text/internal/number/gen_common.go
generated
vendored
13
vendor/golang.org/x/text/internal/number/gen_common.go
generated
vendored
|
@ -37,8 +37,19 @@ const (
|
|||
NumSymbolTypes
|
||||
)
|
||||
|
||||
const hasNonLatnMask = 0x8000
|
||||
|
||||
// symOffset is an offset into altSymData if the bit indicated by hasNonLatnMask
|
||||
// is not 0 (with this bit masked out), and an offset into symIndex otherwise.
|
||||
//
|
||||
// TODO: this type can be a byte again if we use an indirection into altsymData
|
||||
// and introduce an alt -> offset slice (the length of this will be number of
|
||||
// alternatives plus 1). This also allows getting rid of the compactTag field
|
||||
// in altSymData. In total this will save about 1K.
|
||||
type symOffset uint16
|
||||
|
||||
type altSymData struct {
|
||||
compactTag uint16
|
||||
symIndex symOffset
|
||||
system system
|
||||
symIndex byte
|
||||
}
|
||||
|
|
58
vendor/golang.org/x/text/internal/number/number.go
generated
vendored
58
vendor/golang.org/x/text/internal/number/number.go
generated
vendored
|
@ -17,7 +17,7 @@ import (
|
|||
// Info holds number formatting configuration data.
|
||||
type Info struct {
|
||||
system systemData // numbering system information
|
||||
symIndex byte // index to symbols
|
||||
symIndex symOffset // index to symbols
|
||||
}
|
||||
|
||||
// InfoFromLangID returns a Info for the given compact language identifier and
|
||||
|
@ -26,16 +26,16 @@ type Info struct {
|
|||
func InfoFromLangID(compactIndex int, numberSystem string) Info {
|
||||
p := langToDefaults[compactIndex]
|
||||
// Lookup the entry for the language.
|
||||
pSymIndex := byte(0) // Default: Latin, default symbols
|
||||
pSymIndex := symOffset(0) // Default: Latin, default symbols
|
||||
system, ok := systemMap[numberSystem]
|
||||
if !ok {
|
||||
// Take the value for the default numbering system. This is by far the
|
||||
// most common case as an alternative numbering system is hardly used.
|
||||
if p&0x80 == 0 {
|
||||
if p&hasNonLatnMask == 0 { // Latn digits.
|
||||
pSymIndex = p
|
||||
} else {
|
||||
} else { // Non-Latn or multiple numbering systems.
|
||||
// Take the first entry from the alternatives list.
|
||||
data := langToAlt[p&^0x80]
|
||||
data := langToAlt[p&^hasNonLatnMask]
|
||||
pSymIndex = data.symIndex
|
||||
system = data.system
|
||||
}
|
||||
|
@ -43,8 +43,8 @@ func InfoFromLangID(compactIndex int, numberSystem string) Info {
|
|||
langIndex := compactIndex
|
||||
ns := system
|
||||
outerLoop:
|
||||
for {
|
||||
if p&0x80 == 0 {
|
||||
for ; ; p = langToDefaults[langIndex] {
|
||||
if p&hasNonLatnMask == 0 {
|
||||
if ns == 0 {
|
||||
// The index directly points to the symbol data.
|
||||
pSymIndex = p
|
||||
|
@ -52,30 +52,32 @@ func InfoFromLangID(compactIndex int, numberSystem string) Info {
|
|||
}
|
||||
// Move to the parent and retry.
|
||||
langIndex = int(internal.Parent[langIndex])
|
||||
}
|
||||
// The index points to a list of symbol data indexes.
|
||||
for _, e := range langToAlt[p&^0x80:] {
|
||||
if int(e.compactTag) != langIndex {
|
||||
if langIndex == 0 {
|
||||
// The CLDR root defines full symbol information for all
|
||||
// numbering systems (even though mostly by means of
|
||||
// aliases). This means that we will never fall back to
|
||||
// the default of the language. Also, the loop is
|
||||
// guaranteed to terminate as a consequence.
|
||||
ns = numLatn
|
||||
// Fall back to Latin and start from the original
|
||||
// language. See
|
||||
// http://unicode.org/reports/tr35/#Locale_Inheritance.
|
||||
langIndex = compactIndex
|
||||
} else {
|
||||
} else {
|
||||
// The index points to a list of symbol data indexes.
|
||||
for _, e := range langToAlt[p&^hasNonLatnMask:] {
|
||||
if int(e.compactTag) != langIndex {
|
||||
if langIndex == 0 {
|
||||
// The CLDR root defines full symbol information for
|
||||
// all numbering systems (even though mostly by
|
||||
// means of aliases). Fall back to the default entry
|
||||
// for Latn if there is no data for the numbering
|
||||
// system of this language.
|
||||
if ns == 0 {
|
||||
break
|
||||
}
|
||||
// Fall back to Latin and start from the original
|
||||
// language. See
|
||||
// http://unicode.org/reports/tr35/#Locale_Inheritance.
|
||||
ns = numLatn
|
||||
langIndex = compactIndex
|
||||
continue outerLoop
|
||||
}
|
||||
// Fall back to parent.
|
||||
langIndex = int(internal.Parent[langIndex])
|
||||
} else if e.system == ns {
|
||||
pSymIndex = e.symIndex
|
||||
break outerLoop
|
||||
}
|
||||
break
|
||||
}
|
||||
if e.system == ns {
|
||||
pSymIndex = e.symIndex
|
||||
break outerLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
vendor/golang.org/x/text/internal/number/number_test.go
generated
vendored
4
vendor/golang.org/x/text/internal/number/number_test.go
generated
vendored
|
@ -31,6 +31,10 @@ func TestInfo(t *testing.T) {
|
|||
{"de-CH-oxendict", SymGroup, "’", '9'}, // inherits from de-CH (no compact index)
|
||||
{"de-CH-u-nu-deva", SymGroup, "’", '\u096f'}, // miss -> latn -> de-CH
|
||||
|
||||
{"bn-u-nu-beng", SymGroup, ",", '\u09ef'},
|
||||
{"bn-u-nu-deva", SymGroup, ",", '\u096f'},
|
||||
{"bn-u-nu-latn", SymGroup, ",", '9'},
|
||||
|
||||
{"pa", SymExponential, "E", '9'},
|
||||
|
||||
// "×۱۰^" -> U+00d7 U+06f1 U+06f0^"
|
||||
|
|
1007
vendor/golang.org/x/text/internal/number/tables.go
generated
vendored
1007
vendor/golang.org/x/text/internal/number/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
171
vendor/golang.org/x/text/internal/tables.go
generated
vendored
171
vendor/golang.org/x/text/internal/tables.go
generated
vendored
|
@ -4,9 +4,9 @@ package internal
|
|||
|
||||
// Parent maps a compact index of a tag to the compact index of the parent of
|
||||
// this tag.
|
||||
var Parent = []uint16{ // 754 elements
|
||||
var Parent = []uint16{ // 768 elements
|
||||
// Entry 0 - 3F
|
||||
0x0000, 0x0053, 0x00e5, 0x0000, 0x0003, 0x0003, 0x0000, 0x0006,
|
||||
0x0000, 0x0053, 0x00e8, 0x0000, 0x0003, 0x0003, 0x0000, 0x0006,
|
||||
0x0000, 0x0008, 0x0000, 0x000a, 0x0000, 0x000c, 0x000c, 0x000c,
|
||||
0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c,
|
||||
0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c,
|
||||
|
@ -18,100 +18,101 @@ var Parent = []uint16{ // 754 elements
|
|||
0x0000, 0x0040, 0x0000, 0x0042, 0x0042, 0x0000, 0x0045, 0x0045,
|
||||
0x0000, 0x0048, 0x0000, 0x004a, 0x0000, 0x0000, 0x004d, 0x004c,
|
||||
0x004c, 0x0000, 0x0051, 0x0051, 0x0051, 0x0051, 0x0000, 0x0056,
|
||||
0x0000, 0x0058, 0x0000, 0x005a, 0x0000, 0x005c, 0x005c, 0x0000,
|
||||
0x005f, 0x0000, 0x0061, 0x0000, 0x0063, 0x0000, 0x0065, 0x0065,
|
||||
0x0000, 0x0068, 0x0000, 0x006a, 0x006a, 0x006a, 0x006a, 0x006a,
|
||||
0x006a, 0x006a, 0x0000, 0x0072, 0x0000, 0x0074, 0x0000, 0x0076,
|
||||
0x0000, 0x0000, 0x0079, 0x0000, 0x007b, 0x0000, 0x007d, 0x0000,
|
||||
0x0056, 0x0000, 0x0059, 0x0000, 0x005b, 0x0000, 0x005d, 0x0000,
|
||||
0x005f, 0x005f, 0x0000, 0x0062, 0x0000, 0x0064, 0x0000, 0x0066,
|
||||
0x0000, 0x0068, 0x0068, 0x0000, 0x006b, 0x0000, 0x006d, 0x006d,
|
||||
0x006d, 0x006d, 0x006d, 0x006d, 0x006d, 0x0000, 0x0075, 0x0000,
|
||||
0x0077, 0x0000, 0x0079, 0x0000, 0x0000, 0x007c, 0x0000, 0x007e,
|
||||
// Entry 80 - BF
|
||||
0x007f, 0x007f, 0x0000, 0x0082, 0x0082, 0x0000, 0x0085, 0x0086,
|
||||
0x0086, 0x0086, 0x0085, 0x0087, 0x0086, 0x0086, 0x0086, 0x0085,
|
||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087, 0x0086,
|
||||
0x0086, 0x0086, 0x0086, 0x0087, 0x0086, 0x0087, 0x0086, 0x0086,
|
||||
0x0087, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
|
||||
0x0086, 0x0086, 0x0085, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
|
||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
|
||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0085, 0x0086, 0x0085, 0x0086,
|
||||
0x0000, 0x0080, 0x0000, 0x0082, 0x0082, 0x0000, 0x0085, 0x0085,
|
||||
0x0000, 0x0088, 0x0089, 0x0089, 0x0089, 0x0088, 0x008a, 0x0089,
|
||||
0x0089, 0x0089, 0x0088, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089,
|
||||
0x0089, 0x008a, 0x0089, 0x0089, 0x0089, 0x0089, 0x008a, 0x0089,
|
||||
0x008a, 0x0089, 0x0089, 0x008a, 0x0089, 0x0089, 0x0089, 0x0089,
|
||||
0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0088, 0x0089, 0x0089,
|
||||
0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089,
|
||||
0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0088,
|
||||
// Entry C0 - FF
|
||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087,
|
||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0085,
|
||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087, 0x0086, 0x0086,
|
||||
0x0087, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
|
||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0085, 0x0085, 0x0086, 0x0086,
|
||||
0x0085, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0000, 0x00ee,
|
||||
0x0000, 0x00f0, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f1,
|
||||
0x00f1, 0x00f1, 0x00f1, 0x00f0, 0x00f1, 0x00f0, 0x00f0, 0x00f1,
|
||||
0x0089, 0x0088, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089,
|
||||
0x0089, 0x0089, 0x008a, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089,
|
||||
0x0089, 0x0089, 0x0088, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089,
|
||||
0x008a, 0x0089, 0x0089, 0x008a, 0x0089, 0x0089, 0x0089, 0x0089,
|
||||
0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0089, 0x0088,
|
||||
0x0088, 0x0089, 0x0089, 0x0088, 0x0089, 0x0089, 0x0089, 0x0089,
|
||||
0x0089, 0x0000, 0x00f1, 0x0000, 0x00f3, 0x00f4, 0x00f4, 0x00f4,
|
||||
0x00f4, 0x00f4, 0x00f4, 0x00f4, 0x00f4, 0x00f4, 0x00f3, 0x00f4,
|
||||
// Entry 100 - 13F
|
||||
0x00f1, 0x00f0, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f0, 0x00f1,
|
||||
0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x0000, 0x010d, 0x0000,
|
||||
0x010f, 0x0000, 0x0111, 0x0000, 0x0113, 0x0113, 0x0000, 0x0116,
|
||||
0x0116, 0x0116, 0x0116, 0x0000, 0x011b, 0x0000, 0x011d, 0x0000,
|
||||
0x011f, 0x011f, 0x0000, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
|
||||
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
|
||||
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
|
||||
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
|
||||
0x00f3, 0x00f3, 0x00f4, 0x00f4, 0x00f3, 0x00f4, 0x00f4, 0x00f4,
|
||||
0x00f4, 0x00f3, 0x00f4, 0x00f4, 0x00f4, 0x00f4, 0x00f4, 0x00f4,
|
||||
0x0000, 0x0110, 0x0000, 0x0112, 0x0000, 0x0114, 0x0000, 0x0116,
|
||||
0x0116, 0x0000, 0x0119, 0x0119, 0x0119, 0x0119, 0x0000, 0x011e,
|
||||
0x0000, 0x0120, 0x0000, 0x0122, 0x0122, 0x0000, 0x0125, 0x0125,
|
||||
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
|
||||
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
|
||||
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
|
||||
// Entry 140 - 17F
|
||||
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
|
||||
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
|
||||
0x0122, 0x0000, 0x0151, 0x0000, 0x0153, 0x0000, 0x0155, 0x0000,
|
||||
0x0157, 0x0000, 0x0159, 0x0000, 0x015b, 0x015b, 0x015b, 0x0000,
|
||||
0x015f, 0x0000, 0x0000, 0x0162, 0x0000, 0x0164, 0x0000, 0x0166,
|
||||
0x0166, 0x0166, 0x0000, 0x016a, 0x0000, 0x016c, 0x0000, 0x016e,
|
||||
0x0000, 0x0170, 0x0170, 0x0000, 0x0173, 0x0000, 0x0175, 0x0000,
|
||||
0x0177, 0x0000, 0x0179, 0x0000, 0x017b, 0x0000, 0x017d, 0x0000,
|
||||
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
|
||||
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
|
||||
0x0125, 0x0125, 0x0125, 0x0125, 0x0000, 0x0154, 0x0000, 0x0156,
|
||||
0x0000, 0x0158, 0x0000, 0x015a, 0x0000, 0x015c, 0x0000, 0x015e,
|
||||
0x015e, 0x015e, 0x0000, 0x0162, 0x0000, 0x0000, 0x0165, 0x0000,
|
||||
0x0167, 0x0000, 0x0169, 0x0169, 0x0169, 0x0000, 0x016d, 0x0000,
|
||||
0x016f, 0x0000, 0x0171, 0x0000, 0x0173, 0x0173, 0x0000, 0x0176,
|
||||
0x0000, 0x0178, 0x0000, 0x017a, 0x0000, 0x017c, 0x0000, 0x017e,
|
||||
// Entry 180 - 1BF
|
||||
0x017f, 0x0000, 0x0181, 0x0181, 0x0181, 0x0181, 0x0000, 0x0000,
|
||||
0x0187, 0x0000, 0x0000, 0x018a, 0x0000, 0x018c, 0x0000, 0x0000,
|
||||
0x018f, 0x0000, 0x0191, 0x0000, 0x0000, 0x0194, 0x0000, 0x0000,
|
||||
0x0197, 0x0000, 0x0199, 0x0000, 0x019b, 0x0000, 0x019d, 0x0000,
|
||||
0x0000, 0x0180, 0x0000, 0x0000, 0x0183, 0x0000, 0x0185, 0x0185,
|
||||
0x0185, 0x0185, 0x0000, 0x0000, 0x018b, 0x0000, 0x0000, 0x018e,
|
||||
0x0000, 0x0190, 0x0000, 0x0000, 0x0193, 0x0000, 0x0195, 0x0000,
|
||||
0x0000, 0x0198, 0x0000, 0x0000, 0x019b, 0x0000, 0x019d, 0x0000,
|
||||
0x019f, 0x0000, 0x01a1, 0x0000, 0x01a3, 0x0000, 0x01a5, 0x0000,
|
||||
0x01a7, 0x0000, 0x01a9, 0x0000, 0x01ab, 0x01ab, 0x0000, 0x01ae,
|
||||
0x0000, 0x01b0, 0x0000, 0x01b2, 0x0000, 0x01b4, 0x0000, 0x01b6,
|
||||
0x0000, 0x0000, 0x01b9, 0x0000, 0x01bb, 0x0000, 0x01bd, 0x0000,
|
||||
0x01a7, 0x0000, 0x01a9, 0x0000, 0x01ab, 0x0000, 0x01ad, 0x0000,
|
||||
0x01af, 0x01af, 0x0000, 0x01b2, 0x0000, 0x01b4, 0x0000, 0x01b6,
|
||||
0x0000, 0x01b8, 0x0000, 0x01ba, 0x0000, 0x0000, 0x01bd, 0x0000,
|
||||
// Entry 1C0 - 1FF
|
||||
0x01bf, 0x0000, 0x01c1, 0x0000, 0x01c3, 0x0000, 0x01c5, 0x01c5,
|
||||
0x01c5, 0x01c5, 0x0000, 0x01ca, 0x0000, 0x01cc, 0x01cc, 0x0000,
|
||||
0x01cf, 0x0000, 0x01d1, 0x0000, 0x01d3, 0x0000, 0x01d5, 0x0000,
|
||||
0x01d7, 0x0000, 0x01d9, 0x01d9, 0x0000, 0x01dc, 0x0000, 0x01de,
|
||||
0x01bf, 0x0000, 0x01c1, 0x0000, 0x01c3, 0x0000, 0x01c5, 0x0000,
|
||||
0x01c7, 0x0000, 0x01c9, 0x01c9, 0x01c9, 0x01c9, 0x0000, 0x01ce,
|
||||
0x0000, 0x01d0, 0x01d0, 0x0000, 0x01d3, 0x0000, 0x01d5, 0x0000,
|
||||
0x01d7, 0x0000, 0x01d9, 0x0000, 0x01db, 0x0000, 0x01dd, 0x01dd,
|
||||
0x0000, 0x01e0, 0x0000, 0x01e2, 0x0000, 0x01e4, 0x0000, 0x01e6,
|
||||
0x0000, 0x01e8, 0x0000, 0x01ea, 0x0000, 0x01ec, 0x0000, 0x01ee,
|
||||
0x01ee, 0x01ee, 0x0000, 0x01f2, 0x0000, 0x01f4, 0x0000, 0x01f6,
|
||||
0x0000, 0x01f8, 0x0000, 0x0000, 0x01fb, 0x0000, 0x01fd, 0x01fd,
|
||||
0x0000, 0x01f0, 0x0000, 0x01f2, 0x01f2, 0x01f2, 0x0000, 0x01f6,
|
||||
0x0000, 0x01f8, 0x0000, 0x01fa, 0x0000, 0x01fc, 0x0000, 0x0000,
|
||||
// Entry 200 - 23F
|
||||
0x0000, 0x0200, 0x0000, 0x0202, 0x0202, 0x0000, 0x0205, 0x0205,
|
||||
0x0000, 0x0208, 0x0208, 0x0208, 0x0208, 0x0208, 0x0208, 0x0208,
|
||||
0x0000, 0x0210, 0x0000, 0x0212, 0x0000, 0x0214, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x021a, 0x0000, 0x0000, 0x021d, 0x0000,
|
||||
0x021f, 0x021f, 0x0000, 0x0222, 0x0000, 0x0224, 0x0224, 0x0000,
|
||||
0x0000, 0x0228, 0x0227, 0x0227, 0x0000, 0x0000, 0x022d, 0x0000,
|
||||
0x022f, 0x0000, 0x0231, 0x0000, 0x023d, 0x0233, 0x023d, 0x023d,
|
||||
0x023d, 0x023d, 0x023d, 0x023d, 0x023d, 0x0233, 0x023d, 0x023d,
|
||||
0x01ff, 0x0000, 0x0201, 0x0201, 0x0000, 0x0204, 0x0000, 0x0206,
|
||||
0x0206, 0x0000, 0x0209, 0x0209, 0x0000, 0x020c, 0x020c, 0x020c,
|
||||
0x020c, 0x020c, 0x020c, 0x020c, 0x0000, 0x0214, 0x0000, 0x0216,
|
||||
0x0000, 0x0218, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x021e,
|
||||
0x0000, 0x0000, 0x0221, 0x0000, 0x0223, 0x0223, 0x0000, 0x0226,
|
||||
0x0000, 0x0228, 0x0228, 0x0000, 0x0000, 0x022c, 0x022b, 0x022b,
|
||||
0x0000, 0x0000, 0x0231, 0x0000, 0x0233, 0x0000, 0x0235, 0x0000,
|
||||
0x0241, 0x0237, 0x0241, 0x0241, 0x0241, 0x0241, 0x0241, 0x0241,
|
||||
// Entry 240 - 27F
|
||||
0x0000, 0x0240, 0x0240, 0x0240, 0x0000, 0x0244, 0x0000, 0x0246,
|
||||
0x0000, 0x0248, 0x0248, 0x0000, 0x024b, 0x0000, 0x024d, 0x024d,
|
||||
0x024d, 0x024d, 0x024d, 0x024d, 0x0000, 0x0254, 0x0000, 0x0256,
|
||||
0x0000, 0x0258, 0x0000, 0x025a, 0x0000, 0x025c, 0x0000, 0x0000,
|
||||
0x025f, 0x025f, 0x025f, 0x0000, 0x0263, 0x0000, 0x0265, 0x0000,
|
||||
0x0267, 0x0000, 0x0000, 0x026a, 0x0269, 0x0269, 0x0000, 0x026e,
|
||||
0x0000, 0x0270, 0x0000, 0x0272, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0277, 0x0000, 0x0000, 0x027a, 0x0000, 0x027c, 0x027c, 0x027c,
|
||||
0x0241, 0x0237, 0x0241, 0x0241, 0x0000, 0x0244, 0x0244, 0x0244,
|
||||
0x0000, 0x0248, 0x0000, 0x024a, 0x0000, 0x024c, 0x024c, 0x0000,
|
||||
0x024f, 0x0000, 0x0251, 0x0251, 0x0251, 0x0251, 0x0251, 0x0251,
|
||||
0x0000, 0x0258, 0x0000, 0x025a, 0x0000, 0x025c, 0x0000, 0x025e,
|
||||
0x0000, 0x0260, 0x0000, 0x0262, 0x0000, 0x0000, 0x0265, 0x0265,
|
||||
0x0265, 0x0000, 0x0269, 0x0000, 0x026b, 0x0000, 0x026d, 0x0000,
|
||||
0x0000, 0x0270, 0x026f, 0x026f, 0x0000, 0x0274, 0x0000, 0x0276,
|
||||
0x0000, 0x0278, 0x0000, 0x0000, 0x0000, 0x0000, 0x027d, 0x0000,
|
||||
// Entry 280 - 2BF
|
||||
0x027c, 0x0000, 0x0281, 0x0281, 0x0281, 0x0000, 0x0285, 0x0285,
|
||||
0x0285, 0x0285, 0x0285, 0x0000, 0x028b, 0x028b, 0x028b, 0x028b,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0293, 0x0293, 0x0293, 0x0000,
|
||||
0x0297, 0x0297, 0x0297, 0x0297, 0x0000, 0x0000, 0x029d, 0x029d,
|
||||
0x029d, 0x029d, 0x0000, 0x02a2, 0x0000, 0x02a4, 0x02a4, 0x0000,
|
||||
0x02a7, 0x0000, 0x02a9, 0x02a9, 0x0000, 0x0000, 0x02ad, 0x0000,
|
||||
0x0000, 0x02b0, 0x0000, 0x02b2, 0x02b2, 0x0000, 0x0000, 0x02b6,
|
||||
0x0000, 0x02b8, 0x0000, 0x02ba, 0x0000, 0x02bc, 0x0000, 0x02be,
|
||||
0x0000, 0x0280, 0x0000, 0x0282, 0x0282, 0x0282, 0x0282, 0x0000,
|
||||
0x0287, 0x0287, 0x0287, 0x0000, 0x028b, 0x028b, 0x028b, 0x028b,
|
||||
0x028b, 0x0000, 0x0291, 0x0291, 0x0291, 0x0291, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0299, 0x0299, 0x0299, 0x0000, 0x029d, 0x029d,
|
||||
0x029d, 0x029d, 0x0000, 0x0000, 0x02a3, 0x02a3, 0x02a3, 0x02a3,
|
||||
0x0000, 0x02a8, 0x0000, 0x02aa, 0x02aa, 0x0000, 0x02ad, 0x0000,
|
||||
0x02af, 0x0000, 0x02b1, 0x02b1, 0x0000, 0x0000, 0x02b5, 0x0000,
|
||||
0x0000, 0x02b8, 0x0000, 0x02ba, 0x02ba, 0x0000, 0x0000, 0x02be,
|
||||
// Entry 2C0 - 2FF
|
||||
0x02be, 0x0000, 0x0000, 0x02c2, 0x0000, 0x02c4, 0x02c1, 0x02c1,
|
||||
0x0000, 0x0000, 0x02c9, 0x02c8, 0x02c8, 0x0000, 0x0000, 0x02ce,
|
||||
0x0000, 0x02d0, 0x0000, 0x02d2, 0x0000, 0x0000, 0x02d5, 0x0000,
|
||||
0x0000, 0x0000, 0x02d9, 0x0000, 0x02db, 0x0000, 0x02dd, 0x0000,
|
||||
0x02df, 0x02df, 0x0000, 0x02e2, 0x0000, 0x02e4, 0x0000, 0x02e6,
|
||||
0x02e6, 0x02e6, 0x02e6, 0x02e6, 0x0000, 0x02ec, 0x02ed, 0x02ec,
|
||||
0x0000, 0x02f0,
|
||||
} // Size: 1532 bytes
|
||||
0x0000, 0x02c0, 0x0000, 0x02c2, 0x0000, 0x02c4, 0x0000, 0x02c6,
|
||||
0x0000, 0x02c8, 0x02c8, 0x0000, 0x0000, 0x02cc, 0x0000, 0x02ce,
|
||||
0x02cb, 0x02cb, 0x0000, 0x0000, 0x02d3, 0x02d2, 0x02d2, 0x0000,
|
||||
0x0000, 0x02d8, 0x0000, 0x02da, 0x0000, 0x02dc, 0x0000, 0x0000,
|
||||
0x02df, 0x0000, 0x02e1, 0x0000, 0x0000, 0x02e4, 0x0000, 0x02e6,
|
||||
0x0000, 0x02e8, 0x0000, 0x02ea, 0x02ea, 0x0000, 0x0000, 0x02ee,
|
||||
0x02ed, 0x02ed, 0x0000, 0x02f2, 0x0000, 0x02f4, 0x02f4, 0x02f4,
|
||||
0x02f4, 0x02f4, 0x0000, 0x02fa, 0x02fb, 0x02fa, 0x0000, 0x02fe,
|
||||
} // Size: 1560 bytes
|
||||
|
||||
// Total table size 1532 bytes (1KiB); checksum: 90718A2
|
||||
// Total table size 1560 bytes (1KiB); checksum: 4897681C
|
||||
|
|
2
vendor/golang.org/x/text/language/display/dict_test.go
generated
vendored
2
vendor/golang.org/x/text/language/display/dict_test.go
generated
vendored
|
@ -16,7 +16,7 @@ func TestLinking(t *testing.T) {
|
|||
compact := getSize(t, `display.English.Languages().Name(language.English)`)
|
||||
|
||||
if d := base - compact; d < 1.5*1024*1024 {
|
||||
t.Errorf("size(base)-size(compact) was %d; want > 1.5MB", base, compact)
|
||||
t.Errorf("size(base) - size(compact) = %d - %d = was %d; want > 1.5MB", base, compact, d)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
33
vendor/golang.org/x/text/language/display/display_test.go
generated
vendored
33
vendor/golang.org/x/text/language/display/display_test.go
generated
vendored
|
@ -371,9 +371,6 @@ func TestTag(t *testing.T) {
|
|||
{"sr-Latn", "sr-Latn-ME", "srpskohrvatski (Crna Gora)"},
|
||||
// Double script and region
|
||||
{"nl", "en-Cyrl-BE", "Engels (Cyrillisch, België)"},
|
||||
// Canonical equivalents.
|
||||
{"ro", "ro-MD", "moldovenească"},
|
||||
{"ro", "mo", "moldovenească"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.dict+"/"+tt.tag, func(t *testing.T) {
|
||||
|
@ -445,9 +442,6 @@ func TestLanguage(t *testing.T) {
|
|||
{"en", "af-NA", "Afrikaans"},
|
||||
{"en", "zu-BR", "Zulu"},
|
||||
{"agq", "zh-Hant", "|[language: zh-Hant]"},
|
||||
// Canonical equivalents.
|
||||
{"ro", "ro-MD", "moldovenească"},
|
||||
{"ro", "mo", "moldovenească"},
|
||||
{"en", "sh", "Serbo-Croatian"},
|
||||
{"en", "sr-Latn", "Serbo-Croatian"},
|
||||
{"en", "sr", "Serbian"},
|
||||
|
@ -540,8 +534,6 @@ func TestRegion(t *testing.T) {
|
|||
{"nl", "NL", "Nederland"},
|
||||
{"en", "US", "United States"},
|
||||
{"en", "ZZ", "Unknown Region"},
|
||||
{"en", "UM", "U.S. Outlying Islands"},
|
||||
{"en-GB", "UM", "U.S. Outlying Islands"},
|
||||
{"en-GB", "NL", "Netherlands"},
|
||||
// Canonical equivalents
|
||||
{"en", "UK", "United Kingdom"},
|
||||
|
@ -628,9 +620,6 @@ func TestSelf(t *testing.T) {
|
|||
{"sr-Latn-ME", "srpskohrvatski"},
|
||||
{"sr-Cyrl-ME", "српски"},
|
||||
{"sr-NL", "српски"},
|
||||
// Canonical equivalents.
|
||||
{"ro-MD", "moldovenească"},
|
||||
{"mo", "moldovenească"},
|
||||
// NOTE: kk is defined, but in Cyrillic script. For China, Arab is the
|
||||
// dominant script. We do not have data for kk-Arab and we chose to not
|
||||
// fall back in such cases.
|
||||
|
@ -644,6 +633,27 @@ func TestSelf(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestEquivalence(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
namer Namer
|
||||
}{
|
||||
{"Self", Self},
|
||||
{"Tags", Tags(language.Romanian)},
|
||||
{"Languages", Languages(language.Romanian)},
|
||||
{"Scripts", Scripts(language.Romanian)},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
ro := tc.namer.Name(language.Raw.MustParse("ro-MD"))
|
||||
mo := tc.namer.Name(language.Raw.MustParse("mo"))
|
||||
if ro != mo {
|
||||
t.Errorf("%q != %q", ro, mo)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDictionaryLang(t *testing.T) {
|
||||
tests := []struct {
|
||||
d *Dictionary
|
||||
|
@ -693,7 +703,6 @@ func TestDictionaryScript(t *testing.T) {
|
|||
name string
|
||||
}{
|
||||
{English, "Cyrl", "Cyrillic"},
|
||||
{Portuguese, "Gujr", "gujerati"},
|
||||
{EuropeanPortuguese, "Gujr", "guzerate"},
|
||||
}
|
||||
for i, test := range tests {
|
||||
|
|
45330
vendor/golang.org/x/text/language/display/tables.go
generated
vendored
45330
vendor/golang.org/x/text/language/display/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
10
vendor/golang.org/x/text/language/gen.go
generated
vendored
10
vendor/golang.org/x/text/language/gen.go
generated
vendored
|
@ -1497,8 +1497,14 @@ func (b *builder) writeMatchData() {
|
|||
if desired == supported && desired == "*_*_*" {
|
||||
continue
|
||||
}
|
||||
if desired != supported { // (Weird but correct.)
|
||||
log.Fatalf("not supported: desired=%q; supported=%q", desired, supported)
|
||||
if desired != supported {
|
||||
// This is now supported by CLDR, but only one case, which
|
||||
// should already be covered by paradigm locales. For instance,
|
||||
// test case "und, en, en-GU, en-IN, en-GB ; en-ZA ; en-GB" in
|
||||
// testdata/CLDRLocaleMatcherTest.txt tests this.
|
||||
if supported != "en_*_GB" {
|
||||
log.Fatalf("not supported: desired=%q; supported=%q", desired, supported)
|
||||
}
|
||||
continue
|
||||
}
|
||||
ri := regionIntelligibility{
|
||||
|
|
2
vendor/golang.org/x/text/language/gen_index.go
generated
vendored
2
vendor/golang.org/x/text/language/gen_index.go
generated
vendored
|
@ -49,7 +49,7 @@ func main() {
|
|||
defer func() {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
if _, err = w.WriteGo(buf, "language"); err != nil {
|
||||
if _, err = w.WriteGo(buf, "language", ""); err != nil {
|
||||
log.Fatalf("Error formatting file index.go: %v", err)
|
||||
}
|
||||
|
||||
|
|
1372
vendor/golang.org/x/text/language/index.go
generated
vendored
1372
vendor/golang.org/x/text/language/index.go
generated
vendored
File diff suppressed because it is too large
Load diff
20
vendor/golang.org/x/text/language/language.go
generated
vendored
20
vendor/golang.org/x/text/language/language.go
generated
vendored
|
@ -299,6 +299,26 @@ func (t Tag) String() string {
|
|||
return string(buf[:t.genCoreBytes(buf[:])])
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (t Tag) MarshalText() (text []byte, err error) {
|
||||
if t.str != "" {
|
||||
text = append(text, t.str...)
|
||||
} else if t.script == 0 && t.region == 0 {
|
||||
text = append(text, t.lang.String()...)
|
||||
} else {
|
||||
buf := [maxCoreSize]byte{}
|
||||
text = buf[:t.genCoreBytes(buf[:])]
|
||||
}
|
||||
return text, nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (t *Tag) UnmarshalText(text []byte) error {
|
||||
tag, err := Raw.Parse(string(text))
|
||||
*t = tag
|
||||
return err
|
||||
}
|
||||
|
||||
// Base returns the base language of the language tag. If the base language is
|
||||
// unspecified, an attempt will be made to infer it from the context.
|
||||
// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change.
|
||||
|
|
41
vendor/golang.org/x/text/language/language_test.go
generated
vendored
41
vendor/golang.org/x/text/language/language_test.go
generated
vendored
|
@ -91,11 +91,11 @@ func TestCompactIndex(t *testing.T) {
|
|||
{"ca-ES-valencia-u-co-phonebk", 1, true},
|
||||
{"ca-ES-valencia-u-co-phonebk-va-posix", 0, false},
|
||||
{"x-klingon", 0, false},
|
||||
{"en-US", 229, true},
|
||||
{"en-US", 232, true},
|
||||
{"en-US-u-va-posix", 2, true},
|
||||
{"en", 133, true},
|
||||
{"en-u-co-phonebk", 133, true},
|
||||
{"en-001", 134, true},
|
||||
{"en", 136, true},
|
||||
{"en-u-co-phonebk", 136, true},
|
||||
{"en-001", 137, true},
|
||||
{"sh", 0, false}, // We don't normalize.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
@ -106,6 +106,39 @@ func TestCompactIndex(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMarshal(t *testing.T) {
|
||||
testCases := []string{
|
||||
// TODO: these values will change with each CLDR update. This issue
|
||||
// will be solved if we decide to fix the indexes.
|
||||
"und",
|
||||
"ca-ES-valencia",
|
||||
"ca-ES-valencia-u-va-posix",
|
||||
"ca-ES-valencia-u-co-phonebk",
|
||||
"ca-ES-valencia-u-co-phonebk-va-posix",
|
||||
"x-klingon",
|
||||
"en-US",
|
||||
"en-US-u-va-posix",
|
||||
"en",
|
||||
"en-u-co-phonebk",
|
||||
"en-001",
|
||||
"sh",
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
var tag Tag
|
||||
err := tag.UnmarshalText([]byte(tc))
|
||||
if err != nil {
|
||||
t.Errorf("UnmarshalText(%q): unexpected error: %v", tc, err)
|
||||
}
|
||||
b, err := tag.MarshalText()
|
||||
if err != nil {
|
||||
t.Errorf("MarshalText(%q): unexpected error: %v", tc, err)
|
||||
}
|
||||
if got := string(b); got != tc {
|
||||
t.Errorf("%s: got %q; want %q", tc, got, tc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBase(t *testing.T) {
|
||||
tests := []struct {
|
||||
loc, lang string
|
||||
|
|
4871
vendor/golang.org/x/text/language/tables.go
generated
vendored
4871
vendor/golang.org/x/text/language/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
14
vendor/golang.org/x/text/message/catalog.go
generated
vendored
14
vendor/golang.org/x/text/message/catalog.go
generated
vendored
|
@ -12,10 +12,18 @@ import (
|
|||
"golang.org/x/text/message/catalog"
|
||||
)
|
||||
|
||||
// DefaultCatalog is used by SetString.
|
||||
var DefaultCatalog *catalog.Catalog = defaultCatalog
|
||||
// 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
|
||||
}
|
||||
|
||||
var defaultCatalog = catalog.New()
|
||||
// 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 {
|
||||
|
|
161
vendor/golang.org/x/text/message/catalog/catalog.go
generated
vendored
161
vendor/golang.org/x/text/message/catalog/catalog.go
generated
vendored
|
@ -156,23 +156,127 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/text/internal"
|
||||
|
||||
"golang.org/x/text/internal/catmsg"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// A Catalog holds translations for messages for supported languages.
|
||||
type Catalog struct {
|
||||
// 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{}
|
||||
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.
|
||||
|
@ -186,22 +290,17 @@ type Option func(*options)
|
|||
//
|
||||
// func Dict(tag language.Tag, d ...Dictionary) Option
|
||||
|
||||
// New returns a new Catalog.
|
||||
func New(opts ...Option) *Catalog {
|
||||
c := &Catalog{}
|
||||
// NewBuilder returns an empty mutable Catalog.
|
||||
func NewBuilder(opts ...Option) *Builder {
|
||||
c := &Builder{}
|
||||
for _, o := range opts {
|
||||
o(&c.options)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// Languages returns all languages for which the Catalog contains variants.
|
||||
func (c *Catalog) Languages() []language.Tag {
|
||||
return c.index.languages()
|
||||
}
|
||||
|
||||
// SetString is shorthand for Set(tag, key, String(msg)).
|
||||
func (c *Catalog) SetString(tag language.Tag, key string, msg string) error {
|
||||
func (c *Builder) SetString(tag language.Tag, key string, msg string) error {
|
||||
return c.set(tag, key, &c.index, String(msg))
|
||||
}
|
||||
|
||||
|
@ -209,26 +308,20 @@ func (c *Catalog) SetString(tag language.Tag, key string, msg string) error {
|
|||
//
|
||||
// When evaluation this message, the first Message in the sequence to msgs to
|
||||
// evaluate to a string will be the message returned.
|
||||
func (c *Catalog) Set(tag language.Tag, key string, msg ...Message) error {
|
||||
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 *Catalog) SetMacro(tag language.Tag, name string, msg ...Message) error {
|
||||
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")
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// String specifies a plain message string. It can be used as fallback if no
|
||||
// other strings match or as a simple standalone message.
|
||||
//
|
||||
|
@ -247,44 +340,28 @@ func Var(name string, msg ...Message) Message {
|
|||
return &catmsg.Var{Name: name, Message: firstInSequence(msg)}
|
||||
}
|
||||
|
||||
// firstInSequence is a message type that prints the first message in the
|
||||
// sequence that resolves to a match for the given substitution arguments.
|
||||
type firstInSequence []Message
|
||||
|
||||
func (s firstInSequence) Compile(e *catmsg.Encoder) error {
|
||||
e.EncodeMessageType(catmsg.First)
|
||||
err := catmsg.ErrIncomplete
|
||||
for i, m := range s {
|
||||
if err == nil {
|
||||
return fmt.Errorf("catalog: message argument %d is complete and blocks subsequent messages", i-1)
|
||||
}
|
||||
err = e.EncodeMessage(m)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 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 {
|
||||
func (b *Builder) Context(tag language.Tag, r catmsg.Renderer) *Context {
|
||||
return &Context{
|
||||
cat: c,
|
||||
cat: b,
|
||||
tag: tag,
|
||||
dec: catmsg.NewDecoder(tag, r, &dict{&c.macros, 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
|
||||
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.index.lookup(c.tag, key)
|
||||
data, ok := c.cat.lookup(c.tag, key)
|
||||
if !ok {
|
||||
return ErrNotFound
|
||||
}
|
||||
|
|
148
vendor/golang.org/x/text/message/catalog/catalog_test.go
generated
vendored
148
vendor/golang.org/x/text/message/catalog/catalog_test.go
generated
vendored
|
@ -6,11 +6,11 @@ package catalog
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/text/internal"
|
||||
"golang.org/x/text/internal/catmsg"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
@ -20,17 +20,33 @@ type entry struct {
|
|||
msg interface{}
|
||||
}
|
||||
|
||||
var testCases = []struct {
|
||||
desc string
|
||||
cat []entry
|
||||
lookup []entry
|
||||
}{{
|
||||
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{
|
||||
|
@ -45,6 +61,11 @@ var testCases = []struct {
|
|||
{"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{
|
||||
|
@ -52,6 +73,7 @@ var testCases = []struct {
|
|||
{"en-GB", "hello", "Hellø!"},
|
||||
{"en-US", "hello", "Howdy!"},
|
||||
{"en", "greetings", "Greetings!"},
|
||||
{"gsw", "hello", "Grüetzi!"},
|
||||
},
|
||||
lookup: []entry{
|
||||
{"und", "hello", ""},
|
||||
|
@ -70,6 +92,12 @@ var testCases = []struct {
|
|||
{"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{
|
||||
|
@ -103,6 +131,7 @@ var testCases = []struct {
|
|||
{"en", "scopes", "Hello Joe and Jane."},
|
||||
{"en", "missing var", "Hello missing."},
|
||||
},
|
||||
tags: langs("en"),
|
||||
}, {
|
||||
desc: "macros",
|
||||
cat: []entry{
|
||||
|
@ -122,16 +151,29 @@ var testCases = []struct {
|
|||
{"en", "badnum", "Hello $!(BADNUM)."},
|
||||
{"en", "undefined", "Hello undefined."},
|
||||
{"en", "macroU", "Hello macroU!"},
|
||||
}}}
|
||||
},
|
||||
tags: langs("en"),
|
||||
}}
|
||||
|
||||
func initCat(entries []entry) (*Catalog, []language.Tag) {
|
||||
tags := []language.Tag{}
|
||||
cat := New()
|
||||
for _, e := range entries {
|
||||
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)
|
||||
tags = append(tags, tag)
|
||||
switch msg := e.msg.(type) {
|
||||
case string:
|
||||
|
||||
cat.SetString(tag, e.key, msg)
|
||||
case Message:
|
||||
cat.Set(tag, e.key, msg)
|
||||
|
@ -139,23 +181,81 @@ func initCat(entries []entry) (*Catalog, []language.Tag) {
|
|||
cat.Set(tag, e.key, msg...)
|
||||
}
|
||||
}
|
||||
return cat, internal.UniqueTags(tags)
|
||||
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) {
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s", tc.desc), func(t *testing.T) {
|
||||
cat, wantTags := initCat(tc.cat)
|
||||
cat.SetMacro(language.English, "macro1", String("Joe"))
|
||||
cat.SetMacro(language.Und, "macro2", String("${macro1(1)}"))
|
||||
cat.SetMacro(language.English, "macroU", noMatchMessage{})
|
||||
|
||||
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(fmt.Sprintf("%s/%s", e.tag, e.key), func(t *testing.T) {
|
||||
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)
|
||||
|
@ -171,8 +271,10 @@ func TestCatalog(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
t.Run("Builder", func(t *testing.T) { test(t, initBuilder) })
|
||||
t.Run("Catalog", func(t *testing.T) { test(t, initCatalog) })
|
||||
}
|
||||
|
||||
type testRenderer struct {
|
||||
|
|
53
vendor/golang.org/x/text/message/catalog/dict.go
generated
vendored
53
vendor/golang.org/x/text/message/catalog/dict.go
generated
vendored
|
@ -33,7 +33,11 @@ func (d *dict) Lookup(key string) (data string, ok bool) {
|
|||
return d.s.lookup(d.tag, key)
|
||||
}
|
||||
|
||||
func (c *Catalog) set(tag language.Tag, key string, s *store, msg ...Message) error {
|
||||
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()
|
||||
|
@ -45,6 +49,7 @@ func (c *Catalog) set(tag language.Tag, key string, s *store, msg ...Message) er
|
|||
if s.index == nil {
|
||||
s.index = map[language.Tag]msgMap{}
|
||||
}
|
||||
c.matcher = nil
|
||||
s.index[tag] = m
|
||||
}
|
||||
|
||||
|
@ -52,6 +57,23 @@ func (c *Catalog) set(tag language.Tag, key string, s *store, msg ...Message) er
|
|||
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
|
||||
|
@ -76,15 +98,32 @@ func (s *store) lookup(tag language.Tag, key string) (data string, ok bool) {
|
|||
return "", false
|
||||
}
|
||||
|
||||
// Languages returns all languages for which the store contains variants.
|
||||
func (s *store) languages() []language.Tag {
|
||||
// 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()
|
||||
|
||||
tags := make([]language.Tag, 0, len(s.index))
|
||||
for t := range s.index {
|
||||
tags = append(tags, t)
|
||||
return b.unlockedLanguages()
|
||||
}
|
||||
|
||||
func (b *Builder) unlockedLanguages() []language.Tag {
|
||||
s := &b.index
|
||||
if len(s.index) == 0 {
|
||||
return nil
|
||||
}
|
||||
internal.SortTags(tags)
|
||||
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
|
||||
}
|
||||
|
|
15
vendor/golang.org/x/text/message/catalog/go19.go
generated
vendored
Normal file
15
vendor/golang.org/x/text/message/catalog/go19.go
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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
|
23
vendor/golang.org/x/text/message/catalog/gopre19.go
generated
vendored
Normal file
23
vendor/golang.org/x/text/message/catalog/gopre19.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
// 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)
|
||||
}
|
43
vendor/golang.org/x/text/message/catalog_test.go
generated
vendored
Normal file
43
vendor/golang.org/x/text/message/catalog_test.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
6
vendor/golang.org/x/text/message/doc.go
generated
vendored
6
vendor/golang.org/x/text/message/doc.go
generated
vendored
|
@ -11,15 +11,15 @@
|
|||
// 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(language.English)
|
||||
// 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(language.Dutch)
|
||||
// p := message.NewPrinter(message.MatchLanguage("nl"))
|
||||
// p.Println("Hoogte: %f meter", 1244.9) // Prints Hoogte: 1.244,9 meter
|
||||
//
|
||||
// p := message.NewPrinter(language.Bengali)
|
||||
// p := message.NewPrinter(message.MatchLanguage("bn"))
|
||||
// p.Println(123456.78) // Prints ১,২৩,৪৫৬.৭৮
|
||||
//
|
||||
// Printer currently supports numbers and specialized types for which packages
|
||||
|
|
30
vendor/golang.org/x/text/message/fmt_test.go
generated
vendored
Executable file → Normal file
30
vendor/golang.org/x/text/message/fmt_test.go
generated
vendored
Executable file → Normal file
|
@ -1786,7 +1786,12 @@ func TestNilDoesNotBecomeTyped(t *testing.T) {
|
|||
type B struct{}
|
||||
var a *A = nil
|
||||
var b B = B{}
|
||||
got := p.Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) // go vet should complain about this line.
|
||||
|
||||
// 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)
|
||||
|
@ -1864,26 +1869,3 @@ func TestFormatterFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsenum(t *testing.T) {
|
||||
testCases := []struct {
|
||||
s string
|
||||
start, end int
|
||||
num int
|
||||
isnum bool
|
||||
newi int
|
||||
}{
|
||||
{"a123", 0, 4, 0, false, 0},
|
||||
{"1234", 1, 1, 0, false, 1},
|
||||
{"123a", 0, 4, 123, true, 3},
|
||||
{"12a3", 0, 4, 12, true, 2},
|
||||
{"1234", 0, 4, 1234, true, 4},
|
||||
{"1a234", 1, 3, 0, false, 1},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
num, isnum, newi := parsenum(tt.s, tt.start, tt.end)
|
||||
if num != tt.num || isnum != tt.isnum || newi != tt.newi {
|
||||
t.Errorf("parsenum(%q, %d, %d) = %d, %v, %d, want %d, %v, %d", tt.s, tt.start, tt.end, num, isnum, newi, tt.num, tt.isnum, tt.newi)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
150
vendor/golang.org/x/text/message/format.go
generated
vendored
150
vendor/golang.org/x/text/message/format.go
generated
vendored
|
@ -8,6 +8,8 @@ import (
|
|||
"bytes"
|
||||
"strconv"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/text/internal/format"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -20,45 +22,21 @@ const (
|
|||
unsigned = false
|
||||
)
|
||||
|
||||
// flags placed in a separate struct for easy clearing.
|
||||
type fmtFlags struct {
|
||||
widPresent bool
|
||||
precPresent bool
|
||||
minus bool
|
||||
plus bool
|
||||
sharp bool
|
||||
space bool
|
||||
zero bool
|
||||
|
||||
// For the formats %+v %#v, we set the plusV/sharpV flags
|
||||
// and clear the plus/sharp flags since %+v and %#v are in effect
|
||||
// different, flagless formats set at the top level.
|
||||
plusV bool
|
||||
sharpV bool
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
fmtFlags
|
||||
|
||||
wid int // width
|
||||
prec int // precision
|
||||
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) clearflags() {
|
||||
f.fmtFlags = fmtFlags{}
|
||||
}
|
||||
|
||||
func (f *formatInfo) init(buf *bytes.Buffer) {
|
||||
f.ClearFlags()
|
||||
f.buf = buf
|
||||
f.clearflags()
|
||||
}
|
||||
|
||||
// writePadding generates n bytes of padding.
|
||||
|
@ -69,7 +47,7 @@ func (f *formatInfo) writePadding(n int) {
|
|||
f.buf.Grow(n)
|
||||
// Decide which byte the padding should be filled with.
|
||||
padByte := byte(' ')
|
||||
if f.zero {
|
||||
if f.Zero {
|
||||
padByte = byte('0')
|
||||
}
|
||||
// Fill padding with padByte.
|
||||
|
@ -80,12 +58,12 @@ func (f *formatInfo) writePadding(n int) {
|
|||
|
||||
// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
|
||||
func (f *formatInfo) pad(b []byte) {
|
||||
if !f.widPresent || f.wid == 0 {
|
||||
if !f.WidthPresent || f.Width == 0 {
|
||||
f.buf.Write(b)
|
||||
return
|
||||
}
|
||||
width := f.wid - utf8.RuneCount(b)
|
||||
if !f.minus {
|
||||
width := f.Width - utf8.RuneCount(b)
|
||||
if !f.Minus {
|
||||
// left padding
|
||||
f.writePadding(width)
|
||||
f.buf.Write(b)
|
||||
|
@ -98,12 +76,12 @@ func (f *formatInfo) pad(b []byte) {
|
|||
|
||||
// padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
|
||||
func (f *formatInfo) padString(s string) {
|
||||
if !f.widPresent || f.wid == 0 {
|
||||
if !f.WidthPresent || f.Width == 0 {
|
||||
f.buf.WriteString(s)
|
||||
return
|
||||
}
|
||||
width := f.wid - utf8.RuneCountInString(s)
|
||||
if !f.minus {
|
||||
width := f.Width - utf8.RuneCountInString(s)
|
||||
if !f.Minus {
|
||||
// left padding
|
||||
f.writePadding(width)
|
||||
f.buf.WriteString(s)
|
||||
|
@ -131,8 +109,8 @@ func (f *formatInfo) fmt_unicode(u uint64) {
|
|||
// 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
|
||||
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) {
|
||||
|
@ -144,7 +122,7 @@ func (f *formatInfo) fmt_unicode(u uint64) {
|
|||
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)) {
|
||||
if f.Sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
|
||||
i--
|
||||
buf[i] = '\''
|
||||
i -= utf8.RuneLen(rune(u))
|
||||
|
@ -176,10 +154,10 @@ func (f *formatInfo) fmt_unicode(u uint64) {
|
|||
i--
|
||||
buf[i] = 'U'
|
||||
|
||||
oldZero := f.zero
|
||||
f.zero = false
|
||||
oldZero := f.Zero
|
||||
f.Zero = false
|
||||
f.pad(buf[i:])
|
||||
f.zero = oldZero
|
||||
f.Zero = oldZero
|
||||
}
|
||||
|
||||
// fmt_integer formats signed and unsigned integers.
|
||||
|
@ -192,9 +170,9 @@ func (f *formatInfo) fmt_integer(u uint64, base int, isSigned bool, digits strin
|
|||
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.widPresent || f.precPresent {
|
||||
if f.WidthPresent || f.PrecPresent {
|
||||
// Account 3 extra bytes for possible addition of a sign and "0x".
|
||||
width := 3 + f.wid + f.prec // wid and prec are always positive.
|
||||
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)
|
||||
|
@ -205,19 +183,19 @@ func (f *formatInfo) fmt_integer(u uint64, base int, isSigned bool, digits strin
|
|||
// 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
|
||||
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.wid)
|
||||
f.zero = oldZero
|
||||
oldZero := f.Zero
|
||||
f.Zero = false
|
||||
f.writePadding(f.Width)
|
||||
f.Zero = oldZero
|
||||
return
|
||||
}
|
||||
} else if f.zero && f.widPresent {
|
||||
prec = f.wid
|
||||
if negative || f.plus || f.space {
|
||||
} else if f.Zero && f.WidthPresent {
|
||||
prec = f.Width
|
||||
if negative || f.Plus || f.Space {
|
||||
prec-- // leave room for sign
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +243,7 @@ func (f *formatInfo) fmt_integer(u uint64, base int, isSigned bool, digits strin
|
|||
}
|
||||
|
||||
// Various prefixes: 0x, -, etc.
|
||||
if f.sharp {
|
||||
if f.Sharp {
|
||||
switch base {
|
||||
case 8:
|
||||
if buf[i] != '0' {
|
||||
|
@ -284,26 +262,26 @@ func (f *formatInfo) fmt_integer(u uint64, base int, isSigned bool, digits strin
|
|||
if negative {
|
||||
i--
|
||||
buf[i] = '-'
|
||||
} else if f.plus {
|
||||
} else if f.Plus {
|
||||
i--
|
||||
buf[i] = '+'
|
||||
} else if f.space {
|
||||
} 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
|
||||
oldZero := f.Zero
|
||||
f.Zero = false
|
||||
f.pad(buf[i:])
|
||||
f.zero = oldZero
|
||||
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
|
||||
if f.PrecPresent {
|
||||
n := f.Prec
|
||||
for i := range s {
|
||||
n--
|
||||
if n < 0 {
|
||||
|
@ -328,46 +306,46 @@ func (f *formatInfo) fmt_sbx(s string, b []byte, digits string) {
|
|||
length = len(s)
|
||||
}
|
||||
// Set length to not process more bytes than the precision demands.
|
||||
if f.precPresent && f.prec < length {
|
||||
length = f.prec
|
||||
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 {
|
||||
if f.Space {
|
||||
// Each element encoded by two hexadecimals will get a leading 0x or 0X.
|
||||
if f.sharp {
|
||||
if f.Sharp {
|
||||
width *= 2
|
||||
}
|
||||
// Elements will be separated by a space.
|
||||
width += length - 1
|
||||
} else if f.sharp {
|
||||
} 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.widPresent {
|
||||
f.writePadding(f.wid)
|
||||
if f.WidthPresent {
|
||||
f.writePadding(f.Width)
|
||||
}
|
||||
return
|
||||
}
|
||||
// Handle padding to the left.
|
||||
if f.widPresent && f.wid > width && !f.minus {
|
||||
f.writePadding(f.wid - width)
|
||||
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 {
|
||||
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 {
|
||||
if f.Space && i > 0 {
|
||||
// Separate elements with a space.
|
||||
buf.WriteByte(' ')
|
||||
if f.sharp {
|
||||
if f.Sharp {
|
||||
// Add leading 0x or 0X for each element.
|
||||
buf.WriteByte('0')
|
||||
buf.WriteByte(digits[16])
|
||||
|
@ -383,8 +361,8 @@ func (f *formatInfo) fmt_sbx(s string, b []byte, digits string) {
|
|||
buf.WriteByte(digits[c&0xF])
|
||||
}
|
||||
// Handle padding to the right.
|
||||
if f.widPresent && f.wid > width && f.minus {
|
||||
f.writePadding(f.wid - width)
|
||||
if f.WidthPresent && f.Width > width && f.Minus {
|
||||
f.writePadding(f.Width - width)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,12 +381,12 @@ func (f *formatInfo) fmt_bx(b []byte, digits string) {
|
|||
// 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) {
|
||||
if f.Sharp && strconv.CanBackquote(s) {
|
||||
f.padString("`" + s + "`")
|
||||
return
|
||||
}
|
||||
buf := f.intbuf[:0]
|
||||
if f.plus {
|
||||
if f.Plus {
|
||||
f.pad(strconv.AppendQuoteToASCII(buf, s))
|
||||
} else {
|
||||
f.pad(strconv.AppendQuote(buf, s))
|
||||
|
@ -435,7 +413,7 @@ func (f *formatInfo) fmt_qc(c uint64) {
|
|||
r = utf8.RuneError
|
||||
}
|
||||
buf := f.intbuf[:0]
|
||||
if f.plus {
|
||||
if f.Plus {
|
||||
f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
|
||||
} else {
|
||||
f.pad(strconv.AppendQuoteRune(buf, r))
|
||||
|
@ -446,8 +424,8 @@ func (f *formatInfo) fmt_qc(c uint64) {
|
|||
// 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
|
||||
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)
|
||||
|
@ -458,25 +436,25 @@ func (f *formatInfo) fmt_float(v float64, size int, verb rune, prec int) {
|
|||
}
|
||||
// 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 {
|
||||
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
|
||||
oldZero := f.Zero
|
||||
f.Zero = false
|
||||
// Remove sign before NaN if not asked for.
|
||||
if num[1] == 'N' && !f.space && !f.plus {
|
||||
if num[1] == 'N' && !f.Space && !f.Plus {
|
||||
num = num[1:]
|
||||
}
|
||||
f.pad(num)
|
||||
f.zero = oldZero
|
||||
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' {
|
||||
if f.Sharp && verb != 'b' {
|
||||
digits := 0
|
||||
switch verb {
|
||||
case 'v', 'g', 'G':
|
||||
|
@ -515,12 +493,12 @@ func (f *formatInfo) fmt_float(v float64, size int, verb rune, prec int) {
|
|||
num = append(num, tail...)
|
||||
}
|
||||
// We want a sign if asked for and if the sign is not positive.
|
||||
if f.plus || num[0] != '+' {
|
||||
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.widPresent && f.wid > len(num) {
|
||||
if f.Zero && f.WidthPresent && f.Width > len(num) {
|
||||
f.buf.WriteByte(num[0])
|
||||
f.writePadding(f.wid - len(num))
|
||||
f.writePadding(f.Width - len(num))
|
||||
f.buf.Write(num[1:])
|
||||
return
|
||||
}
|
||||
|
|
103
vendor/golang.org/x/text/message/message.go
generated
vendored
103
vendor/golang.org/x/text/message/message.go
generated
vendored
|
@ -8,26 +8,28 @@ 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"
|
||||
)
|
||||
|
||||
// TODO: allow more than one goroutine per printer. This will allow porting from
|
||||
// fmt much less error prone.
|
||||
|
||||
// A Printer implements language-specific formatted I/O analogous to the fmt
|
||||
// package. Only one goroutine may use a Printer at the same time.
|
||||
// package.
|
||||
type Printer struct {
|
||||
// Wrap the fields in a hidden type to hide some of the implemented methods.
|
||||
printer printer
|
||||
// the language
|
||||
tag language.Tag
|
||||
|
||||
// NOTE: limiting one goroutine per Printer allows for many optimizations
|
||||
// and simplifications. We can consider removing this restriction down the
|
||||
// road if it the benefits do not seem to outweigh the disadvantages.
|
||||
toDecimal number.Formatter
|
||||
toScientific number.Formatter
|
||||
|
||||
cat catalog.Catalog
|
||||
}
|
||||
|
||||
type options struct {
|
||||
cat *catalog.Catalog
|
||||
cat catalog.Catalog
|
||||
// TODO:
|
||||
// - allow %s to print integers in written form (tables are likely too large
|
||||
// to enable this by default).
|
||||
|
@ -39,39 +41,42 @@ type options struct {
|
|||
type Option func(o *options)
|
||||
|
||||
// Catalog defines the catalog to be used.
|
||||
func Catalog(c *catalog.Catalog) Option {
|
||||
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,
|
||||
cat: DefaultCatalog,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(options)
|
||||
}
|
||||
p := &Printer{printer{
|
||||
p := &Printer{
|
||||
tag: t,
|
||||
}}
|
||||
p.printer.toDecimal.InitDecimal(t)
|
||||
p.printer.toScientific.InitScientific(t)
|
||||
p.printer.catContext = options.cat.Context(t, &p.printer)
|
||||
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 {
|
||||
p.printer.reset()
|
||||
p.printer.doPrint(a)
|
||||
return p.printer.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) {
|
||||
p.printer.reset()
|
||||
p.printer.doPrint(a)
|
||||
n64, err := io.Copy(w, &p.printer.Buffer)
|
||||
pp := newPrinter(p)
|
||||
pp.doPrint(a)
|
||||
n64, err := io.Copy(w, &pp.Buffer)
|
||||
pp.free()
|
||||
return int(n64), err
|
||||
}
|
||||
|
||||
|
@ -82,16 +87,19 @@ func (p *Printer) Print(a ...interface{}) (n int, err error) {
|
|||
|
||||
// Sprintln is like fmt.Sprintln, but using language-specific formatting.
|
||||
func (p *Printer) Sprintln(a ...interface{}) string {
|
||||
p.printer.reset()
|
||||
p.printer.doPrintln(a)
|
||||
return p.printer.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) {
|
||||
p.printer.reset()
|
||||
p.printer.doPrintln(a)
|
||||
n64, err := io.Copy(w, &p.printer.Buffer)
|
||||
pp := newPrinter(p)
|
||||
pp.doPrintln(a)
|
||||
n64, err := io.Copy(w, &pp.Buffer)
|
||||
pp.free()
|
||||
return int(n64), err
|
||||
}
|
||||
|
||||
|
@ -102,25 +110,34 @@ func (p *Printer) Println(a ...interface{}) (n int, err error) {
|
|||
|
||||
// Sprintf is like fmt.Sprintf, but using language-specific formatting.
|
||||
func (p *Printer) Sprintf(key Reference, a ...interface{}) string {
|
||||
lookupAndFormat(p, key, a)
|
||||
return p.printer.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) {
|
||||
lookupAndFormat(p, key, a)
|
||||
return w.Write(p.printer.Bytes())
|
||||
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) {
|
||||
lookupAndFormat(p, key, a)
|
||||
return os.Stdout.Write(p.printer.Bytes())
|
||||
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.printer.reset()
|
||||
p.printer.args = a
|
||||
func lookupAndFormat(p *printer, r Reference, a []interface{}) {
|
||||
p.fmt.Reset(a)
|
||||
var id, msg string
|
||||
switch v := r.(type) {
|
||||
case string:
|
||||
|
@ -131,9 +148,9 @@ func lookupAndFormat(p *Printer, r Reference, a []interface{}) {
|
|||
panic("key argument is not a Reference")
|
||||
}
|
||||
|
||||
if p.printer.catContext.Execute(id) == catalog.ErrNotFound {
|
||||
if p.printer.catContext.Execute(msg) == catalog.ErrNotFound {
|
||||
p.printer.Render(msg)
|
||||
if p.catContext.Execute(id) == catalog.ErrNotFound {
|
||||
if p.catContext.Execute(msg) == catalog.ErrNotFound {
|
||||
p.Render(msg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -142,8 +159,8 @@ func lookupAndFormat(p *Printer, r Reference, a []interface{}) {
|
|||
// Arg implements catmsg.Renderer.
|
||||
func (p *printer) Arg(i int) interface{} { // TODO, also return "ok" bool
|
||||
i--
|
||||
if uint(i) < uint(len(p.args)) {
|
||||
return p.args[i]
|
||||
if uint(i) < uint(len(p.fmt.Args)) {
|
||||
return p.fmt.Args[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
4
vendor/golang.org/x/text/message/message_test.go
generated
vendored
4
vendor/golang.org/x/text/message/message_test.go
generated
vendored
|
@ -169,9 +169,9 @@ func TestLocalization(t *testing.T) {
|
|||
|
||||
type entry struct{ tag, key, msg string }
|
||||
|
||||
func initCat(entries []entry) (*catalog.Catalog, []language.Tag) {
|
||||
func initCat(entries []entry) (*catalog.Builder, []language.Tag) {
|
||||
tags := []language.Tag{}
|
||||
cat := catalog.New()
|
||||
cat := catalog.NewBuilder()
|
||||
for _, e := range entries {
|
||||
tag := language.MustParse(e.tag)
|
||||
tags = append(tags, tag)
|
||||
|
|
314
vendor/golang.org/x/text/message/pipeline/extract.go
generated
vendored
Normal file
314
vendor/golang.org/x/text/message/pipeline/extract.go
generated
vendored
Normal file
|
@ -0,0 +1,314 @@
|
|||
// 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
|
||||
}
|
314
vendor/golang.org/x/text/message/pipeline/generate.go
generated
vendored
Normal file
314
vendor/golang.org/x/text/message/pipeline/generate.go
generated
vendored
Normal file
|
@ -0,0 +1,314 @@
|
|||
// 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.
|
||||
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.
|
||||
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) {
|
||||
// TODO: add in external input. Right now we assume that all files are
|
||||
// manually created and stored in the textdata directory.
|
||||
|
||||
// Build up index of translations and original messages.
|
||||
translations := map[language.Tag]map[string]Message{}
|
||||
languages := []language.Tag{}
|
||||
langVars := []string{}
|
||||
usedKeys := map[string]int{}
|
||||
|
||||
for _, loc := range s.Translations {
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
`))
|
221
vendor/golang.org/x/text/message/pipeline/message.go
generated
vendored
Normal file
221
vendor/golang.org/x/text/message/pipeline/message.go
generated
vendored
Normal file
|
@ -0,0 +1,221 @@
|
|||
// 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"
|
||||
"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"`
|
||||
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"`
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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"`
|
||||
// }
|
308
vendor/golang.org/x/text/message/pipeline/pipeline.go
generated
vendored
Normal file
308
vendor/golang.org/x/text/message/pipeline/pipeline.go
generated
vendored
Normal file
|
@ -0,0 +1,308 @@
|
|||
// 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"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
"unicode"
|
||||
|
||||
"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 {
|
||||
panic("unimplemented")
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// Export writes out the messages to translation out files.
|
||||
func (s *State) Export() error {
|
||||
panic("unimplemented")
|
||||
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()
|
||||
}
|
127
vendor/golang.org/x/text/message/pipeline/pipeline_test.go
generated
vendored
Normal file
127
vendor/golang.org/x/text/message/pipeline/pipeline_test.go
generated
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
// 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")
|
||||
|
||||
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) {
|
||||
t.Helper()
|
||||
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
|
||||
// TODO:
|
||||
// for range s.Config.Actions {
|
||||
// // TODO: do the actions.
|
||||
// }
|
||||
// chk(t, s.Export()) // TODO
|
||||
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 {
|
||||
s = path.Clean(filepath.ToSlash(s))
|
||||
if i := strings.LastIndex(s, "Size:"); i != -1 {
|
||||
s = s[:i]
|
||||
}
|
||||
if i := strings.LastIndex(s, "Total table size"); i != -1 {
|
||||
s = s[:i]
|
||||
}
|
||||
return 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)
|
||||
}
|
||||
}
|
268
vendor/golang.org/x/text/message/pipeline/rewrite.go
generated
vendored
Normal file
268
vendor/golang.org/x/text/message/pipeline/rewrite.go
generated
vendored
Normal file
|
@ -0,0 +1,268 @@
|
|||
// 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
|
||||
}
|
83
vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go
generated
vendored
Normal file
83
vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
// 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)": 7,
|
||||
"%[1]s is visiting %[3]s!\n": 3,
|
||||
"%d files remaining!": 4,
|
||||
"%d more files remaining!": 5,
|
||||
"%s is out of order!": 6,
|
||||
"%s is visiting %s!\n": 2,
|
||||
"Hello %s!\n": 1,
|
||||
"Hello world!\n": 0,
|
||||
}
|
||||
|
||||
var deIndex = []uint32{ // 9 elements
|
||||
0x00000000, 0x00000011, 0x00000023, 0x0000003d,
|
||||
0x00000057, 0x00000075, 0x00000094, 0x00000094,
|
||||
0x00000094,
|
||||
} // Size: 60 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{ // 9 elements
|
||||
0x00000000, 0x00000012, 0x00000024, 0x00000042,
|
||||
0x00000060, 0x00000060, 0x000000a3, 0x000000ba,
|
||||
0x000000d9,
|
||||
} // Size: 60 bytes
|
||||
|
||||
const en_USData string = "" + // Size: 217 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!\x14\x01\x81\x01\x00\x02\x14\x02One file remaini" +
|
||||
"ng!\x00&\x02There are %[1]d more files remaining!\x02%[1]s is out of ord" +
|
||||
"er!\x02%.2[1]f miles traveled (%[1]f)"
|
||||
|
||||
var zhIndex = []uint32{ // 9 elements
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000,
|
||||
} // Size: 60 bytes
|
||||
|
||||
const zhData string = ""
|
||||
|
||||
// Total table size 545 bytes (0KiB); checksum: 343E0210
|
83
vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go.want
generated
vendored
Normal file
83
vendor/golang.org/x/text/message/pipeline/testdata/test1/catalog_gen.go.want
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
// 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)": 7,
|
||||
"%[1]s is visiting %[3]s!\n": 3,
|
||||
"%d files remaining!": 4,
|
||||
"%d more files remaining!": 5,
|
||||
"%s is out of order!": 6,
|
||||
"%s is visiting %s!\n": 2,
|
||||
"Hello %s!\n": 1,
|
||||
"Hello world!\n": 0,
|
||||
}
|
||||
|
||||
var deIndex = []uint32{ // 9 elements
|
||||
0x00000000, 0x00000011, 0x00000023, 0x0000003d,
|
||||
0x00000057, 0x00000075, 0x00000094, 0x00000094,
|
||||
0x00000094,
|
||||
} // Size: 60 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{ // 9 elements
|
||||
0x00000000, 0x00000012, 0x00000024, 0x00000042,
|
||||
0x00000060, 0x00000060, 0x000000a3, 0x000000ba,
|
||||
0x000000d9,
|
||||
} // Size: 60 bytes
|
||||
|
||||
const en_USData string = "" + // Size: 217 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!\x14\x01\x81\x01\x00\x02\x14\x02One file remaini" +
|
||||
"ng!\x00&\x02There are %[1]d more files remaining!\x02%[1]s is out of ord" +
|
||||
"er!\x02%.2[1]f miles traveled (%[1]f)"
|
||||
|
||||
var zhIndex = []uint32{ // 9 elements
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000,
|
||||
} // Size: 60 bytes
|
||||
|
||||
const zhData string = ""
|
||||
|
||||
// Total table size 545 bytes (0KiB); checksum: 343E0210
|
188
vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json
generated
vendored
Normal file
188
vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json
generated
vendored
Normal file
|
@ -0,0 +1,188 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
188
vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json.want
generated
vendored
Normal file
188
vendor/golang.org/x/text/message/pipeline/testdata/test1/extracted.gotext.json.want
generated
vendored
Normal file
|
@ -0,0 +1,188 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
123
vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/messages.gotext.json
generated
vendored
Executable file
123
vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/de/messages.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,123 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
91
vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/messages.gotext.json
generated
vendored
Executable file
91
vendor/golang.org/x/text/message/pipeline/testdata/test1/locales/en-US/messages.gotext.json
generated
vendored
Executable file
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
"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})"
|
||||
}
|
||||
]
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue