all repos

rss-tools @ a5ac52722b131734c74504b6e6f4d9900536cac7

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/golang.org/x/text/internal/language/match.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
we're vendoring now, 7 days ago
1
// Copyright 2013 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
5
package language
6
7
import "errors"
8
9
type scriptRegionFlags uint8
10
11
const (
12
	isList = 1 << iota
13
	scriptInFrom
14
	regionInFrom
15
)
16
17
func (t *Tag) setUndefinedLang(id Language) {
18
	if t.LangID == 0 {
19
		t.LangID = id
20
	}
21
}
22
23
func (t *Tag) setUndefinedScript(id Script) {
24
	if t.ScriptID == 0 {
25
		t.ScriptID = id
26
	}
27
}
28
29
func (t *Tag) setUndefinedRegion(id Region) {
30
	if t.RegionID == 0 || t.RegionID.Contains(id) {
31
		t.RegionID = id
32
	}
33
}
34
35
// ErrMissingLikelyTagsData indicates no information was available
36
// to compute likely values of missing tags.
37
var ErrMissingLikelyTagsData = errors.New("missing likely tags data")
38
39
// addLikelySubtags sets subtags to their most likely value, given the locale.
40
// In most cases this means setting fields for unknown values, but in some
41
// cases it may alter a value.  It returns an ErrMissingLikelyTagsData error
42
// if the given locale cannot be expanded.
43
func (t Tag) addLikelySubtags() (Tag, error) {
44
	id, err := addTags(t)
45
	if err != nil {
46
		return t, err
47
	} else if id.equalTags(t) {
48
		return t, nil
49
	}
50
	id.RemakeString()
51
	return id, nil
52
}
53
54
// specializeRegion attempts to specialize a group region.
55
func specializeRegion(t *Tag) bool {
56
	if i := regionInclusion[t.RegionID]; i < nRegionGroups {
57
		x := likelyRegionGroup[i]
58
		if Language(x.lang) == t.LangID && Script(x.script) == t.ScriptID {
59
			t.RegionID = Region(x.region)
60
		}
61
		return true
62
	}
63
	return false
64
}
65
66
// Maximize returns a new tag with missing tags filled in.
67
func (t Tag) Maximize() (Tag, error) {
68
	return addTags(t)
69
}
70
71
func addTags(t Tag) (Tag, error) {
72
	// We leave private use identifiers alone.
73
	if t.IsPrivateUse() {
74
		return t, nil
75
	}
76
	if t.ScriptID != 0 && t.RegionID != 0 {
77
		if t.LangID != 0 {
78
			// already fully specified
79
			specializeRegion(&t)
80
			return t, nil
81
		}
82
		// Search matches for und-script-region. Note that for these cases
83
		// region will never be a group so there is no need to check for this.
84
		list := likelyRegion[t.RegionID : t.RegionID+1]
85
		if x := list[0]; x.flags&isList != 0 {
86
			list = likelyRegionList[x.lang : x.lang+uint16(x.script)]
87
		}
88
		for _, x := range list {
89
			// Deviating from the spec. See match_test.go for details.
90
			if Script(x.script) == t.ScriptID {
91
				t.setUndefinedLang(Language(x.lang))
92
				return t, nil
93
			}
94
		}
95
	}
96
	if t.LangID != 0 {
97
		// Search matches for lang-script and lang-region, where lang != und.
98
		if t.LangID < langNoIndexOffset {
99
			x := likelyLang[t.LangID]
100
			if x.flags&isList != 0 {
101
				list := likelyLangList[x.region : x.region+uint16(x.script)]
102
				if t.ScriptID != 0 {
103
					for _, x := range list {
104
						if Script(x.script) == t.ScriptID && x.flags&scriptInFrom != 0 {
105
							t.setUndefinedRegion(Region(x.region))
106
							return t, nil
107
						}
108
					}
109
				} else if t.RegionID != 0 {
110
					count := 0
111
					goodScript := true
112
					tt := t
113
					for _, x := range list {
114
						// We visit all entries for which the script was not
115
						// defined, including the ones where the region was not
116
						// defined. This allows for proper disambiguation within
117
						// regions.
118
						if x.flags&scriptInFrom == 0 && t.RegionID.Contains(Region(x.region)) {
119
							tt.RegionID = Region(x.region)
120
							tt.setUndefinedScript(Script(x.script))
121
							goodScript = goodScript && tt.ScriptID == Script(x.script)
122
							count++
123
						}
124
					}
125
					if count == 1 {
126
						return tt, nil
127
					}
128
					// Even if we fail to find a unique Region, we might have
129
					// an unambiguous script.
130
					if goodScript {
131
						t.ScriptID = tt.ScriptID
132
					}
133
				}
134
			}
135
		}
136
	} else {
137
		// Search matches for und-script.
138
		if t.ScriptID != 0 {
139
			x := likelyScript[t.ScriptID]
140
			if x.region != 0 {
141
				t.setUndefinedRegion(Region(x.region))
142
				t.setUndefinedLang(Language(x.lang))
143
				return t, nil
144
			}
145
		}
146
		// Search matches for und-region. If und-script-region exists, it would
147
		// have been found earlier.
148
		if t.RegionID != 0 {
149
			if i := regionInclusion[t.RegionID]; i < nRegionGroups {
150
				x := likelyRegionGroup[i]
151
				if x.region != 0 {
152
					t.setUndefinedLang(Language(x.lang))
153
					t.setUndefinedScript(Script(x.script))
154
					t.RegionID = Region(x.region)
155
				}
156
			} else {
157
				x := likelyRegion[t.RegionID]
158
				if x.flags&isList != 0 {
159
					x = likelyRegionList[x.lang]
160
				}
161
				if x.script != 0 && x.flags != scriptInFrom {
162
					t.setUndefinedLang(Language(x.lang))
163
					t.setUndefinedScript(Script(x.script))
164
					return t, nil
165
				}
166
			}
167
		}
168
	}
169
170
	// Search matches for lang.
171
	if t.LangID < langNoIndexOffset {
172
		x := likelyLang[t.LangID]
173
		if x.flags&isList != 0 {
174
			x = likelyLangList[x.region]
175
		}
176
		if x.region != 0 {
177
			t.setUndefinedScript(Script(x.script))
178
			t.setUndefinedRegion(Region(x.region))
179
		}
180
		specializeRegion(&t)
181
		if t.LangID == 0 {
182
			t.LangID = _en // default language
183
		}
184
		return t, nil
185
	}
186
	return t, ErrMissingLikelyTagsData
187
}
188
189
func (t *Tag) setTagsFrom(id Tag) {
190
	t.LangID = id.LangID
191
	t.ScriptID = id.ScriptID
192
	t.RegionID = id.RegionID
193
}
194
195
// minimize removes the region or script subtags from t such that
196
// t.addLikelySubtags() == t.minimize().addLikelySubtags().
197
func (t Tag) minimize() (Tag, error) {
198
	t, err := minimizeTags(t)
199
	if err != nil {
200
		return t, err
201
	}
202
	t.RemakeString()
203
	return t, nil
204
}
205
206
// minimizeTags mimics the behavior of the ICU 51 C implementation.
207
func minimizeTags(t Tag) (Tag, error) {
208
	if t.equalTags(Und) {
209
		return t, nil
210
	}
211
	max, err := addTags(t)
212
	if err != nil {
213
		return t, err
214
	}
215
	for _, id := range [...]Tag{
216
		{LangID: t.LangID},
217
		{LangID: t.LangID, RegionID: t.RegionID},
218
		{LangID: t.LangID, ScriptID: t.ScriptID},
219
	} {
220
		if x, err := addTags(id); err == nil && max.equalTags(x) {
221
			t.setTagsFrom(id)
222
			break
223
		}
224
	}
225
	return t, nil
226
}