rvm 1.08

error.h

Go to the documentation of this file.
00001 #ifndef __error_h__
00002 #define __error_h__
00003 
00004 #include <iostream>
00005 #include <string>
00006 #include <algorithm>
00007 #include <exception>
00008 #include <vector>
00009 
00010 #include <cerrno>
00011 
00012 #include "asserts.h"
00013 #include "types.h"
00014 
00015 /** Instance of a single error containing a descriptive error message and the
00016  * location in the file that the error took place */
00017 class error_instance
00018 {
00019 public:
00020         error_instance();
00021         error_instance(const error_instance& a_e);
00022         error_instance(
00023                 const std::string a_what,
00024 #ifdef __GNUC__
00025                 const std::string a_where,
00026 #endif
00027                 const std::string a_file,
00028                 const uint16 a_line
00029                 );
00030 
00031         void clear(void);
00032         void set(void);
00033         void set(const error_instance& a_e);
00034         void set(
00035                 const std::string a_what,
00036 #ifdef __GNUC__
00037                 const std::string a_where,
00038 #endif
00039                 const std::string a_file,
00040                 const uint16 a_line
00041                 );
00042 
00043         const std::string what(void) const;
00044 #ifdef __GNUC__
00045         const std::string where(void) const;
00046 #endif
00047         const std::string file(void) const;
00048         const uint16 line(void) const;
00049 
00050         error_instance& operator=(const error_instance& a_e);
00051 
00052         // void dump(std::ostream& a_out, const std::string& a_prefix) const;
00053 
00054 private:
00055         std::string m_what;
00056 #ifdef __GNUC__
00057         std::string m_where;
00058 #endif
00059         std::string m_file;
00060         uint16 m_line;
00061 };
00062 
00063 #ifdef __GNUC__
00064 #define ERROR_INSTANCE(s) \
00065         error_instance((s), __PRETTY_FUNCTION__, __FILE__, __LINE__)
00066 #else
00067 #define ERROR_INSTANCE(s) \
00068         error_instance((s), __FILE__, __LINE__)
00069 #endif
00070 
00071 /** An error class */
00072 class error : public std::vector<error_instance>
00073 {
00074 public:
00075         typedef std::vector<error_instance> type;
00076 
00077         error(const int a_errno);
00078         error(
00079                 const int a_errno,
00080                 const error_instance& a_e, 
00081                 const bool a_internal = false
00082                 );
00083         error(const error& a_e);
00084 
00085         void clear(void);
00086         void clear_stack(void);
00087         void internal(bool a_i);
00088         const bool internal(void) const;
00089         void num(int a_i);
00090         int num(void) const;
00091         void push_back(const error_instance& a_e);
00092         void push_back(const error& a_e);
00093         void push_back(const std::string& a_str);
00094         void assign(const error& a_e);
00095 
00096         error& operator=(const error& a_e);
00097         std::ostream& write(
00098                 std::ostream& a_out, 
00099                 const std::string a_prefix = ""
00100                 ) const;
00101         const std::string str(const std::string a_prefix = "") const;
00102 
00103         // std::ostream& dump(std::ostream& a_out) const;
00104 
00105 private:
00106         int m_errno;
00107         bool m_internal;
00108 };
00109 
00110 std::ostream& operator<<(std::ostream& a_out, const error& a_e);
00111 
00112 //-----------------------------------------------------------------------------
00113 
00114 #define err_unknown INTERNAL_ERROR(0,"An unknown error has occured")
00115 
00116 #define err_nomem ERROR(ENOMEM,"Out of memory")
00117 
00118 //-----------------------------------------------------------------------------
00119 
00120 #define ERROR(e,s) \
00121         error(e,ERROR_INSTANCE((s)), false)
00122 
00123 #define INTERNAL_ERROR(e,s) \
00124         error(e,ERROR_INSTANCE(s), true)
00125 
00126 #define TRY(code,es) \
00127         try { \
00128                 code; \
00129         } \
00130         catch(error e) { \
00131                 e.push_back(ERROR_INSTANCE(es)); \
00132                 throw(e); \
00133         } \
00134         catch(...) { \
00135                 if (errno == ENOMEM) { \
00136                         throw(err_nomem); \
00137                 } \
00138                 error e = err_unknown; \
00139         \
00140                 e.push_back(es); \
00141                 throw(e); \
00142         }
00143 
00144 #define TRY_nomem(code) \
00145         try { \
00146                 code; \
00147         } \
00148         catch(error e) { \
00149                 throw(e); \
00150         } \
00151         catch(...) { \
00152                 if (errno == ENOMEM) { \
00153                         throw(err_nomem); \
00154                 } \
00155                 throw(err_unknown); \
00156         }
00157 
00158 #define TRY_instead(code,es) \
00159         try { \
00160                 code; \
00161         } \
00162         catch(error e) { \
00163                 e.clear_stack(); \
00164                 e.push_back(ERROR_INSTANCE(es)); \
00165                 throw(e); \
00166         } \
00167         catch(...) { \
00168                 if (errno == ENOMEM) { \
00169                         throw(err_nomem); \
00170                 } \
00171                 error e = err_unknown; \
00172         \
00173                 e.push_back(es); \
00174                 throw(e); \
00175         }
00176 
00177 #define TRY_log(code,es) \
00178         try { \
00179                 code; \
00180         } \
00181         catch(error e) { \
00182                 e.clear_stack(); \
00183                 e.push_back(ERROR_INSTANCE(es)); \
00184                 logger.write(e.str()); \
00185         } \
00186         catch(...) { \
00187                 if (errno == ENOMEM) { \
00188                         throw(err_nomem); \
00189                 } \
00190                 error e = err_unknown; \
00191         \
00192                 e.push_back(es); \
00193                 logger.write(e.str()); \
00194         }
00195 
00196 const char * get_error_str(const int a_err);
00197 
00198 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines