Add ICU message format support
[chromium-blink-merge.git] / chrome / common / spellcheck_common.cc
blob9aa3a02d8bcefdf2004ff0c9f8062526ff01cc56
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
3 // found in the LICENSE file.
5 #include "chrome/common/spellcheck_common.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/macros.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "third_party/icu/source/common/unicode/uloc.h"
13 #include "third_party/icu/source/common/unicode/urename.h"
14 #include "third_party/icu/source/common/unicode/utypes.h"
16 namespace chrome {
17 namespace spellcheck_common {
19 struct LanguageRegion {
20 const char* language; // The language.
21 const char* language_region; // language & region, used by dictionaries.
24 struct LanguageVersion {
25 const char* language; // The language input.
26 const char* version; // The corresponding version.
29 static const LanguageRegion g_supported_spellchecker_languages[] = {
30 // Several languages are not to be included in the spellchecker list:
31 // th-TH, vi-VI.
32 {"af", "af-ZA"},
33 {"bg", "bg-BG"},
34 {"ca", "ca-ES"},
35 {"cs", "cs-CZ"},
36 {"da", "da-DK"},
37 {"de", "de-DE"},
38 {"el", "el-GR"},
39 {"en-AU", "en-AU"},
40 {"en-CA", "en-CA"},
41 {"en-GB", "en-GB"},
42 {"en-US", "en-US"},
43 {"es", "es-ES"},
44 {"et", "et-EE"},
45 {"fo", "fo-FO"},
46 {"fr", "fr-FR"},
47 {"he", "he-IL"},
48 {"hi", "hi-IN"},
49 {"hr", "hr-HR"},
50 {"hu", "hu-HU"},
51 {"id", "id-ID"},
52 {"it", "it-IT"},
53 {"ko", "ko"},
54 {"lt", "lt-LT"},
55 {"lv", "lv-LV"},
56 {"nb", "nb-NO"},
57 {"nl", "nl-NL"},
58 {"pl", "pl-PL"},
59 {"pt-BR", "pt-BR"},
60 {"pt-PT", "pt-PT"},
61 {"ro", "ro-RO"},
62 {"ru", "ru-RU"},
63 {"sh", "sh"},
64 {"sk", "sk-SK"},
65 {"sl", "sl-SI"},
66 {"sq", "sq"},
67 {"sr", "sr"},
68 {"sv", "sv-SE"},
69 {"ta", "ta-IN"},
70 {"tg", "tg-TG"},
71 {"tr", "tr-TR"},
72 {"uk", "uk-UA"},
73 {"vi", "vi-VN"},
76 bool IsValidRegion(const std::string& region) {
77 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages);
78 ++i) {
79 if (g_supported_spellchecker_languages[i].language_region == region)
80 return true;
82 return false;
85 // This function returns the language-region version of language name.
86 // e.g. returns hi-IN for hi.
87 std::string GetSpellCheckLanguageRegion(const std::string& input_language) {
88 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages);
89 ++i) {
90 if (g_supported_spellchecker_languages[i].language == input_language) {
91 return std::string(
92 g_supported_spellchecker_languages[i].language_region);
96 return input_language;
99 base::FilePath GetVersionedFileName(const std::string& input_language,
100 const base::FilePath& dict_dir) {
101 // The default dictionary version is 3-0. This version indicates that the bdic
102 // file contains a checksum.
103 static const char kDefaultVersionString[] = "-3-0";
105 // Add non-default version strings here. Use the same version for all the
106 // dictionaries that you add at the same time. Increment the major version
107 // number if you're updating either dic or aff files. Increment the minor
108 // version number if you're updating only dic_delta files.
109 static LanguageVersion special_version_string[] = {
110 {"tr-TR", "-4-0"}, // Jan 9, 2013: Add "FLAG num" to aff to avoid heapcheck
111 // crash.
112 {"tg-TG", "-5-0"}, // Mar 4, 2014: Add Tajik dictionary.
114 // Oct 28, 2014: Update from upstream, add new words.
115 {"en-AU", "-4-0"},
116 {"en-GB", "-4-0"},
118 // March 10, 2015: Update from upstream, enable typographical apostrophe.
119 {"en-CA", "-6-1"},
120 {"en-US", "-6-1"},
123 // Generate the bdict file name using default version string or special
124 // version string, depending on the language.
125 std::string language = GetSpellCheckLanguageRegion(input_language);
126 std::string versioned_bdict_file_name(language + kDefaultVersionString +
127 ".bdic");
128 for (size_t i = 0; i < arraysize(special_version_string); ++i) {
129 if (language == special_version_string[i].language) {
130 versioned_bdict_file_name =
131 language + special_version_string[i].version + ".bdic";
132 break;
136 return dict_dir.AppendASCII(versioned_bdict_file_name);
139 std::string GetCorrespondingSpellCheckLanguage(const std::string& language) {
140 // Look for exact match in the Spell Check language list.
141 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages);
142 ++i) {
143 // First look for exact match in the language region of the list.
144 std::string spellcheck_language(
145 g_supported_spellchecker_languages[i].language);
146 if (spellcheck_language == language)
147 return language;
149 // Next, look for exact match in the language_region part of the list.
150 std::string spellcheck_language_region(
151 g_supported_spellchecker_languages[i].language_region);
152 if (spellcheck_language_region == language)
153 return g_supported_spellchecker_languages[i].language;
156 // No match found - return blank.
157 return std::string();
160 void SpellCheckLanguages(std::vector<std::string>* languages) {
161 for (size_t i = 0; i < arraysize(g_supported_spellchecker_languages);
162 ++i) {
163 languages->push_back(g_supported_spellchecker_languages[i].language);
167 void GetISOLanguageCountryCodeFromLocale(const std::string& locale,
168 std::string* language_code,
169 std::string* country_code) {
170 DCHECK(language_code);
171 DCHECK(country_code);
172 char language[ULOC_LANG_CAPACITY] = ULOC_ENGLISH;
173 const char* country = "USA";
174 if (!locale.empty()) {
175 UErrorCode error = U_ZERO_ERROR;
176 char id[ULOC_LANG_CAPACITY + ULOC_SCRIPT_CAPACITY + ULOC_COUNTRY_CAPACITY];
177 uloc_addLikelySubtags(locale.c_str(), id, arraysize(id), &error);
178 error = U_ZERO_ERROR;
179 uloc_getLanguage(id, language, arraysize(language), &error);
180 country = uloc_getISO3Country(id);
182 *language_code = std::string(language);
183 *country_code = std::string(country);
186 bool IsMultilingualSpellcheckEnabled() {
187 return base::CommandLine::ForCurrentProcess()->HasSwitch(
188 switches::kEnableMultilingualSpellChecker);
191 } // namespace spellcheck_common
192 } // namespace chrome