Source File
parse.go
Belonging Package
golang.org/x/text/internal/language
package language
import (
)
var ErrDuplicateKey = errors.New("language: different values for same key in -u extension")
type ValueError struct {
v [8]byte
}
func ( []byte) ValueError {
var ValueError
copy(.v[:], )
return
}
func ( ValueError) () []byte {
:= bytes.IndexByte(.v[:], 0)
if == -1 {
= 8
}
return .v[:]
}
func ( ValueError) () string {
return fmt.Sprintf("language: subtag %q is well-formed but unknown", .tag())
}
func ( ValueError) () string {
return string(.tag())
}
type scanner struct {
b []byte
bytes [max99thPercentileSize]byte
token []byte
start int // start position of the current token
end int // end position of the current token
next int // next point for scan
err error
done bool
}
func ( string) scanner {
:= scanner{}
if len() <= len(.bytes) {
.b = .bytes[:copy(.bytes[:], )]
} else {
.b = []byte()
}
.init()
return
}
func ( *scanner) () ( int) {
= .end
.token = nil
for .start = .next; .next < len(.b); {
:= bytes.IndexByte(.b[.next:], '-')
if == -1 {
.end = len(.b)
.next = len(.b)
= .end - .start
} else {
.end = .next +
.next = .end + 1
}
:= .b[.start:.end]
if < 1 || > 8 || !isAlphaNum() {
.gobble(ErrSyntax)
continue
}
.token =
return
}
if := len(.b); > 0 && .b[-1] == '-' {
.setError(ErrSyntax)
.b = .b[:len(.b)-1]
}
.done = true
return
}
if == "" {
return Und, ErrSyntax
}
if len() <= maxAltTaglen {
:= [maxAltTaglen]byte{}
if 'A' <= && <= 'Z' {
+= 'a' - 'A'
} else if == '_' {
= '-'
}
[] = byte()
}
if , := grandfathered(); {
return , nil
}
}
:= makeScannerString()
return parse(&, )
}
func ( *scanner, string) ( Tag, error) {
= Und
var int
if := len(.token); <= 1 {
.toLower(0, len(.b))
if == 0 || .token[0] != 'x' {
return , ErrSyntax
}
= parseExtensions()
} else if >= 4 {
return Und, ErrSyntax
} else { // the usual case
, = parseTag()
if := len(.token); == 1 {
.pExt = uint16()
= parseExtensions()
} else if < len(.b) {
.setError(ErrSyntax)
.b = .b[:]
}
}
if int(.pVariant) < len(.b) {
if < len() {
= [:]
}
if len() > 0 && tag.Compare(, .b) == 0 {
.str =
} else {
.str = string(.b)
}
} else {
.pVariant, .pExt = 0, 0
}
return , .err
}
, := getLangID(.token)
if != 0 {
.LangID =
copy(.b[:], .String())
.b[+3] = '-'
.start = + 4
}
.gobble()
= .scan()
}
if len(.token) == 4 && isAlpha(.token[0]) {
.ScriptID, = getScriptID(script, .token)
if .ScriptID == 0 {
.gobble()
}
= .scan()
}
if := len(.token); >= 2 && <= 3 {
.RegionID, = getRegionID(.token)
if .RegionID == 0 {
.gobble()
} else {
.replace(.RegionID.String())
}
= .scan()
}
.toLower(.start, len(.b))
.pVariant = byte()
= parseVariants(, , )
.pExt = uint16()
return ,
}
var separator = []byte{'-'}
, := variantIndex[string(.token)]
continue
}
[] = []
[] = []
++
=
}
if := bytes.Join([:], separator); len() == 0 {
= - 1
} else {
.resizeRange(, , len())
copy(.b[.start:], )
= .end
}
}
return
}
type variantsSort struct {
i []uint8
v [][]byte
}
func ( variantsSort) () int {
return len(.i)
}
func ( variantsSort) (, int) {
.i[], .i[] = .i[], .i[]
.v[], .v[] = .v[], .v[]
}
func ( variantsSort) (, int) bool {
return .i[] < .i[]
}
type bytesSort struct {
b [][]byte
n int // first n bytes to compare
}
func ( bytesSort) () int {
return len(.b)
}
func ( bytesSort) (, int) {
.b[], .b[] = .b[], .b[]
}
func ( bytesSort) (, int) bool {
for := 0; < .n; ++ {
if .b[][] == .b[][] {
continue
}
return .b[][] < .b[][]
}
return false
}
func ( *scanner) int {
:= .start
:= [][]byte{}
:= []byte{}
:= .end
for len(.token) == 1 {
:= .start
:= .token[0]
= parseExtension()
:= .b[:]
if len() < 3 || ( != 'x' && len() < 4) {
.setError(ErrSyntax)
=
continue
} else if == && ( == 'x' || .start == len(.b)) {
.b = .b[:]
return
} else if == 'x' {
=
break
}
= append(, )
}
sort.Sort(bytesSort{, 1})
if len() > 0 {
= append(, )
}
.b = .b[:]
if len() > 0 {
.b = append(.b, bytes.Join(, separator)...)
:= + 1
.next =
:= [][]byte{}
for .scan(); len(.token) == 2; {
, := .start, .end
= .acceptMinSize(3)
if != {
= append(, .b[:])
} else {
.setError(ErrSyntax)
=
}
}
sort.Stable(bytesSort{, 2})
if := len(); > 0 {
:= 0
for := 1; < ; ++ {
if !bytes.Equal([][:2], [][:2]) {
++
[] = []
} else if !bytes.Equal([], []) {
.setError(ErrDuplicateKey)
}
}
= [:+1]
}
:= bytes.Join(, separator)
if := + len(); < {
.deleteRange(, )
=
}
copy(.b[:], )
break
}
}
case 't':
.scan()
if := len(.token); >= 2 && <= 3 && isAlpha(.token[1]) {
_, = parseTag()
.toLower(, )
}
for len(.token) == 2 && !isAlpha(.token[1]) {
= .acceptMinSize(3)
}
case 'x':
= .acceptMinSize(1)
default:
= .acceptMinSize(2)
}
return
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |