mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Replace windows_error with system_error
This commit is contained in:
2
.github/workflows/linux.yml
vendored
2
.github/workflows/linux.yml
vendored
@ -70,3 +70,5 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
run: ctest -C ${{matrix.build_type}}
|
run: ctest -C ${{matrix.build_type}}
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: True
|
||||||
|
2
.github/workflows/macos.yml
vendored
2
.github/workflows/macos.yml
vendored
@ -28,3 +28,5 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
run: ctest -C ${{matrix.build_type}}
|
run: ctest -C ${{matrix.build_type}}
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: True
|
||||||
|
2
.github/workflows/windows.yml
vendored
2
.github/workflows/windows.yml
vendored
@ -54,3 +54,5 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
run: ctest -C ${{matrix.build_type}}
|
run: ctest -C ${{matrix.build_type}}
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: True
|
||||||
|
@ -9,10 +9,11 @@
|
|||||||
#define FMT_OS_H_
|
#define FMT_OS_H_
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <clocale> // for locale_t
|
#include <clocale> // locale_t
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib> // for strtod_l
|
#include <cstdlib> // strtod_l
|
||||||
|
#include <system_error> // std::system_error
|
||||||
|
|
||||||
#if defined __APPLE__ || defined(__FreeBSD__)
|
#if defined __APPLE__ || defined(__FreeBSD__)
|
||||||
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
|
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
|
||||||
@ -154,45 +155,42 @@ FMT_API void format_windows_error(buffer<char>& out, int error_code,
|
|||||||
string_view message) FMT_NOEXCEPT;
|
string_view message) FMT_NOEXCEPT;
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/** A Windows error. */
|
FMT_API std::system_error vwindows_error(int error_code, string_view format_str,
|
||||||
class windows_error : public system_error {
|
format_args args);
|
||||||
private:
|
|
||||||
FMT_API void init(int error_code, string_view format_str, format_args args);
|
|
||||||
|
|
||||||
public:
|
/**
|
||||||
/**
|
\rst
|
||||||
\rst
|
Constructs a :class:`std::system_error` object with the description
|
||||||
Constructs a :class:`fmt::windows_error` object with the description
|
of the form
|
||||||
of the form
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
*<message>*: *<system-message>*
|
*<message>*: *<system-message>*
|
||||||
|
|
||||||
where *<message>* is the formatted message and *<system-message>* is the
|
where *<message>* is the formatted message and *<system-message>* is the
|
||||||
system message corresponding to the error code.
|
system message corresponding to the error code.
|
||||||
*error_code* is a Windows error code as given by ``GetLastError``.
|
*error_code* is a Windows error code as given by ``GetLastError``.
|
||||||
If *error_code* is not a valid error code such as -1, the system message
|
If *error_code* is not a valid error code such as -1, the system message
|
||||||
will look like "error -1".
|
will look like "error -1".
|
||||||
|
|
||||||
**Example**::
|
**Example**::
|
||||||
|
|
||||||
// This throws a windows_error with the description
|
// This throws a windows_error with the description
|
||||||
// cannot open file 'madeup': The system cannot find the file specified.
|
// cannot open file 'madeup': The system cannot find the file specified.
|
||||||
// or similar (system message may vary).
|
// or similar (system message may vary).
|
||||||
const char *filename = "madeup";
|
const char *filename = "madeup";
|
||||||
LPOFSTRUCT of = LPOFSTRUCT();
|
LPOFSTRUCT of = LPOFSTRUCT();
|
||||||
HFILE file = OpenFile(filename, &of, OF_READ);
|
HFILE file = OpenFile(filename, &of, OF_READ);
|
||||||
if (file == HFILE_ERROR) {
|
if (file == HFILE_ERROR) {
|
||||||
throw fmt::windows_error(GetLastError(),
|
throw fmt::windows_error(GetLastError(),
|
||||||
"cannot open file '{}'", filename);
|
"cannot open file '{}'", filename);
|
||||||
}
|
}
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
windows_error(int error_code, string_view message, const Args&... args) {
|
std::system_error windows_error(int error_code, string_view message,
|
||||||
init(error_code, message, make_format_args(args...));
|
const Args&... args) {
|
||||||
}
|
return vwindows_error(error_code, message, make_format_args(args...));
|
||||||
};
|
}
|
||||||
|
|
||||||
// Reports a Windows error without throwing an exception.
|
// Reports a Windows error without throwing an exception.
|
||||||
// Can be used to report errors from destructors.
|
// Can be used to report errors from destructors.
|
||||||
|
11
src/os.cc
11
src/os.cc
@ -100,13 +100,10 @@ int detail::utf16_to_utf8::convert(wstring_view s) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void windows_error::init(int err_code, string_view format_str,
|
std::system_error vwindows_error(int err_code, string_view format_str,
|
||||||
format_args args) {
|
format_args args) {
|
||||||
error_code_ = err_code;
|
auto ec = std::error_code(err_code, std::system_category());
|
||||||
memory_buffer buffer;
|
throw std::system_error(ec, vformat(format_str, args));
|
||||||
detail::format_windows_error(buffer, err_code, vformat(format_str, args));
|
|
||||||
std::runtime_error& base = *this;
|
|
||||||
base = std::runtime_error(to_string(buffer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void detail::format_windows_error(detail::buffer<char>& out, int error_code,
|
void detail::format_windows_error(detail::buffer<char>& out, int error_code,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
using fmt::buffered_file;
|
using fmt::buffered_file;
|
||||||
using fmt::error_code;
|
using fmt::error_code;
|
||||||
|
using testing::HasSubstr;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
@ -45,14 +46,15 @@ void check_utf_conversion_error(
|
|||||||
fmt::basic_string_view<Char> str = fmt::basic_string_view<Char>(0, 1)) {
|
fmt::basic_string_view<Char> str = fmt::basic_string_view<Char>(0, 1)) {
|
||||||
fmt::memory_buffer out;
|
fmt::memory_buffer out;
|
||||||
fmt::detail::format_windows_error(out, ERROR_INVALID_PARAMETER, message);
|
fmt::detail::format_windows_error(out, ERROR_INVALID_PARAMETER, message);
|
||||||
auto error = fmt::system_error(0, "");
|
out.resize(out.size() - 2); // Remove newline.
|
||||||
|
auto error = std::system_error(std::error_code());
|
||||||
try {
|
try {
|
||||||
(Converter)(str);
|
(Converter)(str);
|
||||||
} catch (const fmt::system_error& e) {
|
} catch (const std::system_error& e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
EXPECT_EQ(ERROR_INVALID_PARAMETER, error.error_code());
|
EXPECT_EQ(ERROR_INVALID_PARAMETER, error.code().value());
|
||||||
EXPECT_EQ(fmt::to_string(out), error.what());
|
EXPECT_THAT(error.what(), HasSubstr(fmt::to_string(out)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(util_test, utf16_to_utf8_error) {
|
TEST(util_test, utf16_to_utf8_error) {
|
||||||
@ -69,11 +71,11 @@ TEST(util_test, utf16_to_utf8_convert) {
|
|||||||
|
|
||||||
TEST(os_test, format_windows_error) {
|
TEST(os_test, format_windows_error) {
|
||||||
LPWSTR message = 0;
|
LPWSTR message = 0;
|
||||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
auto result = FormatMessageW(
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
0, ERROR_FILE_EXISTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
0, ERROR_FILE_EXISTS, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
reinterpret_cast<LPWSTR>(&message), 0, 0);
|
reinterpret_cast<LPWSTR>(&message), 0, 0);
|
||||||
fmt::detail::utf16_to_utf8 utf8_message(message);
|
fmt::detail::utf16_to_utf8 utf8_message(message);
|
||||||
LocalFree(message);
|
LocalFree(message);
|
||||||
fmt::memory_buffer actual_message;
|
fmt::memory_buffer actual_message;
|
||||||
@ -93,16 +95,14 @@ TEST(os_test, format_long_windows_error) {
|
|||||||
// this error code is not available on all Windows platforms and
|
// this error code is not available on all Windows platforms and
|
||||||
// Windows SDKs, so do not fail the test if the error string cannot
|
// Windows SDKs, so do not fail the test if the error string cannot
|
||||||
// be retrieved.
|
// be retrieved.
|
||||||
const int provisioning_not_allowed =
|
int provisioning_not_allowed = 0x80284013L; // TBS_E_PROVISIONING_NOT_ALLOWED
|
||||||
0x80284013L /*TBS_E_PROVISIONING_NOT_ALLOWED*/;
|
auto result = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
0, static_cast<DWORD>(provisioning_not_allowed),
|
||||||
0, static_cast<DWORD>(provisioning_not_allowed),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
reinterpret_cast<LPWSTR>(&message), 0, 0);
|
||||||
reinterpret_cast<LPWSTR>(&message), 0, 0) == 0) {
|
EXPECT_NE(result, 0);
|
||||||
return;
|
|
||||||
}
|
|
||||||
fmt::detail::utf16_to_utf8 utf8_message(message);
|
fmt::detail::utf16_to_utf8 utf8_message(message);
|
||||||
LocalFree(message);
|
LocalFree(message);
|
||||||
fmt::memory_buffer actual_message;
|
fmt::memory_buffer actual_message;
|
||||||
@ -113,16 +113,17 @@ TEST(os_test, format_long_windows_error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(os_test, windows_error) {
|
TEST(os_test, windows_error) {
|
||||||
auto error = fmt::system_error(0, "");
|
auto error = std::system_error(std::error_code());
|
||||||
try {
|
try {
|
||||||
throw fmt::windows_error(ERROR_FILE_EXISTS, "test {}", "error");
|
throw fmt::windows_error(ERROR_FILE_EXISTS, "test {}", "error");
|
||||||
} catch (const fmt::system_error& e) {
|
} catch (const std::system_error& e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
fmt::memory_buffer message;
|
fmt::memory_buffer message;
|
||||||
fmt::detail::format_windows_error(message, ERROR_FILE_EXISTS, "test error");
|
fmt::detail::format_windows_error(message, ERROR_FILE_EXISTS, "test error");
|
||||||
EXPECT_EQ(to_string(message), error.what());
|
message.resize(message.size() - 2);
|
||||||
EXPECT_EQ(ERROR_FILE_EXISTS, error.error_code());
|
EXPECT_THAT(error.what(), HasSubstr(to_string(message)));
|
||||||
|
EXPECT_EQ(ERROR_FILE_EXISTS, error.code().value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(os_test, report_windows_error) {
|
TEST(os_test, report_windows_error) {
|
||||||
|
@ -264,12 +264,16 @@ TEST(file_test, size) {
|
|||||||
EXPECT_GE(f.size(), 0);
|
EXPECT_GE(f.size(), 0);
|
||||||
EXPECT_EQ(content.size(), static_cast<unsigned long long>(f.size()));
|
EXPECT_EQ(content.size(), static_cast<unsigned long long>(f.size()));
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
fmt::memory_buffer message;
|
auto error_code = std::error_code();
|
||||||
fmt::detail::format_windows_error(message, ERROR_ACCESS_DENIED,
|
|
||||||
"cannot get file size");
|
|
||||||
fstat_sim = error;
|
fstat_sim = error;
|
||||||
EXPECT_THROW_MSG(f.size(), fmt::windows_error, fmt::to_string(message));
|
try {
|
||||||
|
f.size();
|
||||||
|
} catch (const std::system_error& e) {
|
||||||
|
error_code = e.code();
|
||||||
|
}
|
||||||
fstat_sim = none;
|
fstat_sim = none;
|
||||||
|
EXPECT_EQ(error_code,
|
||||||
|
std::error_code(ERROR_ACCESS_DENIED, std::system_category()));
|
||||||
# else
|
# else
|
||||||
f.close();
|
f.close();
|
||||||
EXPECT_SYSTEM_ERROR(f.size(), EBADF, "cannot get file attributes");
|
EXPECT_SYSTEM_ERROR(f.size(), EBADF, "cannot get file attributes");
|
||||||
|
Reference in New Issue
Block a user