From cd98f4edd784ac5e2eeb98bbcf9d98d7d5a00330 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 15 Sep 2021 07:42:57 +0300 Subject: [PATCH] Update system_error to incorporate the source location in what() --- include/boost/system/detail/error_code.hpp | 2 +- include/boost/system/system_error.hpp | 156 ++++++++++++--------- 2 files changed, 91 insertions(+), 67 deletions(-) diff --git a/include/boost/system/detail/error_code.hpp b/include/boost/system/detail/error_code.hpp index e46ffe4..45833eb 100644 --- a/include/boost/system/detail/error_code.hpp +++ b/include/boost/system/detail/error_code.hpp @@ -3,7 +3,7 @@ // Copyright Beman Dawes 2006, 2007 // Copyright Christoper Kohlhoff 2007 -// Copyright Peter Dimov 2017, 2018 +// Copyright Peter Dimov 2017-2021 // // 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) diff --git a/include/boost/system/system_error.hpp b/include/boost/system/system_error.hpp index ef19e97..f3f1701 100644 --- a/include/boost/system/system_error.hpp +++ b/include/boost/system/system_error.hpp @@ -1,84 +1,108 @@ -// Boost system_error.hpp --------------------------------------------------// - -// Copyright Beman Dawes 2006 - -// 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) - #ifndef BOOST_SYSTEM_SYSTEM_ERROR_HPP #define BOOST_SYSTEM_SYSTEM_ERROR_HPP +// Copyright Beman Dawes 2006 +// Copyright Peter Dimov 2021 +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + #include +#include #include #include #include namespace boost { - namespace system - { - // class system_error ------------------------------------------------------------// +namespace system +{ - 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 +class BOOST_SYMBOL_VISIBLE system_error: public std::runtime_error +{ +private: + + error_code code_; + +private: + + static std::string to_string( int v ) { - public: - explicit system_error( error_code ec ) - : std::runtime_error(""), m_error_code(ec) {} + char buffer[ 32 ]; + detail::snprintf( buffer, sizeof( buffer ), "%d", v ); - system_error( error_code ec, const std::string & what_arg ) - : std::runtime_error(what_arg), m_error_code(ec) {} - - system_error( error_code ec, const char* what_arg ) - : std::runtime_error(what_arg), m_error_code(ec) {} - - system_error( int ev, const error_category & ecat ) - : std::runtime_error(""), m_error_code(ev,ecat) {} - - system_error( int ev, const error_category & ecat, - const std::string & what_arg ) - : std::runtime_error(what_arg), m_error_code(ev,ecat) {} - - system_error( int ev, const error_category & ecat, - const char * what_arg ) - : std::runtime_error(what_arg), m_error_code(ev,ecat) {} - - virtual ~system_error() BOOST_NOEXCEPT_OR_NOTHROW {} - - error_code code() const BOOST_NOEXCEPT { return m_error_code; } - const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE; - - private: - error_code m_error_code; - mutable std::string m_what; - }; - - // implementation ------------------------------------------------------// - - inline const char * system_error::what() const BOOST_NOEXCEPT_OR_NOTHROW - // see http://www.boost.org/more/error_handling.html for lazy build rationale - { - if ( m_what.empty() ) - { -#ifndef BOOST_NO_EXCEPTIONS - try -#endif - { - m_what = this->std::runtime_error::what(); - if ( !m_what.empty() ) m_what += ": "; - m_what += m_error_code.message(); - } -#ifndef BOOST_NO_EXCEPTIONS - catch (...) { return std::runtime_error::what(); } -#endif - } - return m_what.c_str(); + return buffer; } - } // namespace system + static std::string build_message( char const * prefix, error_code const & ec ) + { + std::string r; + + if( prefix ) + { + r += prefix; + r += ": "; + } + + if( ec.has_location() ) + { + boost::source_location loc = ec.location(); + + r += loc.file_name(); + + r += ':'; + r += to_string( loc.line() ); + + if( loc.column() != 0 ) + { + r += ':'; + r += to_string( loc.column() ); + } + + r += ": in function '"; + r += loc.function_name(); + r += "\': "; + + r += ec.to_string(); + r += ": "; + } + + r += ec.message(); + + return r; + } + + static std::string build_message( char const * prefix, int ev, error_category const & cat ) + { + return build_message( prefix, error_code( ev, cat ) ); + } + +public: + + explicit system_error( error_code const & ec ) + : std::runtime_error( build_message( 0, ec ) ), code_( ec ) {} + + system_error( error_code const & ec, std::string const & prefix ) + : std::runtime_error( build_message( prefix.c_str(), ec ) ), code_( ec ) {} + + system_error( error_code const & ec, char const * prefix ) + : std::runtime_error( build_message( prefix, ec ) ), code_( ec ) {} + + system_error( int ev, error_category const & ecat ) + : std::runtime_error( build_message( 0, ev, ecat ) ), code_( ev, ecat ) {} + + system_error( int ev, error_category const & ecat, std::string const & prefix ) + : std::runtime_error( build_message( prefix.c_str(), ev, ecat ) ), code_( ev, ecat ) {} + + system_error( int ev, error_category const & ecat, char const * prefix ) + : std::runtime_error( build_message( prefix, ev, ecat ) ), code_( ev, ecat ) {} + + error_code code() const BOOST_NOEXCEPT + { + return code_; + } +}; + +} // namespace system } // namespace boost #endif // BOOST_SYSTEM_SYSTEM_ERROR_HPP - -