diff options
Diffstat (limited to 'klm/util/exception.hh')
-rw-r--r-- | klm/util/exception.hh | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/klm/util/exception.hh b/klm/util/exception.hh index c6936914..81675a57 100644 --- a/klm/util/exception.hh +++ b/klm/util/exception.hh @@ -1,8 +1,6 @@ #ifndef UTIL_EXCEPTION__ #define UTIL_EXCEPTION__ -#include "util/string_piece.hh" - #include <exception> #include <sstream> #include <string> @@ -22,6 +20,14 @@ class Exception : public std::exception { // Not threadsafe, but probably doesn't matter. FWIW, Boost's exception guidance implies that what() isn't threadsafe. const char *what() const throw(); + // For use by the UTIL_THROW macros. + void SetLocation( + const char *file, + unsigned int line, + const char *func, + const char *child_name, + const char *condition); + private: template <class Except, class Data> friend typename Except::template ExceptionTag<Except&>::Identity operator<<(Except &e, const Data &data); @@ -43,7 +49,49 @@ template <class Except, class Data> typename Except::template ExceptionTag<Excep return e; } -#define UTIL_THROW(Exception, Modify) { Exception UTIL_e; {UTIL_e << Modify;} throw UTIL_e; } +#ifdef __GNUC__ +#define UTIL_FUNC_NAME __PRETTY_FUNCTION__ +#else +#ifdef _WIN32 +#define UTIL_FUNC_NAME __FUNCTION__ +#else +#define UTIL_FUNC_NAME NULL +#endif +#endif + +#define UTIL_SET_LOCATION(UTIL_e, child, condition) do { \ + (UTIL_e).SetLocation(__FILE__, __LINE__, UTIL_FUNC_NAME, (child), (condition)); \ +} while (0) + +/* Create an instance of Exception, add the message Modify, and throw it. + * Modify is appended to the what() message and can contain << for ostream + * operations. + * + * do .. while kludge to swallow trailing ; character + * http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html . + */ +#define UTIL_THROW(Exception, Modify) do { \ + Exception UTIL_e; \ + UTIL_SET_LOCATION(UTIL_e, #Exception, NULL); \ + UTIL_e << Modify; \ + throw UTIL_e; \ +} while (0) + +#define UTIL_THROW_VAR(Var, Modify) do { \ + Exception &UTIL_e = (Var); \ + UTIL_SET_LOCATION(UTIL_e, NULL, NULL); \ + UTIL_e << Modify; \ + throw UTIL_e; \ +} while (0) + +#define UTIL_THROW_IF(Condition, Exception, Modify) do { \ + if (Condition) { \ + Exception UTIL_e; \ + UTIL_SET_LOCATION(UTIL_e, #Exception, #Condition); \ + UTIL_e << Modify; \ + throw UTIL_e; \ + } \ +} while (0) class ErrnoException : public Exception { public: @@ -51,7 +99,7 @@ class ErrnoException : public Exception { virtual ~ErrnoException() throw(); - int Error() { return errno_; } + int Error() const throw() { return errno_; } private: int errno_; |