| 160 | } |
| 161 | |
| 162 | void InitLocale() { |
| 163 | auto id = boost::locale::util::get_system_locale(true); |
| 164 | UErrorCode err = U_ZERO_ERROR; |
| 165 | icu::Locale::setDefault(icu::Locale::createCanonical(id.c_str()), err); |
| 166 | if (U_FAILURE(err)) throw InternalError(u_errorName(err)); |
| 167 | |
| 168 | // Try to get the UTF-8 version of the current locale |
| 169 | auto locale = boost::locale::generator().generate(""); |
| 170 | |
| 171 | // Check if we actually got a UTF-8 locale |
| 172 | using codecvt = std::codecvt<wchar_t, char, std::mbstate_t>; |
| 173 | int result = std::codecvt_base::error; |
| 174 | if (std::has_facet<codecvt>(locale)) { |
| 175 | wchar_t test[] = L"\xFFFE"; |
| 176 | char buff[8]; |
| 177 | auto mb = std::mbstate_t(); |
| 178 | const wchar_t* from_next; |
| 179 | char* to_next; |
| 180 | result = std::use_facet<codecvt>(locale).out(mb, |
| 181 | test, std::end(test), from_next, |
| 182 | buff, std::end(buff), to_next); |
| 183 | } |
| 184 | |
| 185 | // If we didn't get a UTF-8 locale, force it to a known one |
| 186 | // FIXME: Should the ICU locale also be forced to en_US here? |
| 187 | if (result != std::codecvt_base::ok) |
| 188 | locale = boost::locale::generator().generate("en_US.UTF-8"); |
| 189 | std::locale::global(locale); |
| 190 | } |
| 191 | } // namespace util |
| 192 | |
| 193 | #ifndef __APPLE__ |