Skip to content

Commit d97a4f8

Browse files
committed
Ensure that the locale set is a UTF-8 one
This brings back logic removed in 0b40de8 . The locale not ending up as UTF-8 happened on MacOS, which would then e.g. break search for strings containing non-ASCII characters.
1 parent 6d54e87 commit d97a4f8

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

libaegisub/common/util.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,33 @@ void tagless_find_helper::map_range(size_t &s, size_t &e) {
160160
}
161161

162162
void InitLocale() {
163-
// FIXME: need to verify we actually got a utf-8 locale
164163
auto id = boost::locale::util::get_system_locale(true);
165164
UErrorCode err = U_ZERO_ERROR;
166165
icu::Locale::setDefault(icu::Locale::createCanonical(id.c_str()), err);
167166
if (U_FAILURE(err)) throw InternalError(u_errorName(err));
168-
std::locale::global(boost::locale::generator().generate(""));
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);
169190
}
170191
} // namespace util
171192

0 commit comments

Comments
 (0)