Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue #2274. #2275

Merged
merged 1 commit into from May 10, 2021
Merged

Fix issue #2274. #2275

merged 1 commit into from May 10, 2021

Conversation

phprus
Copy link
Contributor

@phprus phprus commented May 9, 2021

See: #2274

Copy link
Contributor

@vitaut vitaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR.

src/os.cc Outdated
}

public:
system_message(unsigned long error_code) : result_(0), message_(nullptr) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make this ctor explicit.

src/os.cc Outdated
reinterpret_cast<wchar_t*>(&message_), 0, nullptr);
}
~system_message() { LocalFree(message_); }
unsigned long result() const FMT_NOEXCEPT { return result_; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's replace this with explicit operator bool since callers don't need the actual result, just the success indicator.

src/os.cc Outdated
Comment on lines 129 to 135
wstring_view rtrim() const FMT_NOEXCEPT {
auto len = result_;
while (len != 0 && is_whitespace(message_[len - 1])) {
--len;
}
return wstring_view(message_, len);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's fold this into the constructor to always remove trailing whitespace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fmt/src/os.cc

Lines 109 to 136 in 2a9b314

void detail::format_windows_error(detail::buffer<char>& out, int error_code,
const char* message) FMT_NOEXCEPT {
FMT_TRY {
wmemory_buffer buf;
buf.resize(inline_buffer_size);
for (;;) {
wchar_t* system_message = &buf[0];
int result = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), system_message,
static_cast<uint32_t>(buf.size()), nullptr);
if (result != 0) {
utf16_to_utf8 utf8_message;
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
format_to(buffer_appender<char>(out), "{}: {}", message,
utf8_message);
return;
}
break;
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break; // Can't get error message, report error code instead.
buf.resize(buf.size() * 2);
}
}
FMT_CATCH(...) {}
format_error_code(out, error_code, message);
}

The original implementation of the detail::format_windows_error function does not remove trailing whitespace. For compatibility, I have separated the operator wstring_view() and the rtrim() function.

Modify code and change the behavior of a detail::format_windows_error function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modify code and change the behavior of a detail::format_windows_error function?

Sure.

src/os.cc Outdated
Comment on lines 142 to 143
system_message msg(error_code);
if (msg.result() != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With explicit operator bool proposed above this can be

    if (system_message msg(error_code)) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Visual Studio 2017:

F:\tmp\fmt\fmt\src\os.cc(141): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
F:\tmp\fmt\fmt\src\os.cc(141): error C2059: syntax error: '('
F:\tmp\fmt\fmt\src\os.cc(141): error C2143: syntax error: missing ';' before '{'

src/os.cc Outdated
Comment on lines 169 to 170
system_message msg(error_code);
if (msg.result() != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here:

if (system_message msg(error_code)) {

test/os-test.cc Outdated
Comment on lines 123 to 126
EXPECT_NE(result, 0);
if (result == 0) {
LocalFree(message);
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the old logic because we shouldn't skip test on failure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before commit 4b885c8 this test was successful if windows did not support the given error code.
On non-English version Windows 7 SP1 this test failed after commit 4b885c8.

FormatMessageW generates an error 15100. And test has comment:

  // 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.

@phprus
Copy link
Contributor Author

phprus commented May 10, 2021

Unexpected CI Error: The operation was canceled on task "macos / build (Release) (pull_request)".
In my fork (https://github.com/phprus/fmt/tree/issue2274) all tests a passed.

@phprus phprus requested a review from vitaut May 10, 2021 18:12
src/os.cc Outdated Show resolved Hide resolved
@phprus phprus requested a review from vitaut May 10, 2021 20:28
@vitaut vitaut merged commit 0036a1d into fmtlib:master May 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants