Skip to content

Commit 059a1b0

Browse files
Prefer US English for system_category() messages, fall back to system locale, then ID 0 (#5104)
Co-authored-by: Jcr-dev <[email protected]>
1 parent 126f4eb commit 059a1b0

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

stl/src/syserror_import_lib.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,33 @@ extern "C" {
4040
// convert to name of Windows error, return 0 for failure, otherwise return number of chars in buffer
4141
// __std_system_error_deallocate_message should be called even if 0 is returned
4242
// pre: *_Ptr_str == nullptr
43-
DWORD _Lang_id;
44-
const int _Ret = GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER,
45-
reinterpret_cast<LPWSTR>(&_Lang_id), sizeof(_Lang_id) / sizeof(wchar_t));
46-
if (_Ret == 0) {
47-
_Lang_id = 0;
43+
44+
// We start by requesting US English for system_category() messages. (See GH-2451 and GH-3254 for the history.)
45+
// This is consistent with generic_category(), which uses a table of US English strings in the STL.
46+
// In general, system_error messages aren't directly useful to end-users - they're meant for programmer-users.
47+
// Of course, the programmer-user might not speak US English, but machine translation of the message
48+
// (and the numeric value of the error code) should help them understand the error.
49+
50+
constexpr auto _Flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
51+
52+
DWORD _Lang_id = 0;
53+
DWORD _Chars = 0;
54+
55+
for (int _Attempt = 0; _Attempt < 3 && _Chars == 0; ++_Attempt) {
56+
if (_Attempt == 0) {
57+
_Lang_id = 0x0409; // 1033 decimal, "en-US" locale
58+
} else if (_Attempt == 1) {
59+
const int _Ret = GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER,
60+
reinterpret_cast<LPWSTR>(&_Lang_id), sizeof(_Lang_id) / sizeof(wchar_t));
61+
if (_Ret == 0) {
62+
continue; // If we can't get the system locale's language ID, skip this attempt
63+
}
64+
} else {
65+
_Lang_id = 0;
66+
}
67+
68+
_Chars = FormatMessageA(_Flags, nullptr, _Message_id, _Lang_id, reinterpret_cast<char*>(_Ptr_str), 0, nullptr);
4869
}
49-
const unsigned long _Chars =
50-
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
51-
nullptr, _Message_id, _Lang_id, reinterpret_cast<char*>(_Ptr_str), 0, nullptr);
5270

5371
return _CSTD __std_get_string_size_without_trailing_whitespace(*_Ptr_str, _Chars);
5472
}

0 commit comments

Comments
 (0)