1 /*************************************************************************** 2 * foxxll/common/error_handling.hpp 3 * 4 * Part of FOXXLL. See http://foxxll.org 5 * 6 * Copyright (C) 2007-2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 7 * Copyright (C) 2013 Timo Bingmann <tb@panthema.net> 8 * 9 * Distributed under the Boost Software License, Version 1.0. 10 * (See accompanying file LICENSE_1_0.txt or copy at 11 * http://www.boost.org/LICENSE_1_0.txt) 12 **************************************************************************/ 13 14 #ifndef FOXXLL_COMMON_ERROR_HANDLING_HEADER 15 #define FOXXLL_COMMON_ERROR_HANDLING_HEADER 16 17 /** \file error_handling.hpp 18 * Macros for convenient error checking and reporting via exception. 19 */ 20 21 #include <cerrno> 22 #include <cstring> 23 #include <sstream> 24 25 #include <foxxll/common/exceptions.hpp> 26 #include <foxxll/config.hpp> 27 28 namespace foxxll { 29 30 #if FOXXLL_MSVC 31 #define FOXXLL_PRETTY_FUNCTION_NAME __FUNCTION__ 32 #else 33 #define FOXXLL_PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__ 34 #endif 35 36 //////////////////////////////////////////////////////////////////////////// 37 38 //! Throws exception_type with "Error in [location] : [error_message]" 39 #define FOXXLL_THROW2(exception_type, location, error_message) \ 40 do { \ 41 std::ostringstream msg; \ 42 msg << "Error in " << location << " : " << error_message; \ 43 throw exception_type(msg.str()); \ 44 } while (false) 45 46 //! Throws exception_type with "Error in [function] : [error_message]" 47 #define FOXXLL_THROW(exception_type, error_message) \ 48 FOXXLL_THROW2( \ 49 exception_type, \ 50 FOXXLL_PRETTY_FUNCTION_NAME, \ 51 error_message \ 52 ) 53 54 //! Throws exception_type with "Error in [function] : [error_message] : [errno_value message]" 55 #define FOXXLL_THROW_ERRNO2(exception_type, error_message, errno_value) \ 56 FOXXLL_THROW2( \ 57 exception_type, \ 58 FOXXLL_PRETTY_FUNCTION_NAME, \ 59 error_message << " : " << strerror(errno_value) \ 60 ) 61 62 //! Throws exception_type with "Error in [function] : [error_message] : [errno message]" 63 #define FOXXLL_THROW_ERRNO(exception_type, error_message) \ 64 FOXXLL_THROW_ERRNO2(exception_type, error_message, errno) 65 66 //! Throws std::invalid_argument with "Error in [function] : [error_message]" 67 #define FOXXLL_THROW_INVALID_ARGUMENT(error_message) \ 68 FOXXLL_THROW2( \ 69 std::invalid_argument, \ 70 FOXXLL_PRETTY_FUNCTION_NAME, \ 71 error_message \ 72 ) 73 74 //! Throws foxxll::unreachable with "Error in file [file], line [line] : this code should never be reachable" 75 #define FOXXLL_THROW_UNREACHABLE() \ 76 FOXXLL_THROW2( \ 77 foxxll::unreachable, \ 78 "file " << __FILE__ << ", line " << __LINE__, \ 79 "this code should never be reachable" \ 80 ) 81 82 //////////////////////////////////////////////////////////////////////////// 83 84 //! Throws exception_type if (expr) with "Error in [function] : [error_message]" 85 #define FOXXLL_THROW_IF(expr, exception_type, error_message) \ 86 do { \ 87 if (expr) { \ 88 FOXXLL_THROW(exception_type, error_message); \ 89 } \ 90 } while (false) 91 92 //! Throws exception_type if (expr) with "Error in [function] : [error_message] : [errno message]" 93 #define FOXXLL_THROW_ERRNO_IF(expr, exception_type, error_message) \ 94 do { \ 95 if (expr) { \ 96 FOXXLL_THROW_ERRNO(exception_type, error_message); \ 97 } \ 98 } while (false) 99 100 //! Throws exception_type if (expr != 0) with "Error in [function] : [error_message] : [errno message]" 101 #define FOXXLL_THROW_ERRNO_NE_0(expr, exception_type, error_message) \ 102 FOXXLL_THROW_ERRNO_IF((expr) != 0, exception_type, error_message) 103 104 #if FOXXLL_WINDOWS || defined(__MINGW32__) 105 106 //! Throws exception_type with "Error in [function] : [error_message] : [formatted GetLastError()]" 107 #define FOXXLL_THROW_WIN_LASTERROR(exception_type, error_message) \ 108 do { \ 109 LPVOID lpMsgBuf; \ 110 DWORD dw = GetLastError(); \ 111 FormatMessage( \ 112 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, \ 113 nullptr, dw, \ 114 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \ 115 (LPTSTR)&lpMsgBuf, \ 116 0, nullptr \ 117 ); \ 118 std::ostringstream msg; \ 119 msg << "Error in " << FOXXLL_PRETTY_FUNCTION_NAME \ 120 << " : " << error_message \ 121 << " : error code " << dw << " : " << ((char*)lpMsgBuf); \ 122 LocalFree(lpMsgBuf); \ 123 throw exception_type(msg.str()); \ 124 } while (false) 125 126 #endif 127 128 } // namespace foxxll 129 130 #endif // !FOXXLL_COMMON_ERROR_HANDLING_HEADER 131 132 /**************************************************************************/ 133