00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __libutilxx__sella__Exception_H__
00010 #define __libutilxx__sella__Exception_H__
00011
00012 #include "../common.h"
00013
00014 #include <stdarg.h>
00015 #include <typeinfo>
00016
00017 #include <string>
00018 #include <exception>
00019
00026 #define NO_EXCEPTIONS throw ()
00027
00034 #define THROWS(e, ...) throw (e, ##__VA_ARGS__)
00035
00036 #define THROW(exception, format, ...) throw exception(false, __func__, __FILE__, __LINE__, 0, format, ##__VA_ARGS__)
00037 #define THROW_CODE(exception, code, format, ...) throw exception(false, __func__, __FILE__, __LINE__, code, format, ##__VA_ARGS__)
00038 #define THROW2(exception, format, ...) throw exception(true, __func__, __FILE__, __LINE__, 0, format, ##__VA_ARGS__)
00039 #define THROW2_CODE(exception, code, format, ...) throw exception(true, __func__, __FILE__, __LINE__, code, format, ##__VA_ARGS__)
00040 #define RETHROW(exception, e) throw exception(false, __func__, __FILE__, __LINE__, e.getCode(), e.what())
00041 #define RETHROW_CODE(exception, code, e) throw exception(false, __func__, __FILE__, __LINE__, code, e.what())
00042 #define RETHROW2(exception, e, format, ...) throw exception(false, __func__, __FILE__, __LINE__, 0, e, format, ##__VA_ARGS__)
00043 #define RETHROW2_CODE(exception, code, e, format, ...) throw exception(false, __func__, __FILE__, __LINE__, code, e, format, ##__VA_ARGS__)
00044
00045 #define EXCEPTION_BUILDMESSAGE_CODE \
00046 do { \
00047 va_list list; \
00048 va_start(list, format); \
00049 buildMessage(sysmsg, format, list); \
00050 va_end(list); \
00051 } while (false);
00052
00053
00054 #define BUILD_EXCEPTION(T) \
00055 class T : public sella::Exception { \
00056 public: \
00057 T(bool sysmsg, const char *function, const char *file, int line, int code, const char *format, ...) throw () : \
00058 Exception(function, file, line, code) { EXCEPTION_BUILDMESSAGE_CODE }; \
00059 T(bool sysmsg, const char *function, const char *file, int line, int code, sella::Exception &e, const char *format, ...) throw () : \
00060 Exception(function, file, line, code) { EXCEPTION_BUILDMESSAGE_CODE; message.append(" Error: ").append(e.getMessage()); }; \
00061 virtual const char* what() const throw () { return Exception::what(); } \
00062 virtual int getCode() const throw () { return Exception::getCode(); } \
00063 virtual const std::string getName() const throw () { return demangle(typeid(T).name()); } \
00064 };
00065
00066 namespace sella {
00067 class Exception;
00068 }
00069
00070 class sella::Exception : public std::exception {
00071 public:
00072 Exception(const char *function, const char *file, int line, int code) throw ();
00073 Exception(bool sysmsg, const char *function, const char *file, int line, int code, const char *format, ...) throw ();
00074
00075 Exception(const Exception &other) throw ();
00076 #ifndef SWIG
00077 Exception(const Exception &&other) throw ();
00078 #endif
00079
00080 virtual ~Exception() throw ();
00081
00082 public:
00083 Exception& operator=(const Exception &other) throw ();
00084 #ifndef SWIG
00085 Exception& operator=(const Exception &&other) throw ();
00086 #endif
00087
00088 public:
00089 virtual const char* what() const throw ();
00090 virtual const std::string& getMessage() const throw ();
00091 virtual const std::string& getFunction() const throw ();
00092 virtual const std::string& getFile() const throw ();
00093 virtual const std::string getName() const throw ();
00094 virtual int getLine() const throw ();
00095 virtual int getCode() const throw ();
00096
00097 virtual const std::string& str() const throw ();
00098 virtual const char* c_str() const throw ();
00099
00100 protected:
00101 std::string function;
00102 std::string file;
00103 int line;
00104 int code;
00105 std::string message;
00106 mutable std::string cache;
00107
00108 void buildMessage(bool sysmsg, const char *format, va_list list) throw ();
00109 const std::string demangle(const char *name) const throw ();
00110 };
00111
00112 #endif
00113
00114
00115
00116