mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-10 21:20:07 +00:00
Merge pull request #285 from mwinterb/winerror_winu
Changed format_windows_error to not need LocalFree
This commit is contained in:
commit
6883d6e724
@ -588,27 +588,25 @@ FMT_FUNC void fmt::WindowsError::init(
|
|||||||
FMT_FUNC void fmt::internal::format_windows_error(
|
FMT_FUNC void fmt::internal::format_windows_error(
|
||||||
fmt::Writer &out, int error_code,
|
fmt::Writer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT {
|
fmt::StringRef message) FMT_NOEXCEPT {
|
||||||
class String {
|
|
||||||
private:
|
|
||||||
LPWSTR str_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
String() : str_() {}
|
|
||||||
~String() { LocalFree(str_); }
|
|
||||||
LPWSTR *ptr() { return &str_; }
|
|
||||||
LPCWSTR c_str() const { return str_; }
|
|
||||||
};
|
|
||||||
FMT_TRY {
|
FMT_TRY {
|
||||||
String system_message;
|
MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
|
||||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
buffer.resize(INLINE_BUFFER_SIZE);
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
|
for (;;) {
|
||||||
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
wchar_t *system_message = &buffer[0];
|
||||||
reinterpret_cast<LPWSTR>(system_message.ptr()), 0, 0)) {
|
int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
system_message, static_cast<uint32_t>(buffer.size()), 0);
|
||||||
|
if (result != 0) {
|
||||||
UTF16ToUTF8 utf8_message;
|
UTF16ToUTF8 utf8_message;
|
||||||
if (utf8_message.convert(system_message.c_str()) == ERROR_SUCCESS) {
|
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
|
||||||
out << message << ": " << utf8_message;
|
out << message << ": " << utf8_message;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
break; // Can't get error message, report error code instead.
|
||||||
|
buffer.resize(buffer.size() * 2);
|
||||||
}
|
}
|
||||||
} FMT_CATCH(...) {}
|
} FMT_CATCH(...) {}
|
||||||
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
|
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
|
||||||
|
@ -873,6 +873,27 @@ TEST(UtilTest, FormatWindowsError) {
|
|||||||
EXPECT_EQ(fmt::format("error {}", ERROR_FILE_EXISTS), actual_message.str());
|
EXPECT_EQ(fmt::format("error {}", ERROR_FILE_EXISTS), actual_message.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(UtilTest, FormatLongWindowsError) {
|
||||||
|
LPWSTR message = 0;
|
||||||
|
// this error code is not available on all Windows platforms and
|
||||||
|
// Windows SDKs, so do not fail the test if the error string cannot
|
||||||
|
// be retrieved.
|
||||||
|
const int provisioning_not_allowed = 0x80284013L /*TBS_E_PROVISIONING_NOT_ALLOWED*/;
|
||||||
|
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
|
||||||
|
provisioning_not_allowed, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
reinterpret_cast<LPWSTR>(&message), 0, 0) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fmt::internal::UTF16ToUTF8 utf8_message(message);
|
||||||
|
LocalFree(message);
|
||||||
|
fmt::MemoryWriter actual_message;
|
||||||
|
fmt::internal::format_windows_error(
|
||||||
|
actual_message, provisioning_not_allowed, "test");
|
||||||
|
EXPECT_EQ(fmt::format("test: {}", utf8_message.str()),
|
||||||
|
actual_message.str());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(UtilTest, WindowsError) {
|
TEST(UtilTest, WindowsError) {
|
||||||
check_throw_error<fmt::WindowsError>(
|
check_throw_error<fmt::WindowsError>(
|
||||||
ERROR_FILE_EXISTS, fmt::internal::format_windows_error);
|
ERROR_FILE_EXISTS, fmt::internal::format_windows_error);
|
||||||
|
Loading…
Reference in New Issue
Block a user