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 std::string& a_str);
00093         void assign(const error& a_e);
00094 
00095         error& operator=(const error& a_e);
00096         std::ostream& write(
00097                 std::ostream& a_out, 
00098                 const std::string a_prefix = ""
00099                 ) const;
00100         const std::string str(const std::string a_prefix = "") const;
00101 
00102         // std::ostream& dump(std::ostream& a_out) const;
00103 
00104 private:
00105         int m_errno;
00106         bool m_internal;
00107 };
00108 
00109 std::ostream& operator<<(std::ostream& a_out, const error& a_e);
00110 
00111 //-----------------------------------------------------------------------------
00112 
00113 #define err_unknown INTERNAL_ERROR(0,"An unknown error has occured")
00114 
00115 #define err_nomem ERROR(ENOMEM,"Out of memory")
00116 
00117 //-----------------------------------------------------------------------------
00118 
00119 #define ERROR(e,s) \
00120         error(e,ERROR_INSTANCE((s)), false)
00121 
00122 #define INTERNAL_ERROR(e,s) \
00123         error(e,ERROR_INSTANCE(s), true)
00124 
00125 #define TRY(code,es) \
00126         try { \
00127                 code; \
00128         } \
00129         catch(error e) { \
00130                 e.push_back(ERROR_INSTANCE(es)); \
00131                 throw(e); \
00132         } \
00133         catch(...) { \
00134                 if (errno == ENOMEM) { \
00135                         throw(err_nomem); \
00136                 } \
00137                 error e = err_unknown; \
00138         \
00139                 e.push_back(es); \
00140                 throw(e); \
00141         }
00142 
00143 #define TRY_nomem(code) \
00144         try { \
00145                 code; \
00146         } \
00147         catch(error e) { \
00148                 throw(e); \
00149         } \
00150         catch(...) { \
00151                 if (errno == ENOMEM) { \
00152                         throw(err_nomem); \
00153                 } \
00154                 throw(err_unknown); \
00155         }
00156 
00157 #define TRY_instead(code,es) \
00158         try { \
00159                 code; \
00160         } \
00161         catch(error e) { \
00162                 e.clear_stack(); \
00163                 e.push_back(ERROR_INSTANCE(es)); \
00164                 throw(e); \
00165         } \
00166         catch(...) { \
00167                 if (errno == ENOMEM) { \
00168                         throw(err_nomem); \
00169                 } \
00170                 error e = err_unknown; \
00171         \
00172                 e.push_back(es); \
00173                 throw(e); \
00174         }
00175 
00176 #define TRY_log(code,es) \
00177         try { \
00178                 code; \
00179         } \
00180         catch(error e) { \
00181                 e.clear_stack(); \
00182                 e.push_back(ERROR_INSTANCE(es)); \
00183                 logger.write(e.str()); \
00184         } \
00185         catch(...) { \
00186                 if (errno == ENOMEM) { \
00187                         throw(err_nomem); \
00188                 } \
00189                 error e = err_unknown; \
00190         \
00191                 e.push_back(es); \
00192                 logger.write(e.str()); \
00193         }
00194 
00195 const char * get_error_str(const int a_err);
00196 
00197 #endif

Generated on Mon Jul 12 12:02:42 2004 for rvm by doxygen 1.3.6