From 7ffc036bc2c5ea128d9a7dbde217b9f6c6e010e9 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Tue, 6 Jul 2010 10:47:30 +0000 Subject: [PATCH] Merge trunk, including changes to come into closer conformance with C++0x FCD [SVN r63685] --- doc/index.html | 16 +- doc/reference.html | 167 +++++++------- include/boost/system/api_config.hpp | 42 ++++ include/boost/system/config.hpp | 47 +--- include/boost/system/cygwin_error.hpp | 4 +- include/boost/system/error_code.hpp | 32 +-- include/boost/system/linux_error.hpp | 4 +- include/boost/system/system_error.hpp | 13 +- include/boost/system/windows_error.hpp | 4 +- src/error_code.cpp | 45 ++-- src/local_free_on_destruction.hpp | 40 ++++ test/Jamfile.v2 | 16 +- test/dynamic_link_test.cpp | 55 +++++ test/error_code_test.cpp | 206 ++++++++++-------- test/error_code_user_test.cpp | 100 ++++----- test/header_only_test.cpp | 9 +- test/initialization_test.cpp | 6 +- test/system_error_test.cpp | 55 ++--- test/system_msvc/common.vsprops | 7 +- .../error_code_test/error_code_test.vcproj | 12 +- test/system_msvc/system_msvc.sln | 37 ++++ test/throw_test.cpp | 31 +++ 22 files changed, 585 insertions(+), 363 deletions(-) create mode 100644 include/boost/system/api_config.hpp create mode 100644 src/local_free_on_destruction.hpp create mode 100644 test/dynamic_link_test.cpp create mode 100644 test/throw_test.cpp diff --git a/doc/index.html b/doc/index.html index 50a6267..38ab455 100644 --- a/doc/index.html +++ b/doc/index.html @@ -6,7 +6,7 @@ Boost System Library - + @@ -93,6 +93,18 @@ supports both error reporting by exception and by error code.

error_code.hpp header, system-specific headers support the Cygwin, Linux, and Windows platforms. These headers are effectively no-ops if included for platforms other than their intended target.

+ + + + +
The Boost System Library will become part of the C++0x Standard Library. + A number of changes, particularly to names, were made by the C++ committee + during standardization. The Boost implementation is tracking those changes. + See Deprecated names for + synonyms provided to prevent breakage of existing user code. See + Breaking changes for changes + that unavoidably break existing user code. All breaking changes are noisy + and will cause compile-time errors.

Design Rationale

Class error_code  and error_condition are designed as a value types so they can be copied @@ -133,7 +145,7 @@ paper. Johan Nilsson's comments led to several of the refinements in N2066 .


Revised -February 23, 2008 +May 28, 2010

© Copyright Beman Dawes, 1999

diff --git a/doc/reference.html b/doc/reference.html index 82ad2c8..05c2102 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -6,7 +6,7 @@ System Library Reference - + @@ -40,6 +40,7 @@ Introduction
Macros
Deprecated names
+ Breaking changes
Header <boost/system/error_code.hpp>
Class error_category
   Class error_category synopsis
@@ -77,55 +78,50 @@ errno.

Macros

Users may defined the following macros if desired. Sensible defaults are provided, so users may ignore these macros if they prefer.

- +
- - - + + + - - - - - - - - - - - - + - - - + - - - - + + + -
Macro NameDefaultEffect if definedMacro NameDefaultEffect if defined
BOOST_WINDOWS_APIDefined if Windows is detected by Boost.System's automatic configuration - code, otherwise not defined.Implementation uses the Microsoft Windows native - application program interface (API).
BOOST_POSIX_APIDefined if Windows is not detected by Boost.System's automatic configuration - code.Implementation uses the POSIX native - application program interface (API).
BOOST_SYSTEM_DYN_LINKDefined if BOOST_ALL_DYN_LINK is defined, + BOOST_SYSTEM_DYN_LINKDefined if BOOST_ALL_DYN_LINK is defined, otherwise not defined.Boost.System library is dynamically linked. If not defined, + Boost.System library is dynamically linked. If not defined, static linking is assumed.
BOOST_SYSTEM_NO_LIBDefined if BOOST_ALL_NO_LIB is defined, + BOOST_SYSTEM_NO_LIBDefined if BOOST_ALL_NO_LIB is defined, otherwise not defined.Boost.System library does not use the Boost auto-link + Boost.System library does not use the Boost auto-link facility.
BOOST_SYSTEM_NO_DEPRECATEDNot defined.Deprecated features are excluded.BOOST_SYSTEM_NO_DEPRECATEDNot defined.Deprecated features are excluded.
+

Deprecated names

-

In the process of adding Boost.System to C++0x standard library, some of the -names are being changed. To ease transition, Boost.System deprecates the old +

In the process of adding Boost.System to C++0x standard library, the C++ +committee changed some +names. To ease transition, Boost.System deprecates the old names, but continues to provide them unless macro BOOST_SYSTEM_NO_DEPRECATED is defined.

- - + + + + + + + + + + @@ -141,21 +137,39 @@ is defined.

- + - + - + - +
Old name, now deprecatedNew nameOld usage, now deprecatedReplacement
get_generic_category()generic_category()
get_system_category()system_category()
namespace posix
get_posix_category()get_generic_category()generic_category()
posix_categorygeneric_categorygeneric_category()
errno_ecatgeneric_categorygeneric_category()
native_ecatsystem_categorysystem_category()
+

Breaking changes

+

Two static consts are replaced by functions. These are breaking changes best +fixed by globally adding () to these names to turn them into function calls.

+ + + + + + + + + + + + + +
Old usage, now brokenReplacement
generic_categorygeneric_category()
system_categorysystem_category()
+

User-defined BOOST_POSIX_API and BOOST_WINDOWS_API macros are no longer supported.

Header <boost/system/error_code.hpp>

<boost/system/error_code.hpp> synopsis

@@ -265,9 +279,6 @@ is defined.

template<> struct is_error_condition_enum<errc::errc_t> { static const bool value = true; }; - // predefined error_code object used as "throw on error" tag - extern error_code throws; - // non-member functions bool operator==( const error_code & lhs, const error_code & rhs ); @@ -336,11 +347,8 @@ types should create a single object of each such type. bool operator< ( const error_category & rhs ) const; }; - const error_category & get_system_category(); - const error_category & get_generic_category(); - - static const error_category & system_category = get_system_category(); - static const error_category & generic_category = get_generic_category(); + const error_category & system_category(); + const error_category & generic_category(); } }
@@ -362,8 +370,8 @@ this subclause.

Returns:  error_condition( ev, *this ).

-

 [--Note: Derived classes will typically convert ev - to some portable error_category, such as generic_category, +

 [--Note: Derived classes will typically convert ev + to some portable error_category, such as generic_category(), and return it as an error_condition for that category. --end note]

@@ -402,22 +410,18 @@ const;

Class error_category non-member functions

-
const error_category & get_system_category();
+
const error_category & system_category();

Returns: A reference to a error_category object identifying errors originating from the operating system.

Throws: Nothing.

-
const error_category & get_generic_category();
+
const error_category & generic_category();

Returns: A reference to a error_category object identifying portable error conditions.

Throws: Nothing.

-

Class error_category -predefined objects

-

Predefined objects system_category -and generic_category identify system specific error codes and portable error conditions, respectively.

Class error_code

The class error_code describes an object used to hold error code @@ -439,14 +443,12 @@ error_code synopsis error_code(); error_code( val, const error_category & cat ); template <class ErrorCodeEnum> - error_code( ErrorCodeEnum e, - typename enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0); + error_code( ErrorCodeEnum e ); // modifiers: void assign( int val, const error_category & cat ); template<typename ErrorCodeEnum> - typename enable_if<is_error_code_enum<ErrorCodeEnum>, error_code>::type & - operator=( ErrorCodeEnum val );; + error_code & operator=( ErrorCodeEnum val );; void clear(); // observers: @@ -468,7 +470,7 @@ error_code constructors

error_code();

Effects: Constructs an object of type error_code.

-

Postconditions: val_ == 0 && cat_ == &system_category.

+

Postconditions: val_ == 0 && cat_ == &system_category().

Throws: Nothing.

error_code( int val, const error_category & cat );
@@ -478,12 +480,14 @@ error_code constructors

Throws: Nothing.

template <class ErrorCodeEnum>
-  error_code( errorCodeEnum val,
-    typename enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0);
+ error_code( ErrorCodeEnum val );

Effects: Constructs an object of type error_code.

Postconditions: *this == make_error_code( val ).

Throws: Nothing.

+

Remarks: This constructor shall not participate in overload + resolution unless is_error_code_enum<ErrorCodeEnum>::value is + true.

Class error_code modifiers

@@ -493,15 +497,17 @@ error_code modifiers

Throws: Nothing.

template<typename ErrorCodeEnum>
-  typename enable_if<is_error_code_enum<ErrorCodeEnum>, error_code>::type &
-    operator=( ErrorCodeEnum val );
+ error_code & operator=( ErrorCodeEnum val );

Postconditions: *this == make_error_code( val ).

Throws: Nothing.

+

Remarks: This operator shall not participate in overload resolution + unless is_error_code_enum<ErrorCodeEnum>::value is true.

void clear();

-

postcondition: value() == 0 && category() == generic_category

+

postcondition: value() == 0 && category() == + system_category()

Class error_code observers

@@ -557,14 +563,12 @@ implementation specific. --end note ]

error_condition(); error_condition( int val, const error_category & cat ); template <class ErrorConditionEnum> - error_condition( errorConditionEnum val, - typename enable_if<is_error_condition_enum<ErrorConditionEnum> >::type* = 0 ); + error_condition( errorConditionEnum val ); // modifiers: void assign( int val, const error_category & cat ); template<typename ErrorConditionEnum> - typename enable_if<is_error_condition_enum<ErrorConditionEnum>, error_code>::type & - operator=( ErrorConditionEnum val ); + error_condition & operator=( ErrorConditionEnum val ); void clear(); // observers: @@ -585,7 +589,7 @@ constructors
error_condition(); 

Effects: Constructs an object of type error_condition.

-

Postconditions: val_ == 0 and cat_ == &generic_category.

+

Postconditions: val_ == 0 and cat_ == &generic_category().

Throws: Nothing.

error_condition( int val, const error_category & cat );
@@ -595,12 +599,14 @@ constructors

Throws: Nothing.

template <class ErrorConditionEnum>
-  error_condition( errorConditionEnum val,
-    typename enable_if<is_error_condition_enum<ErrorConditionEnum> >::type* = 0 );
+ error_condition( ErrorConditionEnum e );

Effects: Constructs an object of type error_condition.

-

Postconditions: *this == make_error_condition( val ).

+

Postconditions: *this == make_error_condition(e).

Throws: Nothing.

+

Remarks: This constructor shall not participate in overload + resolution unless is_error_condition_enum<ErrorConditionEnum>::value + is true.

Class error_condition modifiers

@@ -610,15 +616,18 @@ modifiers

Throws: Nothing.

template<typename ErrorConditionEnum>
-  typename enable_if<is_error_condition_enum<ErrorConditionEnum>, error_code>::type &
-    operator=( ErrorConditionEnum val );
+ error_condition & operator=( ErrorConditionEnum e );
-

Postconditions: *this == make_error_condition( val ).

+

Postconditions: *this == make_error_condition( e ).

+

Returns: *this.

Throws: Nothing.

+

Remarks: This operator shall not participate in overload resolution + unless is_error_condition_enum<ErrorConditionEnum>::value is + true.

void clear();

-

postcondition: value() == 0 && category() == generic_category

+

postcondition: value() == 0 && category() == generic_category()

Class error_condition observers

@@ -730,11 +739,11 @@ bool operator!=( const error_condition & condition, const error_code & c
error_code make_error_code( errc::errc_t e );
-

Returns: error_code( e, generic_category).

+

Returns: error_code( e, generic_category()).

error_condition make_error_condition( errc::errc_t e );
-

Returns: error_condition( static_cast<int>( e ), generic_category).

+

Returns: error_condition( static_cast<int>( e ), generic_category()).

template <class charT, class traits>
@@ -831,7 +840,7 @@ application program interfaces.


Revised -October 11, 2008 +June 29, 2010

© Copyright Beman Dawes, 2006, 2007, 2008

@@ -841,4 +850,4 @@ application program interfaces.

- + \ No newline at end of file diff --git a/include/boost/system/api_config.hpp b/include/boost/system/api_config.hpp new file mode 100644 index 0000000..28b8bec --- /dev/null +++ b/include/boost/system/api_config.hpp @@ -0,0 +1,42 @@ +// boost/system/api_config.hpp -------------------------------------------------------// + +// Copyright Beman Dawes 2003, 2006, 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/system for documentation. + +//--------------------------------------------------------------------------------------// + +// Boost.System calls operating system API functions to implement system error category +// functions. Usually there is no question as to which API is to be used. +// +// In the case of MinGW or Cygwin/MinGW, however, both POSIX and Windows API's are +// available. Chaos ensues if other code thinks one is in use when Boost.System was +// actually built with the other. This header centralizes the API choice and prevents +// user definition of API macros, thus elminating the possibility of mismatches and the +// need to test configurations with little or no practical value. +// + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_SYSTEM_API_CONFIG_HPP +#define BOOST_SYSTEM_API_CONFIG_HPP + +# if defined(BOOST_POSIX_API) || defined(BOOST_WINDOWS_API) +# error user defined BOOST_POSIX_API or BOOST_WINDOWS_API not supported +# endif + +// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use +// Cygwin/MinGW does not predefine _WIN32. +// Standalone MinGW and all other known Windows compilers do predefine _WIN32 +// Compilers that predefine _WIN32 or __MINGW32__ do so for Windows 64-bit builds too. + +# if defined(_WIN32) || defined(__CYGWIN__) // Windows default, including MinGW and Cygwin +# define BOOST_WINDOWS_API +# else +# define BOOST_POSIX_API +# endif + +#endif // BOOST_SYSTEM_API_CONFIG_HPP diff --git a/include/boost/system/config.hpp b/include/boost/system/config.hpp index fa09099..bf78051 100644 --- a/include/boost/system/config.hpp +++ b/include/boost/system/config.hpp @@ -1,4 +1,4 @@ -// boost/system/config.hpp -------------------------------------------------// +// boost/system/config.hpp -----------------------------------------------------------// // Copyright Beman Dawes 2003, 2006 @@ -11,47 +11,24 @@ #define BOOST_SYSTEM_CONFIG_HPP #include +#include // for BOOST_POSIX_API or BOOST_WINDOWS_API -// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use. -// If not specified, a sensible default will be applied. +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html -# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API ) -# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined -# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API ) -# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) -# define BOOST_WINDOWS_API -# else -# define BOOST_POSIX_API -# endif -# endif +// enable dynamic or static linking as requested --------------------------------------// -// enable dynamic linking on Windows ---------------------------------------// - -//# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__) -//# error Dynamic linking Boost.System does not work for Borland; use static linking instead -//# endif - -#ifdef BOOST_HAS_DECLSPEC // defined in config system -// we need to import/export our code only if the user has specifically -// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost -// libraries to be dynamically linked, or BOOST_SYSTEM_DYN_LINK -// if they want just this one to be dynamically liked: #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) -// export if this is our own source, otherwise import: -#ifdef BOOST_SYSTEM_SOURCE -# define BOOST_SYSTEM_DECL __declspec(dllexport) +# if defined(BOOST_SYSTEM_SOURCE) +# define BOOST_SYSTEM_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_SYSTEM_DECL BOOST_SYMBOL_IMPORT +# endif #else -# define BOOST_SYSTEM_DECL __declspec(dllimport) -#endif // BOOST_SYSTEM_SOURCE -#endif // DYN_LINK -#endif // BOOST_HAS_DECLSPEC -// -// if BOOST_SYSTEM_DECL isn't defined yet define it now: -#ifndef BOOST_SYSTEM_DECL -#define BOOST_SYSTEM_DECL +# define BOOST_SYSTEM_DECL #endif -// enable automatic library variant selection ------------------------------// +// enable automatic library variant selection ----------------------------------------// #if !defined(BOOST_SYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SYSTEM_NO_LIB) // diff --git a/include/boost/system/cygwin_error.hpp b/include/boost/system/cygwin_error.hpp index 4955be9..ea3528b 100644 --- a/include/boost/system/cygwin_error.hpp +++ b/include/boost/system/cygwin_error.hpp @@ -23,7 +23,7 @@ namespace boost { // To construct an error_code after a API error: // - // error_code( errno, system_category ) + // error_code( errno, system_category() ) // User code should use the portable "posix" enums for POSIX errors; this // allows such code to be portable to non-POSIX systems. For the non-POSIX @@ -46,7 +46,7 @@ namespace boost namespace cygwin_error { inline error_code make_error_code( cygwin_errno e ) - { return error_code( e, get_system_category() ); } + { return error_code( e, system_category() ); } } } } diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index d0eb6c5..b22775f 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -202,18 +202,18 @@ namespace boost // predefined error categories -----------------------------------------// - BOOST_SYSTEM_DECL const error_category & get_system_category(); - BOOST_SYSTEM_DECL const error_category & get_generic_category(); + BOOST_SYSTEM_DECL const error_category & system_category(); + BOOST_SYSTEM_DECL const error_category & generic_category(); + + // deprecated synonyms --------------------------------------------------// - static const error_category & system_category = get_system_category(); - static const error_category & generic_category = get_generic_category(); - # ifndef BOOST_SYSTEM_NO_DEPRECATED - // deprecated synonyms - inline const error_category & get_posix_category() { return get_generic_category(); } - static const error_category & posix_category = get_generic_category(); - static const error_category & errno_ecat = get_generic_category(); - static const error_category & native_ecat = get_system_category(); + inline const error_category & get_system_category() { return system_category(); } + inline const error_category & get_generic_category() { return generic_category(); } + inline const error_category & get_posix_category() { return generic_category(); } + static const error_category & posix_category = generic_category(); + static const error_category & errno_ecat = generic_category(); + static const error_category & native_ecat = system_category(); # endif // class error_condition -----------------------------------------------// @@ -225,7 +225,7 @@ namespace boost public: // constructors: - error_condition() : m_val(0), m_cat(&get_generic_category()) {} + error_condition() : m_val(0), m_cat(&generic_category()) {} error_condition( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {} template @@ -254,7 +254,7 @@ namespace boost void clear() { m_val = 0; - m_cat = &get_generic_category(); + m_cat = &generic_category(); } // observers: @@ -312,7 +312,7 @@ namespace boost public: // constructors: - error_code() : m_val(0), m_cat(&get_system_category()) {} + error_code() : m_val(0), m_cat(&system_category()) {} error_code( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {} template @@ -340,7 +340,7 @@ namespace boost void clear() { m_val = 0; - m_cat = &get_system_category(); + m_cat = &system_category(); } // observers: @@ -473,11 +473,11 @@ namespace boost { // explicit conversion: inline error_code make_error_code( errc_t e ) - { return error_code( e, get_generic_category() ); } + { return error_code( e, generic_category() ); } // implicit conversion: inline error_condition make_error_condition( errc_t e ) - { return error_condition( e, get_generic_category() ); } + { return error_condition( e, generic_category() ); } } // error_category default implementation -------------------------------// diff --git a/include/boost/system/linux_error.hpp b/include/boost/system/linux_error.hpp index 2998253..0eb22bf 100644 --- a/include/boost/system/linux_error.hpp +++ b/include/boost/system/linux_error.hpp @@ -23,7 +23,7 @@ namespace boost { // To construct an error_code after a API error: // - // error_code( errno, system_category ) + // error_code( errno, system_category() ) // User code should use the portable "posix" enums for POSIX errors; this // allows such code to be portable to non-POSIX systems. For the non-POSIX @@ -99,7 +99,7 @@ namespace boost namespace linux_error { inline error_code make_error_code( linux_errno e ) - { return error_code( e, get_system_category() ); } + { return error_code( e, system_category() ); } } } // namespace system diff --git a/include/boost/system/system_error.hpp b/include/boost/system/system_error.hpp index 4091647..065d365 100644 --- a/include/boost/system/system_error.hpp +++ b/include/boost/system/system_error.hpp @@ -17,9 +17,11 @@ namespace boost { namespace system { - // class system_error --------------------------------------------------// + // class system_error ------------------------------------------------------------// - class system_error : public std::runtime_error + class BOOST_SYMBOL_VISIBLE system_error : public std::runtime_error + // BOOST_SYMBOL_VISIBLE is needed by GCC to ensure system_error thrown from a shared + // library can be caught. See svn.boost.org/trac/boost/ticket/3697 { public: system_error( error_code ec ) @@ -62,11 +64,8 @@ namespace boost try { m_what = this->std::runtime_error::what(); - if ( m_error_code ) - { - if ( !m_what.empty() ) m_what += ": "; - m_what += m_error_code.message(); - } + if ( !m_what.empty() ) m_what += ": "; + m_what += m_error_code.message(); } catch (...) { return std::runtime_error::what(); } } diff --git a/include/boost/system/windows_error.hpp b/include/boost/system/windows_error.hpp index b6d2f0f..fff3a98 100644 --- a/include/boost/system/windows_error.hpp +++ b/include/boost/system/windows_error.hpp @@ -29,7 +29,7 @@ namespace boost // To construct an error_code after a API error: // - // error_code( ::GetLastError(), system_category ) + // error_code( ::GetLastError(), system_category() ) namespace windows_error { @@ -107,7 +107,7 @@ namespace boost namespace windows_error { inline error_code make_error_code( windows_error_code e ) - { return error_code( e, get_system_category() ); } + { return error_code( e, system_category() ); } } } // namespace system diff --git a/src/error_code.cpp b/src/error_code.cpp index fa2cb0b..bd87403 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -29,8 +29,9 @@ using namespace boost::system::errc; # if defined( BOOST_WINDOWS_API ) # include +# include "local_free_on_destruction.hpp" # ifndef ERROR_INCORRECT_SIZE -# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS +# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS # endif # endif @@ -159,7 +160,7 @@ namespace switch ( ev ) { case 0: return make_error_condition( success ); - # if defined(BOOST_POSIX_API) +# if defined(BOOST_POSIX_API) // POSIX-like O/S -> posix_errno decode table ---------------------------// case E2BIG: return make_error_condition( argument_list_too_long ); case EACCES: return make_error_condition( permission_denied ); @@ -221,7 +222,9 @@ namespace # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value case ENOTEMPTY: return make_error_condition( directory_not_empty ); # endif // ENOTEMPTY != EEXIST - case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); + # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips + case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); + # endif // ENOTRECOVERABLE != ECONNRESET case ENOTSOCK: return make_error_condition( not_a_socket ); case ENOTSUP: return make_error_condition( not_supported ); case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); @@ -230,7 +233,9 @@ namespace case EOPNOTSUPP: return make_error_condition( operation_not_supported ); # endif // EOPNOTSUPP != ENOTSUP case EOVERFLOW: return make_error_condition( value_too_large ); - case EOWNERDEAD: return make_error_condition( owner_dead ); + # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips + case EOWNERDEAD: return make_error_condition( owner_dead ); + # endif // EOWNERDEAD != ECONNABORTED case EPERM: return make_error_condition( operation_not_permitted ); case EPIPE: return make_error_condition( broken_pipe ); case EPROTO: return make_error_condition( protocol_error ); @@ -325,7 +330,7 @@ namespace case WSAETIMEDOUT: return make_error_condition( timed_out ); case WSAEWOULDBLOCK: return make_error_condition( operation_would_block ); #endif - default: return error_condition( ev, system_category ); + default: return error_condition( ev, system_category() ); } } @@ -333,28 +338,14 @@ namespace std::string system_error_category::message( int ev ) const { - return generic_category.message( ev ); + return generic_category().message( ev ); } # else -// TODO: - -//Some quick notes on the implementation (sorry for the noise if -//someone has already mentioned them): -// -//- The ::LocalFree() usage isn't exception safe. -// -//See: -// -// -// -//in the implementation of what() for an example. -// -//Cheers, -//Chris + std::string system_error_category::message( int ev ) const { # ifndef BOOST_NO_ANSI_APIS - LPVOID lpMsgBuf; + LPVOID lpMsgBuf = 0; DWORD retval = ::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | @@ -366,13 +357,13 @@ namespace 0, NULL ); + detail::local_free_on_destruction lfod(lpMsgBuf); if (retval == 0) return std::string("Unknown error"); std::string str( static_cast(lpMsgBuf) ); - ::LocalFree( lpMsgBuf ); // free the buffer # else // WinCE workaround - LPVOID lpMsgBuf; + LPVOID lpMsgBuf = 0; DWORD retval = ::FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | @@ -384,6 +375,7 @@ namespace 0, NULL ); + detail::local_free_on_destruction lfod(lpMsgBuf); if (retval == 0) return std::string("Unknown error"); @@ -393,7 +385,6 @@ namespace return std::string("Unknown error"); std::string str( narrow_buffer ); - ::LocalFree( lpMsgBuf ); // free the buffer # endif while ( str.size() && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) @@ -419,13 +410,13 @@ namespace boost // address for comparison purposes # endif - BOOST_SYSTEM_DECL const error_category & get_system_category() + BOOST_SYSTEM_DECL const error_category & system_category() { static const system_error_category system_category_const; return system_category_const; } - BOOST_SYSTEM_DECL const error_category & get_generic_category() + BOOST_SYSTEM_DECL const error_category & generic_category() { static const generic_error_category generic_category_const; return generic_category_const; diff --git a/src/local_free_on_destruction.hpp b/src/local_free_on_destruction.hpp new file mode 100644 index 0000000..110024f --- /dev/null +++ b/src/local_free_on_destruction.hpp @@ -0,0 +1,40 @@ +// local_free_on_exit.hpp ------------------------------------------------------------// + +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2010 Beman Dawes + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// This is derived from boost/asio/detail/local_free_on_block_exit.hpp to avoid +// a dependency on asio. Thanks to Chris Kohlhoff for pointing it out. + +#ifndef BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP +#define BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP + +namespace boost { +namespace system { +namespace detail { + +class local_free_on_destruction +{ +public: + explicit local_free_on_destruction(void* p) + : p_(p) {} + + ~local_free_on_destruction() + { + ::LocalFree(p_); + } + +private: + void* p_; + local_free_on_destruction(const local_free_on_destruction&); // = deleted + local_free_on_destruction& operator=(const local_free_on_destruction&); // = deleted +}; + +} // namespace detail +} // namespace system +} // namespace boost + +#endif // BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 7b14c76..043a36f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -12,6 +12,12 @@ project /boost/system//boost_system msvc:on ; + + lib throw_test + : throw_test.cpp + : shared:BOOST_SYSTEM_DYN_LINK=1 + ; + test-suite "system" : [ run error_code_test.cpp @@ -21,21 +27,25 @@ project static ] [ run error_code_test.cpp - : : : : error_code_test_dll + : : : shared : error_code_test_shared ] [ run error_code_user_test.cpp : : : static ] [ run error_code_user_test.cpp - : : : : error_code_user_test_dll + : : : shared : error_code_user_test_shared ] [ run system_error_test.cpp : : : static ] [ run system_error_test.cpp - : : : : system_error_test_dll + : : : shared : system_error_test_shared + ] + [ run dynamic_link_test.cpp throw_test + : : : shared : throw_test_shared ] [ run initialization_test.cpp + : : : shared : initialization_test_shared ] [ run header_only_test.cpp : : : static diff --git a/test/dynamic_link_test.cpp b/test/dynamic_link_test.cpp new file mode 100644 index 0000000..87f37c2 --- /dev/null +++ b/test/dynamic_link_test.cpp @@ -0,0 +1,55 @@ +// dynamic_link_test.cpp -------------------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See www.boost.org/LICENSE_1_0.txt + +// Library home page is www.boost.org/libs/system + +//--------------------------------------------------------------------------------------// + +// Dynamic link libraries (DLL's), also know as dynamic shared objects (DSO's), +// can cause symbol visability problems unless carefully configured. One of the +// manifestations, particularly with GCC, is that a system_error exception thrown from +// a DLL or DSO is not caught. +// +// The purpose of this program is to test for that error. + +//--------------------------------------------------------------------------------------// + +#include + +#include + +namespace boost +{ + namespace system + { + BOOST_SYSTEM_DECL void throw_test(); + } +} + +int main() +{ + try + { + boost::system::throw_test(); + } + catch (const boost::system::system_error& ex) + { + std::cout << " caught boost::system::system_error as expected\n"; + std::cout << " what() reports " << ex.what() << '\n'; + return 0; + } + + catch (const std::runtime_error& ex) + { + std::cout << " error: caught std::runtime_error instead of boost::system::system_error\n"; + std::cout << " what() reports " << ex.what() << '\n'; + return 1; + } + + std::cout << " error: failed to catch boost::system::system_error\n"; + return 1; +} \ No newline at end of file diff --git a/test/error_code_test.cpp b/test/error_code_test.cpp index 69f6c3c..a9a928e 100644 --- a/test/error_code_test.cpp +++ b/test/error_code_test.cpp @@ -7,7 +7,10 @@ // See library home page at http://www.boost.org/libs/system -//----------------------------------------------------------------------------// +//----------------------------------------------------------------------------// + +// test without deprecated features +#define BOOST_SYSTEM_NO_DEPRECATED #include @@ -56,55 +59,61 @@ namespace int main( int, char ** ) { + std::cout << "Conversion use cases...\n"; + error_condition x1( errc::file_exists ); + //error_code x2( errc::file_exists ); // should fail to compile + make_error_code(errc::file_exists); + make_error_condition(errc::file_exists); + std::cout << "General tests...\n"; // unit tests: - BOOST_TEST( posix_category == posix_category ); - BOOST_TEST( system_category == system_category ); - BOOST_TEST( posix_category != system_category ); - BOOST_TEST( system_category != posix_category ); + BOOST_TEST( generic_category() == generic_category() ); + BOOST_TEST( system_category() == system_category() ); + BOOST_TEST( generic_category() != system_category() ); + BOOST_TEST( system_category() != generic_category() ); - if ( std::less()( &posix_category, &system_category ) ) + if ( std::less()( &generic_category(), &system_category() ) ) { - BOOST_TEST( posix_category < system_category ); - BOOST_TEST( !(system_category < posix_category) ); + BOOST_TEST( generic_category() < system_category() ); + BOOST_TEST( !(system_category() < generic_category()) ); } else { - BOOST_TEST( system_category < posix_category ); - BOOST_TEST( !(posix_category < system_category) ); + BOOST_TEST( system_category() < generic_category() ); + BOOST_TEST( !(generic_category() < system_category()) ); } error_code ec; - error_condition dec; + error_condition econd; BOOST_TEST( !ec ); BOOST_TEST( ec.value() == 0 ); - dec = ec.default_error_condition(); - BOOST_TEST( dec.value() == 0 ); - BOOST_TEST( dec.category() == posix_category ); - BOOST_TEST( ec == posix::success ); - BOOST_TEST( ec.category() == system_category ); + econd = ec.default_error_condition(); + BOOST_TEST( econd.value() == 0 ); + BOOST_TEST( econd.category() == generic_category() ); + BOOST_TEST( ec == errc::success ); + BOOST_TEST( ec.category() == system_category() ); BOOST_TEST( std::strcmp( ec.category().name(), "system") == 0 ); - BOOST_TEST( !(ec < error_code( 0, system_category )) ); - BOOST_TEST( !(error_code( 0, system_category ) < ec) ); - BOOST_TEST( ec < error_code( 1, system_category ) ); - BOOST_TEST( !(error_code( 1, system_category ) < ec) ); + BOOST_TEST( !(ec < error_code( 0, system_category() )) ); + BOOST_TEST( !(error_code( 0, system_category() ) < ec) ); + BOOST_TEST( ec < error_code( 1, system_category() ) ); + BOOST_TEST( !(error_code( 1, system_category() ) < ec) ); - error_code ec_0_system( 0, system_category ); + error_code ec_0_system( 0, system_category() ); BOOST_TEST( !ec_0_system ); BOOST_TEST( ec_0_system.value() == 0 ); - dec = ec_0_system.default_error_condition(); - BOOST_TEST( dec.value() == 0 ); - BOOST_TEST( dec.category() == posix_category ); - BOOST_TEST( ec_0_system == posix::success ); - BOOST_TEST( ec_0_system.category() == system_category ); + econd = ec_0_system.default_error_condition(); + BOOST_TEST( econd.value() == 0 ); + BOOST_TEST( econd.category() == generic_category() ); + BOOST_TEST( ec_0_system == errc::success ); + BOOST_TEST( ec_0_system.category() == system_category() ); BOOST_TEST( std::strcmp( ec_0_system.category().name(), "system") == 0 ); check_ostream( ec_0_system, "system:0" ); BOOST_TEST( ec_0_system == ec ); - error_code ec_1_system( 1, system_category ); + error_code ec_1_system( 1, system_category() ); BOOST_TEST( ec_1_system ); BOOST_TEST( ec_1_system.value() == 1 ); BOOST_TEST( ec_1_system.value() != 0 ); @@ -112,41 +121,43 @@ int main( int, char ** ) BOOST_TEST( ec_0_system != ec_1_system ); check_ostream( ec_1_system, "system:1" ); - ec = error_code( BOOST_ACCESS_ERROR_MACRO, system_category ); + ec = error_code( BOOST_ACCESS_ERROR_MACRO, system_category() ); BOOST_TEST( ec ); BOOST_TEST( ec.value() == BOOST_ACCESS_ERROR_MACRO ); - dec = ec.default_error_condition(); - BOOST_TEST( dec.value() == static_cast(posix::permission_denied) ); - BOOST_TEST( dec.category() == posix_category ); - BOOST_TEST( dec == error_condition( posix::permission_denied, posix_category ) ); - BOOST_TEST( dec == posix::permission_denied ); - BOOST_TEST( posix::permission_denied == dec ); - BOOST_TEST( ec == posix::permission_denied ); - BOOST_TEST( ec.category() == system_category ); + econd = ec.default_error_condition(); + BOOST_TEST( econd.value() == static_cast(errc::permission_denied) ); + BOOST_TEST( econd.category() == generic_category() ); + BOOST_TEST( econd == error_condition( errc::permission_denied, generic_category() ) ); + BOOST_TEST( econd == errc::permission_denied ); + BOOST_TEST( errc::permission_denied == econd ); + BOOST_TEST( ec == errc::permission_denied ); + BOOST_TEST( ec.category() == system_category() ); BOOST_TEST( std::strcmp( ec.category().name(), "system") == 0 ); - // test the explicit make_error_code conversion for posix - ec = make_error_code( posix::bad_message ); + // test the explicit make_error_code conversion for errc + ec = make_error_code( errc::bad_message ); BOOST_TEST( ec ); - BOOST_TEST( ec == posix::bad_message ); - BOOST_TEST( posix::bad_message == ec ); - BOOST_TEST( ec != posix::permission_denied ); - BOOST_TEST( posix::permission_denied != ec ); - BOOST_TEST( ec.category() == posix_category ); + BOOST_TEST( ec == errc::bad_message ); + BOOST_TEST( errc::bad_message == ec ); + BOOST_TEST( ec != errc::permission_denied ); + BOOST_TEST( errc::permission_denied != ec ); + BOOST_TEST( ec.category() == generic_category() ); - // test the deprecated predefined error_category synonyms - BOOST_TEST( &system_category == &native_ecat ); - BOOST_TEST( &posix_category == &errno_ecat ); - BOOST_TEST( system_category == native_ecat ); - BOOST_TEST( posix_category == errno_ecat ); + //// test the deprecated predefined error_category synonyms + //BOOST_TEST( &system_category() == &native_ecat ); + //BOOST_TEST( &generic_category() == &errno_ecat ); + //BOOST_TEST( system_category() == native_ecat ); + //BOOST_TEST( generic_category() == errno_ecat ); // test error_code and error_condition message(); // see Boost.Filesystem operations_test for code specific message() tests - ec = error_code( -1, system_category ); + ec = error_code( -1, system_category() ); std::cout << "error_code message for -1 is \"" << ec.message() << "\"\n"; + std::cout << "error_code message for 0 is \"" << ec_0_system.message() << "\"\n"; #if defined(BOOST_WINDOWS_API) // Borland appends newline, so just check text BOOST_TEST( ec.message().substr(0,13) == "Unknown error" ); + BOOST_TEST( ec_0_system.message().substr(0,36) == "The operation completed successfully" ); #elif defined(linux) || defined(__linux) || defined(__linux__) // Linux appends value to message as unsigned, so it varies with # of bits BOOST_TEST( ec.message().substr(0,13) == "Unknown error" ); @@ -158,102 +169,105 @@ int main( int, char ** ) BOOST_TEST( ec.message() == "error -1" ); #endif - ec = error_code( BOOST_ACCESS_ERROR_MACRO, system_category ); + ec = error_code( BOOST_ACCESS_ERROR_MACRO, system_category() ); BOOST_TEST( ec.message() != "" ); BOOST_TEST( ec.message().substr( 0, 13) != "Unknown error" ); - dec = error_condition( -1, posix_category ); - std::cout << "error_condition message for -1 is \"" << dec.message() << "\"\n"; + econd = error_condition( -1, generic_category() ); + error_condition econd_ok; + std::cout << "error_condition message for -1 is \"" << econd.message() << "\"\n"; + std::cout << "error_condition message for 0 is \"" << econd_ok.message() << "\"\n"; #if defined(BOOST_WINDOWS_API) // Borland appends newline, so just check text - BOOST_TEST( dec.message().substr(0,13) == "Unknown error" ); + BOOST_TEST( econd.message().substr(0,13) == "Unknown error" ); + BOOST_TEST( econd_ok.message().substr(0,8) == "No error" ); #elif defined(linux) || defined(__linux) || defined(__linux__) // Linux appends value to message as unsigned, so it varies with # of bits - BOOST_TEST( dec.message().substr(0,13) == "Unknown error" ); + BOOST_TEST( econd.message().substr(0,13) == "Unknown error" ); #elif defined(__hpux) - BOOST_TEST( dec.message() == "" ); + BOOST_TEST( econd.message() == "" ); #elif defined(__osf__) - BOOST_TEST( dec.message() == "Error -1 occurred." ); + BOOST_TEST( econd.message() == "Error -1 occurred." ); #elif defined(__vms) - BOOST_TEST( dec.message() == "error -1" ); + BOOST_TEST( econd.message() == "error -1" ); #endif - dec = error_condition( BOOST_ACCESS_ERROR_MACRO, posix_category ); - BOOST_TEST( dec.message() != "" ); - BOOST_TEST( dec.message().substr( 0, 13) != "Unknown error" ); + econd = error_condition( BOOST_ACCESS_ERROR_MACRO, generic_category() ); + BOOST_TEST( econd.message() != "" ); + BOOST_TEST( econd.message().substr( 0, 13) != "Unknown error" ); #ifdef BOOST_WINDOWS_API std::cout << "Windows tests...\n"; - // these tests probe the Windows posix decoder + // these tests probe the Windows errc decoder // test the first entry in the decoder table: - ec = error_code( ERROR_ACCESS_DENIED, system_category ); + ec = error_code( ERROR_ACCESS_DENIED, system_category() ); BOOST_TEST( ec.value() == ERROR_ACCESS_DENIED ); - BOOST_TEST( ec == posix::permission_denied ); - BOOST_TEST( ec.default_error_condition().value() == posix::permission_denied ); - BOOST_TEST( ec.default_error_condition().category() == posix_category ); + BOOST_TEST( ec == errc::permission_denied ); + BOOST_TEST( ec.default_error_condition().value() == errc::permission_denied ); + BOOST_TEST( ec.default_error_condition().category() == generic_category() ); // test the second entry in the decoder table: - ec = error_code( ERROR_ALREADY_EXISTS, system_category ); + ec = error_code( ERROR_ALREADY_EXISTS, system_category() ); BOOST_TEST( ec.value() == ERROR_ALREADY_EXISTS ); - BOOST_TEST( ec == posix::file_exists ); - BOOST_TEST( ec.default_error_condition().value() == posix::file_exists ); - BOOST_TEST( ec.default_error_condition().category() == posix_category ); + BOOST_TEST( ec == errc::file_exists ); + BOOST_TEST( ec.default_error_condition().value() == errc::file_exists ); + BOOST_TEST( ec.default_error_condition().category() == generic_category() ); // test the third entry in the decoder table: - ec = error_code( ERROR_BAD_UNIT, system_category ); + ec = error_code( ERROR_BAD_UNIT, system_category() ); BOOST_TEST( ec.value() == ERROR_BAD_UNIT ); - BOOST_TEST( ec == posix::no_such_device ); - BOOST_TEST( ec.default_error_condition().value() == posix::no_such_device ); - BOOST_TEST( ec.default_error_condition().category() == posix_category ); + BOOST_TEST( ec == errc::no_such_device ); + BOOST_TEST( ec.default_error_condition().value() == errc::no_such_device ); + BOOST_TEST( ec.default_error_condition().category() == generic_category() ); // test the last non-Winsock entry in the decoder table: - ec = error_code( ERROR_WRITE_PROTECT, system_category ); + ec = error_code( ERROR_WRITE_PROTECT, system_category() ); BOOST_TEST( ec.value() == ERROR_WRITE_PROTECT ); - BOOST_TEST( ec == posix::permission_denied ); - BOOST_TEST( ec.default_error_condition().value() == posix::permission_denied ); - BOOST_TEST( ec.default_error_condition().category() == posix_category ); + BOOST_TEST( ec == errc::permission_denied ); + BOOST_TEST( ec.default_error_condition().value() == errc::permission_denied ); + BOOST_TEST( ec.default_error_condition().category() == generic_category() ); // test the last Winsock entry in the decoder table: - ec = error_code( WSAEWOULDBLOCK, system_category ); + ec = error_code( WSAEWOULDBLOCK, system_category() ); BOOST_TEST( ec.value() == WSAEWOULDBLOCK ); - BOOST_TEST( ec == posix::operation_would_block ); - BOOST_TEST( ec.default_error_condition().value() == posix::operation_would_block ); - BOOST_TEST( ec.default_error_condition().category() == posix_category ); + BOOST_TEST( ec == errc::operation_would_block ); + BOOST_TEST( ec.default_error_condition().value() == errc::operation_would_block ); + BOOST_TEST( ec.default_error_condition().category() == generic_category() ); // test not-in-table condition: - ec = error_code( 1234567890, system_category ); + ec = error_code( 1234567890, system_category() ); BOOST_TEST( ec.value() == 1234567890 ); BOOST_TEST( ec.default_error_condition().value() == 1234567890 ); - BOOST_TEST( ec.default_error_condition().category() == system_category ); + BOOST_TEST( ec.default_error_condition().category() == system_category() ); #else // POSIX std::cout << "POSIX tests...\n"; - ec = error_code( EACCES, system_category ); - BOOST_TEST( ec == error_code( posix::permission_denied, system_category ) ); - BOOST_TEST( error_code( posix::permission_denied, system_category ) == ec ); - BOOST_TEST( ec == posix::permission_denied ); - BOOST_TEST( posix::permission_denied == ec ); - BOOST_TEST( ec.default_error_condition().value() == posix::permission_denied ); - BOOST_TEST( ec.default_error_condition().category() == posix_category ); + ec = error_code( EACCES, system_category() ); + BOOST_TEST( ec == error_code( errc::permission_denied, system_category() ) ); + BOOST_TEST( error_code( errc::permission_denied, system_category() ) == ec ); + BOOST_TEST( ec == errc::permission_denied ); + BOOST_TEST( errc::permission_denied == ec ); + BOOST_TEST( ec.default_error_condition().value() == errc::permission_denied ); + BOOST_TEST( ec.default_error_condition().category() == generic_category() ); # ifdef __CYGWIN__ std::cout << "Cygwin tests...\n"; ec = cygwin_error::no_package; BOOST_TEST( ec == cygwin_error::no_package ); - BOOST_TEST( ec == error_code( ENOPKG, system_category ) ); - BOOST_TEST( ec == error_code( cygwin_error::no_package, system_category ) ); - BOOST_TEST( ec.default_error_condition().category() == system_category ); + BOOST_TEST( ec == error_code( ENOPKG, system_category() ) ); + BOOST_TEST( ec == error_code( cygwin_error::no_package, system_category() ) ); + BOOST_TEST( ec.default_error_condition().category() == system_category() ); # elif defined(linux) || defined(__linux) || defined(__linux__) std::cout << "Linux tests...\n"; ec = linux_error::dot_dot_error; BOOST_TEST( ec == linux_error::dot_dot_error ); - BOOST_TEST( ec == error_code( EDOTDOT, system_category ) ); - BOOST_TEST( ec == error_code( linux_error::dot_dot_error, system_category ) ); - BOOST_TEST( ec.default_error_condition().category() == system_category ); + BOOST_TEST( ec == error_code( EDOTDOT, system_category() ) ); + BOOST_TEST( ec == error_code( linux_error::dot_dot_error, system_category() ) ); + BOOST_TEST( ec.default_error_condition().category() == system_category() ); # endif diff --git a/test/error_code_user_test.cpp b/test/error_code_user_test.cpp index be9adaa..4f4eb30 100644 --- a/test/error_code_user_test.cpp +++ b/test/error_code_user_test.cpp @@ -14,11 +14,13 @@ // Motivation was a Boost posting by Christopher Kohlhoff on June 28, 2006. +#define BOOST_SYSTEM_NO_DEPRECATED + #include #include #include #include -#include +#include #ifdef BOOST_POSIX_API # include @@ -40,7 +42,7 @@ boost::system::error_code my_mkdir( const std::string & path ) # else ::CreateDirectoryA( path.c_str(), 0 ) != 0 ? 0 : ::GetLastError(), # endif - boost::system::system_category ); + boost::system::system_category() ); } // ------------------------------------------------------------------------ // @@ -53,9 +55,9 @@ boost::system::error_code my_remove( const std::string & path ) { return boost::system::error_code( std::remove( path.c_str() ) == 0 ? 0 : errno, - boost::system::posix_category ); // OK for both Windows and POSIX - // Alternatively, could use posix_category - // on Windows and system_category on + boost::system::generic_category() ); // OK for both Windows and POSIX + // Alternatively, could use generic_category() + // on Windows and system_category() on // POSIX-based systems. } @@ -118,8 +120,8 @@ namespace boost boost::system::error_condition default_error_condition( int ev ) const { return ev == boo_boo - ? boost::system::error_condition( boost::system::posix::io_error, - boost::system::posix_category ) + ? boost::system::error_condition( boost::system::errc::io_error, + boost::system::generic_category() ) : boost::system::error_condition( ev, boost::lib3::lib3_error_category ); } @@ -180,8 +182,8 @@ namespace lib4 boost::system::error_condition default_error_condition( int ev ) const { return ev == boo_boo.value() - ? boost::system::error_condition( boost::system::posix::io_error, - boost::system::posix_category ) + ? boost::system::error_condition( boost::system::errc::io_error, + boost::system::generic_category() ) : boost::system::error_condition( ev, lib4::lib4_error_category ); } @@ -237,15 +239,15 @@ namespace lib4 // switch (ev) // { // case user_success: -// return boost::system::error_code(boost::system::posix::success, boost::system::posix_category); +// return boost::system::error_code(boost::system::errc::success, boost::system::generic_category()); // case user_permission_denied: -// return boost::system::error_code(boost::system::posix::permission_denied, boost::system::posix_category); +// return boost::system::error_code(boost::system::errc::permission_denied, boost::system::generic_category()); // case user_out_of_memory: -// return boost::system::error_code(boost::system::posix::not_enough_memory, boost::system::posix_category); +// return boost::system::error_code(boost::system::errc::not_enough_memory, boost::system::generic_category()); // default: // break; // } -// return boost::system::error_code(boost::system::posix::no_posix_equivalent, boost::system::posix_category); +// return boost::system::error_code(boost::system::errc::no_posix_equivalent, boost::system::generic_category()); // } // // }; @@ -264,8 +266,8 @@ namespace lib4 // // void check_success(const boost::system::error_code& ec, bool expect) // { -// BOOST_CHECK( (ec == boost::system::posix::success) == expect ); -// if (ec == boost::system::posix::success) +// BOOST_TEST( (ec == boost::system::errc::success) == expect ); +// if (ec == boost::system::errc::success) // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n'; // else // std::cout << "no... " << (expect ? "fail" : "ok") << '\n'; @@ -273,8 +275,8 @@ namespace lib4 // // void check_permission_denied(const boost::system::error_code& ec, bool expect) // { -// BOOST_CHECK( (ec == boost::system::posix::permission_denied) == expect ); -// if (ec == boost::system::posix::permission_denied) +// BOOST_TEST( (ec == boost::system::errc::permission_denied) == expect ); +// if (ec == boost::system::errc::permission_denied) // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n'; // else // std::cout << "no... " << (expect ? "fail" : "ok") << '\n'; @@ -282,8 +284,8 @@ namespace lib4 // // void check_out_of_memory(const boost::system::error_code& ec, bool expect) // { -// BOOST_CHECK( (ec == boost::system::posix::not_enough_memory) == expect ); -// if (ec == boost::system::posix::not_enough_memory) +// BOOST_TEST( (ec == boost::system::errc::not_enough_memory) == expect ); +// if (ec == boost::system::errc::not_enough_memory) // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n'; // else // std::cout << "no... " << (expect ? "fail" : "ok") << '\n'; @@ -295,23 +297,23 @@ namespace lib4 // printf("=====\n"); // boost::system::error_code ec; // check_success(ec, true); -// check_success(boost::system::posix::success, true); -// check_success(boost::system::posix::permission_denied, false); -// check_success(boost::system::posix::not_enough_memory, false); +// check_success(boost::system::errc::success, true); +// check_success(boost::system::errc::permission_denied, false); +// check_success(boost::system::errc::not_enough_memory, false); // check_success(user_success, true); // check_success(user_permission_denied, false); // check_success(user_out_of_memory, false); // check_permission_denied(ec, false); -// check_permission_denied(boost::system::posix::success, false); -// check_permission_denied(boost::system::posix::permission_denied, true); -// check_permission_denied(boost::system::posix::not_enough_memory, false); +// check_permission_denied(boost::system::errc::success, false); +// check_permission_denied(boost::system::errc::permission_denied, true); +// check_permission_denied(boost::system::errc::not_enough_memory, false); // check_permission_denied(user_success, false); // check_permission_denied(user_permission_denied, true); // check_permission_denied(user_out_of_memory, false); // check_out_of_memory(ec, false); -// check_out_of_memory(boost::system::posix::success, false); -// check_out_of_memory(boost::system::posix::permission_denied, false); -// check_out_of_memory(boost::system::posix::not_enough_memory, true); +// check_out_of_memory(boost::system::errc::success, false); +// check_out_of_memory(boost::system::errc::permission_denied, false); +// check_out_of_memory(boost::system::errc::not_enough_memory, true); // check_out_of_memory(user_success, false); // check_out_of_memory(user_permission_denied, false); // check_out_of_memory(user_out_of_memory, true); @@ -337,7 +339,7 @@ namespace lib4 // ------------------------------------------------------------------------ // -int test_main( int, char *[] ) +int main( int, char *[] ) { boost::system::error_code ec; @@ -346,35 +348,35 @@ int test_main( int, char *[] ) ec = my_mkdir( "/no-such-file-or-directory/will-not-succeed" ); std::cout << "ec.value() is " << ec.value() << '\n'; - BOOST_CHECK( ec ); - BOOST_CHECK( ec == boost::system::posix::no_such_file_or_directory ); - BOOST_CHECK( ec.category() == boost::system::system_category ); + BOOST_TEST( ec ); + BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory ); + BOOST_TEST( ec.category() == boost::system::system_category() ); // Library 2 tests: ec = my_remove( "/no-such-file-or-directory" ); std::cout << "ec.value() is " << ec.value() << '\n'; - BOOST_CHECK( ec ); - BOOST_CHECK( ec == boost::system::posix::no_such_file_or_directory ); - BOOST_CHECK( ec.category() == boost::system::posix_category ); + BOOST_TEST( ec ); + BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory ); + BOOST_TEST( ec.category() == boost::system::generic_category() ); // Library 3 tests: ec = boost::lib3::boo_boo; std::cout << "ec.value() is " << ec.value() << '\n'; - BOOST_CHECK( ec ); - BOOST_CHECK( ec == boost::lib3::boo_boo ); - BOOST_CHECK( ec.value() == boost::lib3::boo_boo ); - BOOST_CHECK( ec.category() == boost::lib3::lib3_error_category ); + BOOST_TEST( ec ); + BOOST_TEST( ec == boost::lib3::boo_boo ); + BOOST_TEST( ec.value() == boost::lib3::boo_boo ); + BOOST_TEST( ec.category() == boost::lib3::lib3_error_category ); - BOOST_CHECK( ec == boost::system::posix::io_error ); + BOOST_TEST( ec == boost::system::errc::io_error ); boost::system::error_code ec3( boost::lib3::boo_boo+100, boost::lib3::lib3_error_category ); - BOOST_CHECK( ec3.category() == boost::lib3::lib3_error_category ); - BOOST_CHECK( ec3.default_error_condition().category() + BOOST_TEST( ec3.category() == boost::lib3::lib3_error_category ); + BOOST_TEST( ec3.default_error_condition().category() == boost::lib3::lib3_error_category ); // Library 4 tests: @@ -382,21 +384,21 @@ int test_main( int, char *[] ) ec = lib4::boo_boo; std::cout << "ec.value() is " << ec.value() << '\n'; - BOOST_CHECK( ec ); - BOOST_CHECK( ec == lib4::boo_boo ); - BOOST_CHECK( ec.value() == lib4::boo_boo.value() ); - BOOST_CHECK( ec.category() == lib4::lib4_error_category ); + BOOST_TEST( ec ); + BOOST_TEST( ec == lib4::boo_boo ); + BOOST_TEST( ec.value() == lib4::boo_boo.value() ); + BOOST_TEST( ec.category() == lib4::lib4_error_category ); - BOOST_CHECK( ec == boost::system::posix::io_error ); + BOOST_TEST( ec == boost::system::errc::io_error ); boost::system::error_code ec4( lib4::boo_boo.value()+100, lib4::lib4_error_category ); - BOOST_CHECK( ec4.default_error_condition().category() + BOOST_TEST( ec4.default_error_condition().category() == lib4::lib4_error_category ); // Test 3 //test3::run(); - return 0; + return ::boost::report_errors(); } diff --git a/test/header_only_test.cpp b/test/header_only_test.cpp index 20d6179..6f0943d 100644 --- a/test/header_only_test.cpp +++ b/test/header_only_test.cpp @@ -13,12 +13,11 @@ #define BOOST_ERROR_CODE_HEADER_ONLY -#include - +#include #include -int test_main( int, char*[] ) +int main( int, char*[] ) { - boost::system::error_code ec( 0, boost::system::system_category ); - return 0; + boost::system::error_code ec( 0, boost::system::system_category() ); + return ::boost::report_errors(); } diff --git a/test/initialization_test.cpp b/test/initialization_test.cpp index 7ccd594..8c7c988 100644 --- a/test/initialization_test.cpp +++ b/test/initialization_test.cpp @@ -10,7 +10,7 @@ // This test verifiies that the error_category vtable does not suffer from // order-of-initialization problems. -#include +#include #include struct foo @@ -22,7 +22,7 @@ struct foo } } f; -int test_main( int, char ** ) +int main( int, char ** ) { - return 0; + return ::boost::report_errors(); } diff --git a/test/system_error_test.cpp b/test/system_error_test.cpp index 269fb5d..9f7c996 100644 --- a/test/system_error_test.cpp +++ b/test/system_error_test.cpp @@ -9,9 +9,12 @@ //----------------------------------------------------------------------------// +// test without deprecated features +#define BOOST_SYSTEM_NO_DEPRECATED + #include -#include +#include #include #include #include @@ -33,8 +36,8 @@ namespace int v, const char * str ) { std::cout << "test " << desc << "\n what() returns \"" << ex.what() << "\"\n"; - BOOST_CHECK( ex.code().value() == v ); - BOOST_CHECK( ex.code().category() == system_category ); + BOOST_TEST( ex.code().value() == v ); + BOOST_TEST( ex.code().category() == system_category() ); # ifdef BOOST_WINDOWS_API LANGID language_id; # if !defined(__MINGW32__) && !defined(__CYGWIN__) @@ -45,7 +48,7 @@ namespace // std::cout << "GetUserDefaultUILanguage() returns " << language_id << '\n'; if ( language_id == 0x0409 ) // English (United States) { - BOOST_CHECK( std::string( ex.what() ) == str ); + BOOST_TEST( std::string( ex.what() ) == str ); if ( std::string( ex.what() ) != str ) std::cout << "expected \"" << str << "\", but what() returned \"" << ex.what() << "\"\n"; @@ -56,51 +59,51 @@ namespace const boost::uint_least32_t uvalue = 2u; } -int test_main( int, char *[] ) +int main( int, char *[] ) { // all constructors, in the same order as they appear in the header: - system_error c1_0( error_code(0, system_category) ); - system_error c1_1( error_code(1, system_category) ); - system_error c1_2u( error_code(uvalue, system_category) ); + system_error c1_0( error_code(0, system_category()) ); + system_error c1_1( error_code(1, system_category()) ); + system_error c1_2u( error_code(uvalue, system_category()) ); - system_error c2_0( error_code(0, system_category), string("c2_0") ); - system_error c2_1( error_code(1, system_category), string("c2_1") ); + system_error c2_0( error_code(0, system_category()), string("c2_0") ); + system_error c2_1( error_code(1, system_category()), string("c2_1") ); - system_error c3_0( error_code(0, system_category), "c3_0" ); - system_error c3_1( error_code(1, system_category), "c3_1" ); + system_error c3_0( error_code(0, system_category()), "c3_0" ); + system_error c3_1( error_code(1, system_category()), "c3_1" ); - system_error c4_0( 0, system_category ); - system_error c4_1( 1, system_category ); - system_error c4_2u( uvalue, system_category ); + system_error c4_0( 0, system_category() ); + system_error c4_1( 1, system_category() ); + system_error c4_2u( uvalue, system_category() ); - system_error c5_0( 0, system_category, string("c5_0") ); - system_error c5_1( 1, system_category, string("c5_1") ); + system_error c5_0( 0, system_category(), string("c5_0") ); + system_error c5_1( 1, system_category(), string("c5_1") ); - system_error c6_0( 0, system_category, "c6_0" ); - system_error c6_1( 1, system_category, "c6_1" ); + system_error c6_0( 0, system_category(), "c6_0" ); + system_error c6_1( 1, system_category(), "c6_1" ); - TEST( c1_0, 0, "" ); + TEST( c1_0, 0, "The operation completed successfully" ); TEST( c1_1, 1, "Incorrect function" ); TEST( c1_2u, 2, "The system cannot find the file specified" ); - TEST( c2_0, 0, "c2_0" ); + TEST( c2_0, 0, "c2_0: The operation completed successfully" ); TEST( c2_1, 1, "c2_1: Incorrect function" ); - TEST( c3_0, 0, "c3_0" ); + TEST( c3_0, 0, "c3_0: The operation completed successfully" ); TEST( c3_1, 1, "c3_1: Incorrect function" ); - TEST( c4_0, 0, "" ); + TEST( c4_0, 0, "The operation completed successfully" ); TEST( c4_1, 1, "Incorrect function" ); TEST( c4_2u, 2, "The system cannot find the file specified" ); - TEST( c5_0, 0, "c5_0" ); + TEST( c5_0, 0, "c5_0: The operation completed successfully" ); TEST( c5_1, 1, "c5_1: Incorrect function" ); - TEST( c6_0, 0, "c6_0" ); + TEST( c6_0, 0, "c6_0: The operation completed successfully" ); TEST( c6_1, 1, "c6_1: Incorrect function" ); - return 0; + return ::boost::report_errors(); } diff --git a/test/system_msvc/common.vsprops b/test/system_msvc/common.vsprops index 9a558f8..e4cc705 100644 --- a/test/system_msvc/common.vsprops +++ b/test/system_msvc/common.vsprops @@ -7,12 +7,13 @@ diff --git a/test/system_msvc/error_code_test/error_code_test.vcproj b/test/system_msvc/error_code_test/error_code_test.vcproj index 5857539..f69ff01 100644 --- a/test/system_msvc/error_code_test/error_code_test.vcproj +++ b/test/system_msvc/error_code_test/error_code_test.vcproj @@ -47,7 +47,7 @@ BasicRuntimeChecks="3" RuntimeLibrary="3" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" DebugInformationFormat="4" /> @@ -172,10 +176,6 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > - - diff --git a/test/system_msvc/system_msvc.sln b/test/system_msvc/system_msvc.sln index 71b8a8e..d3d2746 100644 --- a/test/system_msvc/system_msvc.sln +++ b/test/system_msvc/system_msvc.sln @@ -2,6 +2,27 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "error_code_test", "error_code_test\error_code_test.vcproj", "{81960557-E9A9-4E81-AC96-9E11C33CB058}" + ProjectSection(ProjectDependencies) = postProject + {22892211-A1F3-435B-8B97-A12E8772599E} = {22892211-A1F3-435B-8B97-A12E8772599E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "system_error_test", "system_error_test\system_error_test.vcproj", "{CBD12E59-99E5-4F35-9B66-0554D0FBDB76}" + ProjectSection(ProjectDependencies) = postProject + {22892211-A1F3-435B-8B97-A12E8772599E} = {22892211-A1F3-435B-8B97-A12E8772599E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamic_link_test", "dynamic_link_test\dynamic_link_test.vcproj", "{AD186B11-9132-48A9-9F24-3522C2310B0D}" + ProjectSection(ProjectDependencies) = postProject + {F6D9B408-84A3-405A-93ED-DE5AA8CF84D7} = {F6D9B408-84A3-405A-93ED-DE5AA8CF84D7} + {22892211-A1F3-435B-8B97-A12E8772599E} = {22892211-A1F3-435B-8B97-A12E8772599E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "system_dll", "system_dll\system_dll.vcproj", "{22892211-A1F3-435B-8B97-A12E8772599E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "throw_test_dll", "throw_test_dll\throw_test_dll.vcproj", "{F6D9B408-84A3-405A-93ED-DE5AA8CF84D7}" + ProjectSection(ProjectDependencies) = postProject + {22892211-A1F3-435B-8B97-A12E8772599E} = {22892211-A1F3-435B-8B97-A12E8772599E} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -13,6 +34,22 @@ Global {81960557-E9A9-4E81-AC96-9E11C33CB058}.Debug|Win32.Build.0 = Debug|Win32 {81960557-E9A9-4E81-AC96-9E11C33CB058}.Release|Win32.ActiveCfg = Release|Win32 {81960557-E9A9-4E81-AC96-9E11C33CB058}.Release|Win32.Build.0 = Release|Win32 + {CBD12E59-99E5-4F35-9B66-0554D0FBDB76}.Debug|Win32.ActiveCfg = Debug|Win32 + {CBD12E59-99E5-4F35-9B66-0554D0FBDB76}.Debug|Win32.Build.0 = Debug|Win32 + {CBD12E59-99E5-4F35-9B66-0554D0FBDB76}.Release|Win32.ActiveCfg = Release|Win32 + {CBD12E59-99E5-4F35-9B66-0554D0FBDB76}.Release|Win32.Build.0 = Release|Win32 + {AD186B11-9132-48A9-9F24-3522C2310B0D}.Debug|Win32.ActiveCfg = Debug|Win32 + {AD186B11-9132-48A9-9F24-3522C2310B0D}.Debug|Win32.Build.0 = Debug|Win32 + {AD186B11-9132-48A9-9F24-3522C2310B0D}.Release|Win32.ActiveCfg = Release|Win32 + {AD186B11-9132-48A9-9F24-3522C2310B0D}.Release|Win32.Build.0 = Release|Win32 + {22892211-A1F3-435B-8B97-A12E8772599E}.Debug|Win32.ActiveCfg = Debug|Win32 + {22892211-A1F3-435B-8B97-A12E8772599E}.Debug|Win32.Build.0 = Debug|Win32 + {22892211-A1F3-435B-8B97-A12E8772599E}.Release|Win32.ActiveCfg = Release|Win32 + {22892211-A1F3-435B-8B97-A12E8772599E}.Release|Win32.Build.0 = Release|Win32 + {F6D9B408-84A3-405A-93ED-DE5AA8CF84D7}.Debug|Win32.ActiveCfg = Debug|Win32 + {F6D9B408-84A3-405A-93ED-DE5AA8CF84D7}.Debug|Win32.Build.0 = Debug|Win32 + {F6D9B408-84A3-405A-93ED-DE5AA8CF84D7}.Release|Win32.ActiveCfg = Release|Win32 + {F6D9B408-84A3-405A-93ED-DE5AA8CF84D7}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/test/throw_test.cpp b/test/throw_test.cpp new file mode 100644 index 0000000..c42f422 --- /dev/null +++ b/test/throw_test.cpp @@ -0,0 +1,31 @@ +// throw_test.cpp --------------------------------------------------------===========-// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See www.boost.org/LICENSE_1_0.txt + +// Library home page is www.boost.org/libs/system + +//--------------------------------------------------------------------------------------// + +// See dynamic_link_test.cpp comments for use case. + +//--------------------------------------------------------------------------------------// + +// define BOOST_SYSTEM_SOURCE so that knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_SYSTEM_SOURCE + +#include + +namespace boost +{ + namespace system + { + BOOST_SYSTEM_DECL void throw_test() + { + throw system_error(9999, system_category(), "boo boo"); + } + } +}