barometer: update DMA's vendoring packages
[barometer.git] / src / dma / vendor / golang.org / x / text / internal / language / match.go
diff --git a/src/dma/vendor/golang.org/x/text/internal/language/match.go b/src/dma/vendor/golang.org/x/text/internal/language/match.go
new file mode 100644 (file)
index 0000000..75a2dbc
--- /dev/null
@@ -0,0 +1,226 @@
+// Copyright 2013 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 language
+
+import "errors"
+
+type scriptRegionFlags uint8
+
+const (
+       isList = 1 << iota
+       scriptInFrom
+       regionInFrom
+)
+
+func (t *Tag) setUndefinedLang(id Language) {
+       if t.LangID == 0 {
+               t.LangID = id
+       }
+}
+
+func (t *Tag) setUndefinedScript(id Script) {
+       if t.ScriptID == 0 {
+               t.ScriptID = id
+       }
+}
+
+func (t *Tag) setUndefinedRegion(id Region) {
+       if t.RegionID == 0 || t.RegionID.Contains(id) {
+               t.RegionID = id
+       }
+}
+
+// ErrMissingLikelyTagsData indicates no information was available
+// to compute likely values of missing tags.
+var ErrMissingLikelyTagsData = errors.New("missing likely tags data")
+
+// addLikelySubtags sets subtags to their most likely value, given the locale.
+// In most cases this means setting fields for unknown values, but in some
+// cases it may alter a value.  It returns an ErrMissingLikelyTagsData error
+// if the given locale cannot be expanded.
+func (t Tag) addLikelySubtags() (Tag, error) {
+       id, err := addTags(t)
+       if err != nil {
+               return t, err
+       } else if id.equalTags(t) {
+               return t, nil
+       }
+       id.RemakeString()
+       return id, nil
+}
+
+// specializeRegion attempts to specialize a group region.
+func specializeRegion(t *Tag) bool {
+       if i := regionInclusion[t.RegionID]; i < nRegionGroups {
+               x := likelyRegionGroup[i]
+               if Language(x.lang) == t.LangID && Script(x.script) == t.ScriptID {
+                       t.RegionID = Region(x.region)
+               }
+               return true
+       }
+       return false
+}
+
+// Maximize returns a new tag with missing tags filled in.
+func (t Tag) Maximize() (Tag, error) {
+       return addTags(t)
+}
+
+func addTags(t Tag) (Tag, error) {
+       // We leave private use identifiers alone.
+       if t.IsPrivateUse() {
+               return t, nil
+       }
+       if t.ScriptID != 0 && t.RegionID != 0 {
+               if t.LangID != 0 {
+                       // already fully specified
+                       specializeRegion(&t)
+                       return t, nil
+               }
+               // Search matches for und-script-region. Note that for these cases
+               // region will never be a group so there is no need to check for this.
+               list := likelyRegion[t.RegionID : t.RegionID+1]
+               if x := list[0]; x.flags&isList != 0 {
+                       list = likelyRegionList[x.lang : x.lang+uint16(x.script)]
+               }
+               for _, x := range list {
+                       // Deviating from the spec. See match_test.go for details.
+                       if Script(x.script) == t.ScriptID {
+                               t.setUndefinedLang(Language(x.lang))
+                               return t, nil
+                       }
+               }
+       }
+       if t.LangID != 0 {
+               // Search matches for lang-script and lang-region, where lang != und.
+               if t.LangID < langNoIndexOffset {
+                       x := likelyLang[t.LangID]
+                       if x.flags&isList != 0 {
+                               list := likelyLangList[x.region : x.region+uint16(x.script)]
+                               if t.ScriptID != 0 {
+                                       for _, x := range list {
+                                               if Script(x.script) == t.ScriptID && x.flags&scriptInFrom != 0 {
+                                                       t.setUndefinedRegion(Region(x.region))
+                                                       return t, nil
+                                               }
+                                       }
+                               } else if t.RegionID != 0 {
+                                       count := 0
+                                       goodScript := true
+                                       tt := t
+                                       for _, x := range list {
+                                               // We visit all entries for which the script was not
+                                               // defined, including the ones where the region was not
+                                               // defined. This allows for proper disambiguation within
+                                               // regions.
+                                               if x.flags&scriptInFrom == 0 && t.RegionID.Contains(Region(x.region)) {
+                                                       tt.RegionID = Region(x.region)
+                                                       tt.setUndefinedScript(Script(x.script))
+                                                       goodScript = goodScript && tt.ScriptID == Script(x.script)
+                                                       count++
+                                               }
+                                       }
+                                       if count == 1 {
+                                               return tt, nil
+                                       }
+                                       // Even if we fail to find a unique Region, we might have
+                                       // an unambiguous script.
+                                       if goodScript {
+                                               t.ScriptID = tt.ScriptID
+                                       }
+                               }
+                       }
+               }
+       } else {
+               // Search matches for und-script.
+               if t.ScriptID != 0 {
+                       x := likelyScript[t.ScriptID]
+                       if x.region != 0 {
+                               t.setUndefinedRegion(Region(x.region))
+                               t.setUndefinedLang(Language(x.lang))
+                               return t, nil
+                       }
+               }
+               // Search matches for und-region. If und-script-region exists, it would
+               // have been found earlier.
+               if t.RegionID != 0 {
+                       if i := regionInclusion[t.RegionID]; i < nRegionGroups {
+                               x := likelyRegionGroup[i]
+                               if x.region != 0 {
+                                       t.setUndefinedLang(Language(x.lang))
+                                       t.setUndefinedScript(Script(x.script))
+                                       t.RegionID = Region(x.region)
+                               }
+                       } else {
+                               x := likelyRegion[t.RegionID]
+                               if x.flags&isList != 0 {
+                                       x = likelyRegionList[x.lang]
+                               }
+                               if x.script != 0 && x.flags != scriptInFrom {
+                                       t.setUndefinedLang(Language(x.lang))
+                                       t.setUndefinedScript(Script(x.script))
+                                       return t, nil
+                               }
+                       }
+               }
+       }
+
+       // Search matches for lang.
+       if t.LangID < langNoIndexOffset {
+               x := likelyLang[t.LangID]
+               if x.flags&isList != 0 {
+                       x = likelyLangList[x.region]
+               }
+               if x.region != 0 {
+                       t.setUndefinedScript(Script(x.script))
+                       t.setUndefinedRegion(Region(x.region))
+               }
+               specializeRegion(&t)
+               if t.LangID == 0 {
+                       t.LangID = _en // default language
+               }
+               return t, nil
+       }
+       return t, ErrMissingLikelyTagsData
+}
+
+func (t *Tag) setTagsFrom(id Tag) {
+       t.LangID = id.LangID
+       t.ScriptID = id.ScriptID
+       t.RegionID = id.RegionID
+}
+
+// minimize removes the region or script subtags from t such that
+// t.addLikelySubtags() == t.minimize().addLikelySubtags().
+func (t Tag) minimize() (Tag, error) {
+       t, err := minimizeTags(t)
+       if err != nil {
+               return t, err
+       }
+       t.RemakeString()
+       return t, nil
+}
+
+// minimizeTags mimics the behavior of the ICU 51 C implementation.
+func minimizeTags(t Tag) (Tag, error) {
+       if t.equalTags(Und) {
+               return t, nil
+       }
+       max, err := addTags(t)
+       if err != nil {
+               return t, err
+       }
+       for _, id := range [...]Tag{
+               {LangID: t.LangID},
+               {LangID: t.LangID, RegionID: t.RegionID},
+               {LangID: t.LangID, ScriptID: t.ScriptID},
+       } {
+               if x, err := addTags(id); err == nil && max.equalTags(x) {
+                       t.setTagsFrom(id)
+                       break
+               }
+       }
+       return t, nil
+}