OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/spellcheck_common.h" | 5 #include "components/spellcheck/common/spellcheck_common.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #include "base/metrics/field_trial.h" | 11 #include "base/metrics/field_trial.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "chrome/common/chrome_switches.h" | |
14 #include "third_party/icu/source/common/unicode/uloc.h" | 13 #include "third_party/icu/source/common/unicode/uloc.h" |
15 #include "third_party/icu/source/common/unicode/urename.h" | 14 #include "third_party/icu/source/common/unicode/urename.h" |
16 #include "third_party/icu/source/common/unicode/utypes.h" | 15 #include "third_party/icu/source/common/unicode/utypes.h" |
17 | 16 |
18 namespace chrome { | 17 namespace spellcheck { |
19 namespace spellcheck_common { | |
20 | 18 |
21 struct LanguageRegion { | 19 struct LanguageRegion { |
22 const char* language; // The language. | 20 const char* language; // The language. |
23 const char* language_region; // language & region, used by dictionaries. | 21 const char* language_region; // language & region, used by dictionaries. |
24 }; | 22 }; |
25 | 23 |
26 struct LanguageVersion { | 24 struct LanguageVersion { |
27 const char* language; // The language input. | 25 const char* language; // The language input. |
28 const char* version; // The corresponding version. | 26 const char* version; // The corresponding version. |
29 }; | 27 }; |
30 | 28 |
31 static const LanguageRegion g_supported_spellchecker_languages[] = { | 29 static const LanguageRegion g_supported_spellchecker_languages[] = { |
32 // Several languages are not to be included in the spellchecker list: | 30 // Several languages are not to be included in the spellchecker list: |
33 // th-TH, vi-VI. | 31 // th-TH, vi-VI. |
34 {"af", "af-ZA"}, | 32 {"af", "af-ZA"}, {"bg", "bg-BG"}, {"ca", "ca-ES"}, |
groby-ooo-7-16
2016/07/26 21:33:31
Please don't reformat this. Even if clang thinks i
timvolodine
2016/07/27 14:10:34
Done.
| |
35 {"bg", "bg-BG"}, | 33 {"cs", "cs-CZ"}, {"da", "da-DK"}, {"de", "de-DE"}, |
36 {"ca", "ca-ES"}, | 34 {"el", "el-GR"}, {"en-AU", "en-GB"}, {"en-CA", "en-CA"}, |
37 {"cs", "cs-CZ"}, | 35 {"en-GB", "en-GB"}, {"en-US", "en-US"}, {"es", "es-ES"}, |
38 {"da", "da-DK"}, | 36 {"es-419", "es-ES"}, {"es-AR", "es-ES"}, {"es-ES", "es-ES"}, |
39 {"de", "de-DE"}, | 37 {"es-MX", "es-ES"}, {"es-US", "es-ES"}, {"et", "et-EE"}, |
40 {"el", "el-GR"}, | 38 {"fa", "fa-IR"}, {"fo", "fo-FO"}, {"fr", "fr-FR"}, |
41 {"en-AU", "en-GB"}, | 39 {"he", "he-IL"}, {"hi", "hi-IN"}, {"hr", "hr-HR"}, |
42 {"en-CA", "en-CA"}, | 40 {"hu", "hu-HU"}, {"id", "id-ID"}, {"it", "it-IT"}, |
43 {"en-GB", "en-GB"}, | 41 {"ko", "ko"}, {"lt", "lt-LT"}, {"lv", "lv-LV"}, |
44 {"en-US", "en-US"}, | 42 {"nb", "nb-NO"}, {"nl", "nl-NL"}, {"pl", "pl-PL"}, |
45 {"es", "es-ES"}, | 43 {"pt-BR", "pt-BR"}, {"pt-PT", "pt-PT"}, {"ro", "ro-RO"}, |
46 {"es-419", "es-ES"}, | 44 {"ru", "ru-RU"}, {"sh", "sh"}, {"sk", "sk-SK"}, |
47 {"es-AR", "es-ES"}, | 45 {"sl", "sl-SI"}, {"sq", "sq"}, {"sr", "sr"}, |
48 {"es-ES", "es-ES"}, | 46 {"sv", "sv-SE"}, {"ta", "ta-IN"}, {"tg", "tg-TG"}, |
49 {"es-MX", "es-ES"}, | 47 {"tr", "tr-TR"}, {"uk", "uk-UA"}, {"vi", "vi-VN"}, |
50 {"es-US", "es-ES"}, | |
51 {"et", "et-EE"}, | |
52 {"fa", "fa-IR"}, | |
53 {"fo", "fo-FO"}, | |
54 {"fr", "fr-FR"}, | |
55 {"he", "he-IL"}, | |
56 {"hi", "hi-IN"}, | |
57 {"hr", "hr-HR"}, | |
58 {"hu", "hu-HU"}, | |
59 {"id", "id-ID"}, | |
60 {"it", "it-IT"}, | |
61 {"ko", "ko"}, | |
62 {"lt", "lt-LT"}, | |
63 {"lv", "lv-LV"}, | |
64 {"nb", "nb-NO"}, | |
65 {"nl", "nl-NL"}, | |
66 {"pl", "pl-PL"}, | |
67 {"pt-BR", "pt-BR"}, | |
68 {"pt-PT", "pt-PT"}, | |
69 {"ro", "ro-RO"}, | |
70 {"ru", "ru-RU"}, | |
71 {"sh", "sh"}, | |
72 {"sk", "sk-SK"}, | |
73 {"sl", "sl-SI"}, | |
74 {"sq", "sq"}, | |
75 {"sr", "sr"}, | |
76 {"sv", "sv-SE"}, | |
77 {"ta", "ta-IN"}, | |
78 {"tg", "tg-TG"}, | |
79 {"tr", "tr-TR"}, | |
80 {"uk", "uk-UA"}, | |
81 {"vi", "vi-VN"}, | |
82 }; | 48 }; |
83 | 49 |
84 bool IsValidRegion(const std::string& region) { | 50 bool IsValidRegion(const std::string& region) { |
85 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages); | 51 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages); ++i) { |
86 ++i) { | |
87 if (g_supported_spellchecker_languages[i].language_region == region) | 52 if (g_supported_spellchecker_languages[i].language_region == region) |
88 return true; | 53 return true; |
89 } | 54 } |
90 return false; | 55 return false; |
91 } | 56 } |
92 | 57 |
93 // This function returns the language-region version of language name. | 58 // This function returns the language-region version of language name. |
94 // e.g. returns hi-IN for hi. | 59 // e.g. returns hi-IN for hi. |
95 std::string GetSpellCheckLanguageRegion(const std::string& input_language) { | 60 std::string GetSpellCheckLanguageRegion(const std::string& input_language) { |
96 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages); | 61 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages); ++i) { |
97 ++i) { | |
98 if (g_supported_spellchecker_languages[i].language == input_language) { | 62 if (g_supported_spellchecker_languages[i].language == input_language) { |
99 return std::string( | 63 return std::string(g_supported_spellchecker_languages[i].language_region); |
100 g_supported_spellchecker_languages[i].language_region); | |
101 } | 64 } |
102 } | 65 } |
103 | 66 |
104 return input_language; | 67 return input_language; |
105 } | 68 } |
106 | 69 |
107 base::FilePath GetVersionedFileName(const std::string& input_language, | 70 base::FilePath GetVersionedFileName(const std::string& input_language, |
108 const base::FilePath& dict_dir) { | 71 const base::FilePath& dict_dir) { |
109 // The default dictionary version is 3-0. This version indicates that the bdic | 72 // The default dictionary version is 3-0. This version indicates that the bdic |
110 // file contains a checksum. | 73 // file contains a checksum. |
111 static const char kDefaultVersionString[] = "-3-0"; | 74 static const char kDefaultVersionString[] = "-3-0"; |
112 | 75 |
113 // Add non-default version strings here. Use the same version for all the | 76 // Add non-default version strings here. Use the same version for all the |
114 // dictionaries that you add at the same time. Increment the major version | 77 // dictionaries that you add at the same time. Increment the major version |
115 // number if you're updating either dic or aff files. Increment the minor | 78 // number if you're updating either dic or aff files. Increment the minor |
116 // version number if you're updating only dic_delta files. | 79 // version number if you're updating only dic_delta files. |
117 static LanguageVersion special_version_string[] = { | 80 static LanguageVersion special_version_string[] = { |
118 {"tr-TR", "-4-0"}, // Jan 9, 2013: Add "FLAG num" to aff to avoid heapcheck | 81 {"tr-TR", |
groby-ooo-7-16
2016/07/26 21:33:31
Please don't reformat.
timvolodine
2016/07/27 14:10:34
Done.
| |
119 // crash. | 82 "-4-0"}, // Jan 9, 2013: Add "FLAG num" to aff to avoid heapcheck |
120 {"tg-TG", "-5-0"}, // Mar 4, 2014: Add Tajik dictionary. | 83 // crash. |
84 {"tg-TG", "-5-0"}, // Mar 4, 2014: Add Tajik dictionary. | |
121 | 85 |
122 // April 2016: Local fixes | 86 // April 2016: Local fixes |
123 {"en-CA", "-7-1"}, | 87 {"en-CA", "-7-1"}, |
124 {"en-GB", "-7-1"}, | 88 {"en-GB", "-7-1"}, |
125 {"en-US", "-7-1"}, | 89 {"en-US", "-7-1"}, |
126 | 90 |
127 // March 2016: Initial check-in of Persian | 91 // March 2016: Initial check-in of Persian |
128 {"fa-IR", "-7-0"}, | 92 {"fa-IR", "-7-0"}, |
129 }; | 93 }; |
130 | 94 |
131 // Generate the bdict file name using default version string or special | 95 // Generate the bdict file name using default version string or special |
132 // version string, depending on the language. | 96 // version string, depending on the language. |
133 std::string language = GetSpellCheckLanguageRegion(input_language); | 97 std::string language = GetSpellCheckLanguageRegion(input_language); |
134 std::string versioned_bdict_file_name(language + kDefaultVersionString + | 98 std::string versioned_bdict_file_name(language + kDefaultVersionString + |
135 ".bdic"); | 99 ".bdic"); |
136 for (size_t i = 0; i < arraysize(special_version_string); ++i) { | 100 for (size_t i = 0; i < arraysize(special_version_string); ++i) { |
137 if (language == special_version_string[i].language) { | 101 if (language == special_version_string[i].language) { |
138 versioned_bdict_file_name = | 102 versioned_bdict_file_name = |
139 language + special_version_string[i].version + ".bdic"; | 103 language + special_version_string[i].version + ".bdic"; |
140 break; | 104 break; |
141 } | 105 } |
142 } | 106 } |
143 | 107 |
144 return dict_dir.AppendASCII(versioned_bdict_file_name); | 108 return dict_dir.AppendASCII(versioned_bdict_file_name); |
145 } | 109 } |
146 | 110 |
147 std::string GetCorrespondingSpellCheckLanguage(const std::string& language) { | 111 std::string GetCorrespondingSpellCheckLanguage(const std::string& language) { |
148 std::string best_match; | 112 std::string best_match; |
149 // Look for exact match in the Spell Check language list. | 113 // Look for exact match in the Spell Check language list. |
150 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages); | 114 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages); ++i) { |
151 ++i) { | |
152 // First look for exact match in the language region of the list. | 115 // First look for exact match in the language region of the list. |
153 std::string spellcheck_language( | 116 std::string spellcheck_language( |
154 g_supported_spellchecker_languages[i].language); | 117 g_supported_spellchecker_languages[i].language); |
155 if (spellcheck_language == language) | 118 if (spellcheck_language == language) |
156 return language; | 119 return language; |
157 | 120 |
158 // Next, look for exact match in the language_region part of the list. | 121 // Next, look for exact match in the language_region part of the list. |
159 std::string spellcheck_language_region( | 122 std::string spellcheck_language_region( |
160 g_supported_spellchecker_languages[i].language_region); | 123 g_supported_spellchecker_languages[i].language_region); |
161 if (spellcheck_language_region == language) { | 124 if (spellcheck_language_region == language) { |
162 if (best_match.empty()) | 125 if (best_match.empty()) |
163 best_match = g_supported_spellchecker_languages[i].language; | 126 best_match = g_supported_spellchecker_languages[i].language; |
164 } | 127 } |
165 } | 128 } |
166 | 129 |
167 // No match found - return best match, if any. | 130 // No match found - return best match, if any. |
168 return best_match; | 131 return best_match; |
169 } | 132 } |
170 | 133 |
171 void SpellCheckLanguages(std::vector<std::string>* languages) { | 134 void SpellCheckLanguages(std::vector<std::string>* languages) { |
172 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages); | 135 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages); ++i) { |
173 ++i) { | |
174 languages->push_back(g_supported_spellchecker_languages[i].language); | 136 languages->push_back(g_supported_spellchecker_languages[i].language); |
175 } | 137 } |
176 } | 138 } |
177 | 139 |
178 void GetISOLanguageCountryCodeFromLocale(const std::string& locale, | 140 void GetISOLanguageCountryCodeFromLocale(const std::string& locale, |
179 std::string* language_code, | 141 std::string* language_code, |
180 std::string* country_code) { | 142 std::string* country_code) { |
181 DCHECK(language_code); | 143 DCHECK(language_code); |
182 DCHECK(country_code); | 144 DCHECK(country_code); |
183 char language[ULOC_LANG_CAPACITY] = ULOC_ENGLISH; | 145 char language[ULOC_LANG_CAPACITY] = ULOC_ENGLISH; |
184 const char* country = "USA"; | 146 const char* country = "USA"; |
185 if (!locale.empty()) { | 147 if (!locale.empty()) { |
186 UErrorCode error = U_ZERO_ERROR; | 148 UErrorCode error = U_ZERO_ERROR; |
187 char id[ULOC_LANG_CAPACITY + ULOC_SCRIPT_CAPACITY + ULOC_COUNTRY_CAPACITY]; | 149 char id[ULOC_LANG_CAPACITY + ULOC_SCRIPT_CAPACITY + ULOC_COUNTRY_CAPACITY]; |
188 uloc_addLikelySubtags(locale.c_str(), id, arraysize(id), &error); | 150 uloc_addLikelySubtags(locale.c_str(), id, arraysize(id), &error); |
189 error = U_ZERO_ERROR; | 151 error = U_ZERO_ERROR; |
190 uloc_getLanguage(id, language, arraysize(language), &error); | 152 uloc_getLanguage(id, language, arraysize(language), &error); |
191 country = uloc_getISO3Country(id); | 153 country = uloc_getISO3Country(id); |
192 } | 154 } |
193 *language_code = std::string(language); | 155 *language_code = std::string(language); |
194 *country_code = std::string(country); | 156 *country_code = std::string(country); |
195 } | 157 } |
196 | 158 |
197 } // namespace spellcheck_common | 159 } // namespace spellcheck |
198 } // namespace chrome | |
OLD | NEW |