From b7e3be27982d13dea0bdc3505c77f8631ee978ae Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 27 Aug 2020 17:22:24 +0300 Subject: [PATCH] Add system_category.hpp --- .../system_category_condition_win32.hpp | 146 ++++++++ .../system/detail/system_category_impl.hpp | 18 +- .../detail/system_category_message_win32.hpp | 233 ++++++++++++ .../system/detail/system_category_win32.hpp | 341 ------------------ include/boost/system/error_code.hpp | 5 +- include/boost/system/system_category.hpp | 14 + test/Jamfile.v2 | 1 + test/system_category_test2.cpp | 21 ++ 8 files changed, 432 insertions(+), 347 deletions(-) create mode 100644 include/boost/system/detail/system_category_condition_win32.hpp create mode 100644 include/boost/system/detail/system_category_message_win32.hpp delete mode 100644 include/boost/system/detail/system_category_win32.hpp create mode 100644 include/boost/system/system_category.hpp create mode 100644 test/system_category_test2.cpp diff --git a/include/boost/system/detail/system_category_condition_win32.hpp b/include/boost/system/detail/system_category_condition_win32.hpp new file mode 100644 index 0000000..8bb3062 --- /dev/null +++ b/include/boost/system/detail/system_category_condition_win32.hpp @@ -0,0 +1,146 @@ +#ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_CONDITION_WIN32_HPP_INCLUDED +#define BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_CONDITION_WIN32_HPP_INCLUDED + +// Copyright Beman Dawes 2002, 2006 +// Copyright (c) Microsoft Corporation 2014 +// Copyright 2018 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#include +#include +#include + +// + +namespace boost +{ + +namespace system +{ + +namespace detail +{ + +inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT +{ + // When using the Windows Runtime, most system errors are reported as HRESULTs. + // We want to map the common Win32 errors to their equivalent error condition, + // whether or not they are reported via an HRESULT. + +#define BOOST_SYSTEM_FAILED(hr) ((hr) < 0) +#define BOOST_SYSTEM_HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff) +#define BOOST_SYSTEM_HRESULT_CODE(hr) ((hr) & 0xFFFF) +#define BOOST_SYSTEM_FACILITY_WIN32 7 + + if( BOOST_SYSTEM_FAILED( ev ) && BOOST_SYSTEM_HRESULT_FACILITY( ev ) == BOOST_SYSTEM_FACILITY_WIN32 ) + { + ev = BOOST_SYSTEM_HRESULT_CODE( ev ); + } + +#undef BOOST_SYSTEM_FAILED +#undef BOOST_SYSTEM_HRESULT_FACILITY +#undef BOOST_SYSTEM_HRESULT_CODE +#undef BOOST_SYSTEM_FACILITY_WIN32 + + using namespace boost::winapi; + using namespace errc; + + // Windows system -> posix_errno decode table + // see WinError.h comments for descriptions of errors + + switch ( ev ) + { + case 0: return success; + + case ERROR_ACCESS_DENIED_: return permission_denied; + case ERROR_ALREADY_EXISTS_: return file_exists; + case ERROR_BAD_UNIT_: return no_such_device; + case ERROR_BUFFER_OVERFLOW_: return filename_too_long; + case ERROR_BUSY_: return device_or_resource_busy; + case ERROR_BUSY_DRIVE_: return device_or_resource_busy; + case ERROR_CANNOT_MAKE_: return permission_denied; + case ERROR_CANTOPEN_: return io_error; + case ERROR_CANTREAD_: return io_error; + case ERROR_CANTWRITE_: return io_error; + case ERROR_CONNECTION_ABORTED_: return connection_aborted; + case ERROR_CURRENT_DIRECTORY_: return permission_denied; + case ERROR_DEV_NOT_EXIST_: return no_such_device; + case ERROR_DEVICE_IN_USE_: return device_or_resource_busy; + case ERROR_DIR_NOT_EMPTY_: return directory_not_empty; + case ERROR_DIRECTORY_: return invalid_argument; // WinError.h: "The directory name is invalid" + case ERROR_DISK_FULL_: return no_space_on_device; + case ERROR_FILE_EXISTS_: return file_exists; + case ERROR_FILE_NOT_FOUND_: return no_such_file_or_directory; + case ERROR_HANDLE_DISK_FULL_: return no_space_on_device; + case ERROR_INVALID_ACCESS_: return permission_denied; + case ERROR_INVALID_DRIVE_: return no_such_device; + case ERROR_INVALID_FUNCTION_: return function_not_supported; + case ERROR_INVALID_HANDLE_: return invalid_argument; + case ERROR_INVALID_NAME_: return invalid_argument; + case ERROR_LOCK_VIOLATION_: return no_lock_available; + case ERROR_LOCKED_: return no_lock_available; + case ERROR_NEGATIVE_SEEK_: return invalid_argument; + case ERROR_NOACCESS_: return permission_denied; + case ERROR_NOT_ENOUGH_MEMORY_: return not_enough_memory; + case ERROR_NOT_READY_: return resource_unavailable_try_again; + case ERROR_NOT_SAME_DEVICE_: return cross_device_link; + case ERROR_OPEN_FAILED_: return io_error; + case ERROR_OPEN_FILES_: return device_or_resource_busy; + case ERROR_OPERATION_ABORTED_: return operation_canceled; + case ERROR_OUTOFMEMORY_: return not_enough_memory; + case ERROR_PATH_NOT_FOUND_: return no_such_file_or_directory; + case ERROR_READ_FAULT_: return io_error; + case ERROR_RETRY_: return resource_unavailable_try_again; + case ERROR_SEEK_: return io_error; + case ERROR_SHARING_VIOLATION_: return permission_denied; + case ERROR_TOO_MANY_OPEN_FILES_: return too_many_files_open; + case ERROR_WRITE_FAULT_: return io_error; + case ERROR_WRITE_PROTECT_: return permission_denied; + + case WSAEACCES_: return permission_denied; + case WSAEADDRINUSE_: return address_in_use; + case WSAEADDRNOTAVAIL_: return address_not_available; + case WSAEAFNOSUPPORT_: return address_family_not_supported; + case WSAEALREADY_: return connection_already_in_progress; + case WSAEBADF_: return bad_file_descriptor; + case WSAECONNABORTED_: return connection_aborted; + case WSAECONNREFUSED_: return connection_refused; + case WSAECONNRESET_: return connection_reset; + case WSAEDESTADDRREQ_: return destination_address_required; + case WSAEFAULT_: return bad_address; + case WSAEHOSTUNREACH_: return host_unreachable; + case WSAEINPROGRESS_: return operation_in_progress; + case WSAEINTR_: return interrupted; + case WSAEINVAL_: return invalid_argument; + case WSAEISCONN_: return already_connected; + case WSAEMFILE_: return too_many_files_open; + case WSAEMSGSIZE_: return message_size; + case WSAENAMETOOLONG_: return filename_too_long; + case WSAENETDOWN_: return network_down; + case WSAENETRESET_: return network_reset; + case WSAENETUNREACH_: return network_unreachable; + case WSAENOBUFS_: return no_buffer_space; + case WSAENOPROTOOPT_: return no_protocol_option; + case WSAENOTCONN_: return not_connected; + case WSAENOTSOCK_: return not_a_socket; + case WSAEOPNOTSUPP_: return operation_not_supported; + case WSAEPROTONOSUPPORT_: return protocol_not_supported; + case WSAEPROTOTYPE_: return wrong_protocol_type; + case WSAETIMEDOUT_: return timed_out; + case WSAEWOULDBLOCK_: return operation_would_block; + + default: return -1; + } +} + +} // namespace detail + +} // namespace system + +} // namespace boost + +#endif // #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_CONDITION_WIN32_HPP_INCLUDED diff --git a/include/boost/system/detail/system_category_impl.hpp b/include/boost/system/detail/system_category_impl.hpp index d4a9ba8..60ddeda 100644 --- a/include/boost/system/detail/system_category_impl.hpp +++ b/include/boost/system/detail/system_category_impl.hpp @@ -11,6 +11,7 @@ // See library home page at http://www.boost.org/libs/system #include +#include #include #include @@ -22,11 +23,22 @@ #if defined(BOOST_WINDOWS_API) -#include +#include +#include +#include inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT { - return system_category_default_error_condition_win32( ev ); + int e2 = system_category_condition_win32( ev ); + + if( e2 == -1 ) + { + return error_condition( ev, *this ); + } + else + { + return error_condition( e2, generic_category() ); + } } inline std::string boost::system::detail::system_error_category::message( int ev ) const @@ -41,7 +53,7 @@ inline char const * boost::system::detail::system_error_category::message( int e #else // #if defined(BOOST_WINDOWS_API) -#include +#include #include inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT diff --git a/include/boost/system/detail/system_category_message_win32.hpp b/include/boost/system/detail/system_category_message_win32.hpp new file mode 100644 index 0000000..6cdec2d --- /dev/null +++ b/include/boost/system/detail/system_category_message_win32.hpp @@ -0,0 +1,233 @@ +#ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED +#define BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED + +// Copyright Beman Dawes 2002, 2006 +// Copyright (c) Microsoft Corporation 2014 +// Copyright 2018, 2020 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#include +#include +#include +#include +#include + +// + +namespace boost +{ + +namespace system +{ + +namespace detail +{ + +#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) ) + +inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len ) +{ +# if defined( BOOST_MSVC ) +# pragma warning( push ) +# pragma warning( disable: 4996 ) +# endif + + _snprintf( buffer, len - 1, "Unknown error (%d)", ev ); + + buffer[ len - 1 ] = 0; + return buffer; + +# if defined( BOOST_MSVC ) +# pragma warning( pop ) +# endif +} + +#else + +inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len ) +{ + std::snprintf( buffer, len, "Unknown error (%d)", ev ); + return buffer; +} + +#endif + +inline boost::winapi::UINT_ message_cp_win32() +{ +#if defined(BOOST_SYSTEM_USE_UTF8) + + return boost::winapi::CP_UTF8_; + +#else + + return boost::winapi::CP_ACP_; + +#endif +} + +inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT +{ + if( len == 0 ) + { + return buffer; + } + + if( len == 1 ) + { + buffer[0] = 0; + return buffer; + } + + boost::winapi::UINT_ const code_page = message_cp_win32(); + + int r = 0; + +#if !defined(BOOST_NO_ANSI_APIS) + + if( code_page == boost::winapi::CP_ACP_ ) + { + using namespace boost::winapi; + + DWORD_ retval = boost::winapi::FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_, + NULL, + ev, + MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language + buffer, + static_cast( len ), + NULL + ); + + r = static_cast( retval ); + } + else + +#endif + + { + using namespace boost::winapi; + + wchar_t * lpMsgBuf = 0; + + DWORD_ retval = boost::winapi::FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_, + NULL, + ev, + MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language + (LPWSTR_) &lpMsgBuf, + 0, + NULL + ); + + if( retval != 0 ) + { + r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, buffer, static_cast( len ), NULL, NULL ); + boost::winapi::LocalFree( lpMsgBuf ); + if ( r != 0 ) --r; // exclude null terminator + } + } + + if( r == 0 ) + { + return unknown_message_win32( ev, buffer, len ); + } + + while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) ) + { + buffer[ --r ] = 0; + } + + if( r > 0 && buffer[ r-1 ] == '.' ) + { + buffer[ --r ] = 0; + } + + return buffer; +} + +struct local_free +{ + void * p_; + + ~local_free() + { + boost::winapi::LocalFree( p_ ); + } +}; + +inline std::string unknown_message_win32( int ev ) +{ + char buffer[ 38 ]; + return unknown_message_win32( ev, buffer, sizeof( buffer ) ); +} + +inline std::string system_category_message_win32( int ev ) +{ + using namespace boost::winapi; + + wchar_t * lpMsgBuf = 0; + + DWORD_ retval = boost::winapi::FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_, + NULL, + ev, + MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language + (LPWSTR_) &lpMsgBuf, + 0, + NULL + ); + + if( retval == 0 ) + { + return unknown_message_win32( ev ); + } + + local_free lf_ = { lpMsgBuf }; + (void)lf_; + + UINT_ const code_page = message_cp_win32(); + + int r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, 0, 0, NULL, NULL ); + + if( r == 0 ) + { + return unknown_message_win32( ev ); + } + + std::string buffer( r, char() ); + + r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, &buffer[0], r, NULL, NULL ); + + if( r == 0 ) + { + return unknown_message_win32( ev ); + } + + --r; // exclude null terminator + + while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) ) + { + --r; + } + + if( r > 0 && buffer[ r-1 ] == '.' ) + { + --r; + } + + buffer.resize( r ); + + return buffer; +} + +} // namespace detail + +} // namespace system + +} // namespace boost + +#endif // #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED diff --git a/include/boost/system/detail/system_category_win32.hpp b/include/boost/system/detail/system_category_win32.hpp deleted file mode 100644 index da256e1..0000000 --- a/include/boost/system/detail/system_category_win32.hpp +++ /dev/null @@ -1,341 +0,0 @@ -// Windows implementation of system_error_category -// -// Copyright Beman Dawes 2002, 2006 -// Copyright (c) Microsoft Corporation 2014 -// Copyright 2018 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// See library home page at http://www.boost.org/libs/system - -#include -#include -#include -#include -#include - -// - -namespace boost -{ - -namespace system -{ - -namespace detail -{ - -#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) ) - -inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len ) -{ -# if defined( BOOST_MSVC ) -# pragma warning( push ) -# pragma warning( disable: 4996 ) -# endif - - _snprintf( buffer, len - 1, "Unknown error (%d)", ev ); - - buffer[ len - 1 ] = 0; - return buffer; - -# if defined( BOOST_MSVC ) -# pragma warning( pop ) -# endif -} - -#else - -inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len ) -{ - std::snprintf( buffer, len, "Unknown error (%d)", ev ); - return buffer; -} - -#endif - -inline boost::winapi::UINT_ message_cp_win32() -{ -#if defined(BOOST_SYSTEM_USE_UTF8) - - return boost::winapi::CP_UTF8_; - -#else - - return boost::winapi::CP_ACP_; - -#endif -} - -inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT -{ - if( len == 0 ) - { - return buffer; - } - - if( len == 1 ) - { - buffer[0] = 0; - return buffer; - } - - boost::winapi::UINT_ const code_page = message_cp_win32(); - - int r = 0; - -#if !defined(BOOST_NO_ANSI_APIS) - - if( code_page == boost::winapi::CP_ACP_ ) - { - using namespace boost::winapi; - - DWORD_ retval = boost::winapi::FormatMessageA( - FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_, - NULL, - ev, - MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language - buffer, - static_cast( len ), - NULL - ); - - r = static_cast( retval ); - } - else - -#endif - - { - using namespace boost::winapi; - - wchar_t * lpMsgBuf = 0; - - DWORD_ retval = boost::winapi::FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_, - NULL, - ev, - MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language - (LPWSTR_) &lpMsgBuf, - 0, - NULL - ); - - if( retval != 0 ) - { - r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, buffer, static_cast( len ), NULL, NULL ); - boost::winapi::LocalFree( lpMsgBuf ); - if ( r != 0 ) --r; // exclude null terminator - } - } - - if( r == 0 ) - { - return unknown_message_win32( ev, buffer, len ); - } - - while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) ) - { - buffer[ --r ] = 0; - } - - if( r > 0 && buffer[ r-1 ] == '.' ) - { - buffer[ --r ] = 0; - } - - return buffer; -} - -struct local_free -{ - void * p_; - - ~local_free() - { - boost::winapi::LocalFree( p_ ); - } -}; - -inline std::string unknown_message_win32( int ev ) -{ - char buffer[ 38 ]; - return unknown_message_win32( ev, buffer, sizeof( buffer ) ); -} - -inline std::string system_category_message_win32( int ev ) -{ - using namespace boost::winapi; - - wchar_t * lpMsgBuf = 0; - - DWORD_ retval = boost::winapi::FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_, - NULL, - ev, - MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language - (LPWSTR_) &lpMsgBuf, - 0, - NULL - ); - - if( retval == 0 ) - { - return unknown_message_win32( ev ); - } - - local_free lf_ = { lpMsgBuf }; - (void)lf_; - - UINT_ const code_page = message_cp_win32(); - - int r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, 0, 0, NULL, NULL ); - - if( r == 0 ) - { - return unknown_message_win32( ev ); - } - - std::string buffer( r, char() ); - - r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, &buffer[0], r, NULL, NULL ); - - if( r == 0 ) - { - return unknown_message_win32( ev ); - } - - --r; // exclude null terminator - - while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) ) - { - --r; - } - - if( r > 0 && buffer[ r-1 ] == '.' ) - { - --r; - } - - buffer.resize( r ); - - return buffer; -} - -inline error_condition system_category_default_error_condition_win32( int ev ) BOOST_NOEXCEPT -{ - // When using the Windows Runtime, most system errors are reported as HRESULTs. - // We want to map the common Win32 errors to their equivalent error condition, - // whether or not they are reported via an HRESULT. - -#define BOOST_SYSTEM_FAILED(hr) ((hr) < 0) -#define BOOST_SYSTEM_HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff) -#define BOOST_SYSTEM_HRESULT_CODE(hr) ((hr) & 0xFFFF) -#define BOOST_SYSTEM_FACILITY_WIN32 7 - - if( BOOST_SYSTEM_FAILED( ev ) && BOOST_SYSTEM_HRESULT_FACILITY( ev ) == BOOST_SYSTEM_FACILITY_WIN32 ) - { - ev = BOOST_SYSTEM_HRESULT_CODE( ev ); - } - -#undef BOOST_SYSTEM_FAILED -#undef BOOST_SYSTEM_HRESULT_FACILITY -#undef BOOST_SYSTEM_HRESULT_CODE -#undef BOOST_SYSTEM_FACILITY_WIN32 - - using namespace boost::winapi; - using namespace errc; - - // Windows system -> posix_errno decode table - // see WinError.h comments for descriptions of errors - - switch ( ev ) - { - case 0: return make_error_condition( success ); - - case ERROR_ACCESS_DENIED_: return make_error_condition( permission_denied ); - case ERROR_ALREADY_EXISTS_: return make_error_condition( file_exists ); - case ERROR_BAD_UNIT_: return make_error_condition( no_such_device ); - case ERROR_BUFFER_OVERFLOW_: return make_error_condition( filename_too_long ); - case ERROR_BUSY_: return make_error_condition( device_or_resource_busy ); - case ERROR_BUSY_DRIVE_: return make_error_condition( device_or_resource_busy ); - case ERROR_CANNOT_MAKE_: return make_error_condition( permission_denied ); - case ERROR_CANTOPEN_: return make_error_condition( io_error ); - case ERROR_CANTREAD_: return make_error_condition( io_error ); - case ERROR_CANTWRITE_: return make_error_condition( io_error ); - case ERROR_CONNECTION_ABORTED_: return make_error_condition( connection_aborted ); - case ERROR_CURRENT_DIRECTORY_: return make_error_condition( permission_denied ); - case ERROR_DEV_NOT_EXIST_: return make_error_condition( no_such_device ); - case ERROR_DEVICE_IN_USE_: return make_error_condition( device_or_resource_busy ); - case ERROR_DIR_NOT_EMPTY_: return make_error_condition( directory_not_empty ); - case ERROR_DIRECTORY_: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid" - case ERROR_DISK_FULL_: return make_error_condition( no_space_on_device ); - case ERROR_FILE_EXISTS_: return make_error_condition( file_exists ); - case ERROR_FILE_NOT_FOUND_: return make_error_condition( no_such_file_or_directory ); - case ERROR_HANDLE_DISK_FULL_: return make_error_condition( no_space_on_device ); - case ERROR_INVALID_ACCESS_: return make_error_condition( permission_denied ); - case ERROR_INVALID_DRIVE_: return make_error_condition( no_such_device ); - case ERROR_INVALID_FUNCTION_: return make_error_condition( function_not_supported ); - case ERROR_INVALID_HANDLE_: return make_error_condition( invalid_argument ); - case ERROR_INVALID_NAME_: return make_error_condition( invalid_argument ); - case ERROR_LOCK_VIOLATION_: return make_error_condition( no_lock_available ); - case ERROR_LOCKED_: return make_error_condition( no_lock_available ); - case ERROR_NEGATIVE_SEEK_: return make_error_condition( invalid_argument ); - case ERROR_NOACCESS_: return make_error_condition( permission_denied ); - case ERROR_NOT_ENOUGH_MEMORY_: return make_error_condition( not_enough_memory ); - case ERROR_NOT_READY_: return make_error_condition( resource_unavailable_try_again ); - case ERROR_NOT_SAME_DEVICE_: return make_error_condition( cross_device_link ); - case ERROR_OPEN_FAILED_: return make_error_condition( io_error ); - case ERROR_OPEN_FILES_: return make_error_condition( device_or_resource_busy ); - case ERROR_OPERATION_ABORTED_: return make_error_condition( operation_canceled ); - case ERROR_OUTOFMEMORY_: return make_error_condition( not_enough_memory ); - case ERROR_PATH_NOT_FOUND_: return make_error_condition( no_such_file_or_directory ); - case ERROR_READ_FAULT_: return make_error_condition( io_error ); - case ERROR_RETRY_: return make_error_condition( resource_unavailable_try_again ); - case ERROR_SEEK_: return make_error_condition( io_error ); - case ERROR_SHARING_VIOLATION_: return make_error_condition( permission_denied ); - case ERROR_TOO_MANY_OPEN_FILES_: return make_error_condition( too_many_files_open ); - case ERROR_WRITE_FAULT_: return make_error_condition( io_error ); - case ERROR_WRITE_PROTECT_: return make_error_condition( permission_denied ); - case WSAEACCES_: return make_error_condition( permission_denied ); - case WSAEADDRINUSE_: return make_error_condition( address_in_use ); - case WSAEADDRNOTAVAIL_: return make_error_condition( address_not_available ); - case WSAEAFNOSUPPORT_: return make_error_condition( address_family_not_supported ); - case WSAEALREADY_: return make_error_condition( connection_already_in_progress ); - case WSAEBADF_: return make_error_condition( bad_file_descriptor ); - case WSAECONNABORTED_: return make_error_condition( connection_aborted ); - case WSAECONNREFUSED_: return make_error_condition( connection_refused ); - case WSAECONNRESET_: return make_error_condition( connection_reset ); - case WSAEDESTADDRREQ_: return make_error_condition( destination_address_required ); - case WSAEFAULT_: return make_error_condition( bad_address ); - case WSAEHOSTUNREACH_: return make_error_condition( host_unreachable ); - case WSAEINPROGRESS_: return make_error_condition( operation_in_progress ); - case WSAEINTR_: return make_error_condition( interrupted ); - case WSAEINVAL_: return make_error_condition( invalid_argument ); - case WSAEISCONN_: return make_error_condition( already_connected ); - case WSAEMFILE_: return make_error_condition( too_many_files_open ); - case WSAEMSGSIZE_: return make_error_condition( message_size ); - case WSAENAMETOOLONG_: return make_error_condition( filename_too_long ); - case WSAENETDOWN_: return make_error_condition( network_down ); - case WSAENETRESET_: return make_error_condition( network_reset ); - case WSAENETUNREACH_: return make_error_condition( network_unreachable ); - case WSAENOBUFS_: return make_error_condition( no_buffer_space ); - case WSAENOPROTOOPT_: return make_error_condition( no_protocol_option ); - case WSAENOTCONN_: return make_error_condition( not_connected ); - case WSAENOTSOCK_: return make_error_condition( not_a_socket ); - case WSAEOPNOTSUPP_: return make_error_condition( operation_not_supported ); - case WSAEPROTONOSUPPORT_: return make_error_condition( protocol_not_supported ); - case WSAEPROTOTYPE_: return make_error_condition( wrong_protocol_type ); - case WSAETIMEDOUT_: return make_error_condition( timed_out ); - case WSAEWOULDBLOCK_: return make_error_condition( operation_would_block ); - - default: return error_condition( ev, system_category() ); - } -} - -} // namespace detail - -} // namespace system - -} // namespace boost diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 6f02f1e..c34c2c0 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -14,9 +14,8 @@ #include #include #include -#include -#include -#include +#include +#include #include #include diff --git a/include/boost/system/system_category.hpp b/include/boost/system/system_category.hpp new file mode 100644 index 0000000..fe08bc6 --- /dev/null +++ b/include/boost/system/system_category.hpp @@ -0,0 +1,14 @@ +#ifndef BOOST_SYSTEM_SYSTEM_CATEGORY_HPP_INCLUDED +#define BOOST_SYSTEM_SYSTEM_CATEGORY_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// http://www.boost.org/LICENSE_1_0.txt +// +// See library home page at http://www.boost.org/libs/system + +#include +#include +#include + +#endif // #ifndef BOOST_SYSTEM_SYSTEM_CATEGORY_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 0739890..4ff3965 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -81,3 +81,4 @@ run error_category_test2.cpp ; run error_condition_test.cpp ; run error_condition_test2.cpp ; run generic_category_test2.cpp ; +run system_category_test2.cpp ; diff --git a/test/system_category_test2.cpp b/test/system_category_test2.cpp new file mode 100644 index 0000000..46e02a8 --- /dev/null +++ b/test/system_category_test2.cpp @@ -0,0 +1,21 @@ +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +// Tests whether system_category() is functional when only +// system_category.hpp is included + +namespace sys = boost::system; + +int main() +{ + sys::error_category const & cat = sys::system_category(); + + BOOST_TEST_CSTR_EQ( cat.name(), "system" ); + + return boost::report_errors(); +}