ircproxy The Ultimate Cyborg |
00001 // ircproxy -- An IRC bouncer. 00002 // 00003 //! @file exceptions.h 00004 //! @brief This file contains the declaration of exception related classes and (debug) macros. 00005 // 00006 // Copyright (C) 2006, 2007 by 00007 // 00008 // Carlo Wood, Run on IRC <carlo@alinoe.com> 00009 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 00010 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 00011 // 00012 // This file may be distributed under the terms of the Q Public License 00013 // version 1.0 as appearing in the file LICENSE.QPL included in the 00014 // packaging of this file. 00015 00016 #ifndef EXCEPTIONS_H 00017 #define EXCEPTIONS_H 00018 00019 #ifndef USE_PCH 00020 #include "debug.h" 00021 #include <stdexcept> // std::runtime_error 00022 #include <sstream> // std::ostringstream 00023 #endif 00024 00025 /*! @brief An exception class 00026 * 00027 * An object of this class is thrown if the application tries 00028 * to resolve a target by name but no such target is known. 00029 * 00030 * \sa Target::get_joined_nick, Target::serverside_get_nick, Target::serverside_get_channel, Target::clientside_get_channel, Target::clientside_get_nick 00031 */ 00032 class unknown_target : public virtual std::exception { 00033 public: 00034 //! Virtual destructor. 00035 virtual ~unknown_target() throw() { } 00036 //! Implementation of std::exception::what(). Returns the error message string. 00037 virtual char const* what(void) const throw() { return "unknown_target"; } 00038 }; 00039 00040 /*! @brief An exception class 00041 * 00042 * An object of this class is thrown in case a client message 00043 * causes an unrecoverable error. The result is that the client 00044 * is disconnected. 00045 */ 00046 class FatalError : public std::exception { 00047 private: 00048 std::string M_message; //!< The actual error message string. 00049 public: 00050 //! Construct a FatalError instance with message string \a message. 00051 FatalError(std::string const& message) : M_message(message) { } 00052 //! Virtual destructor. 00053 virtual ~FatalError() throw() { } 00054 //! Assignment operator. 00055 FatalError& operator=(FatalError const& error) { M_message = error.M_message; return *this; } 00056 //! Implementation of std::exception::what(). Returns the error message string. 00057 virtual char const* what(void) const throw() { return M_message.c_str(); } 00058 }; 00059 00060 //! @brief Namespace with utilities copied from the edragon project. 00061 namespace edragon { 00062 00063 // Declaration, specifying the noreturn attribute. 00064 // "Indeed, 'throw' is a noreturn function" -- Richard Henderson, 2004/05/07. 00065 // According to this, and other gcc developers, specifying that a function does NOT throw 00066 // speeds up the code a little bit - however, there is no difference between specifying 00067 // what a function throws and specifying nothing; except when then the function indeed 00068 // throws at runtime, in which case it is slower because the code has to check if the 00069 // thrown exception is one of the expected ones. 00070 // Therefore it is best to not specify that this function throws `exception'. 00071 template<class E> 00072 void throw_exception(E const& exception, std::string const& debug_msg) __attribute__ ((noreturn)); 00073 00074 #if defined(CWDEBUG) || defined(DOXYGEN) 00075 /*! 00076 * @internal 00077 * @brief Throw an exception. 00078 * 00079 * @param exception The exception to be thrown. 00080 * @param debug_msg A simple string for debugging purposes, to clarify the reason why the exception is thrown. 00081 * 00082 * Debug output has the form: 00083 * 00084 * EXCEPTIONS: <debug_msg>, throwing exception "<exception.what()>". 00085 * 00086 * Don't use this function directly, instead use the macro THROW_EXCEPTION. 00087 */ 00088 template<class E> 00089 void throw_exception(E const& exception, std::string const& debug_msg) 00090 { 00091 #if CWDEBUG_LOCATION 00092 libcwd::location_ct loc((char*)__builtin_return_address(0) + libcwd::builtin_return_address_offset); 00093 #else 00094 void* loc = (char*)__builtin_return_address(0) + libcwd::builtin_return_address_offset; 00095 #endif 00096 Dout(dc::exceptions, loc << ": " << debug_msg << ", throwing exception \"" << exception.what() << "\"."); 00097 throw exception; 00098 } 00099 00100 /*! @brief Throw an exception. 00101 * 00102 * Always use this macro to throw an exception in eDragon. 00103 * @param exception The exception to be thrown. 00104 * @param debug_msg A simple string for debugging purposes, to clarify the reason why the exception is thrown. 00105 * 00106 * Debug output has the form: 00107 * 00108 * EXCEPTIONS: [<addr location>: ]<debug_msg>, throwing exception "<exception.what()>". 00109 */ 00110 #define THROW_EXCEPTION(exception, debug_msg...) \ 00111 do { \ 00112 std::ostringstream __ssbuf; \ 00113 __ssbuf << debug_msg; \ 00114 edragon::throw_exception(exception, __ssbuf.str()); \ 00115 } while (0) 00116 #else 00117 #define THROW_EXCEPTION(exception, debug_msg...) \ 00118 do { throw exception; } while (0) 00119 #endif 00120 00121 #ifdef CWDEBUG 00122 /*! @brief Debugging function. 00123 * 00124 * Print location that this function was called from and what \a exception was caught there. 00125 */ 00126 template<class E> 00127 void caught(E const& exception) 00128 { 00129 #if CWDEBUG_LOCATION 00130 libcwd::location_ct loc((char*)__builtin_return_address(0) + libcwd::builtin_return_address_offset); 00131 #else 00132 void* loc = (char*)__builtin_return_address(0) + libcwd::builtin_return_address_offset; 00133 #endif 00134 Dout(dc::exceptions, loc << ": caught exception \"" << exception.what() << "\"."); 00135 } 00136 #endif 00137 00138 } // namespace edragon 00139 00140 #endif // EXCEPTIONS_H
Copyright © 2005-2007 Carlo Wood. All rights reserved. |
---|