00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef W_ERROR_H
00054 #define W_ERROR_H
00055
00056 #include "w_defines.h"
00057
00058
00059
00060
00061 #ifdef __GNUG__
00062 #pragma interface
00063 #endif
00064
00065 #include "fc_error_enum_gen.h"
00066 #include "tls.h"
00067 #include "w_base.h"
00068
00069 #define USE_BLOCK_ALLOC_FOR_W_ERROR_T 1
00070 #if USE_BLOCK_ALLOC_FOR_W_ERROR_T
00071 DECLARE_TLS_SCHWARZ(w_error_alloc);
00072 #endif
00073
00074
00075
00076
00077
00078 struct w_error_info_t {
00079 w_base_t::uint4_t err_num;
00080 const char *errstr;
00081 };
00082
00083
00084
00085
00086
00087
00088 class w_error_t : public w_base_t {
00089 public:
00090 typedef w_error_info_t info_t;
00091
00092
00093
00094
00095
00096
00097
00098 typedef uint4_t err_num_t;
00099
00100
00101 const err_num_t err_num;
00102
00103 const char* const file;
00104 const uint4_t line;
00105 const int4_t sys_err_num;
00106
00107 w_error_t* next() { return _next; }
00108 w_error_t const* next() const { return _next; }
00109
00110 w_error_t& add_trace_info(
00111 const char* const filename,
00112 uint4_t line_num);
00113
00114 w_error_t& clear_more_info_msg();
00115 w_error_t& append_more_info_msg(const char* more_info);
00116 const char* get_more_info_msg() const;
00117
00118 ostream &print_error(ostream &o) const;
00119
00120 #if USE_BLOCK_ALLOC_FOR_W_ERROR_T
00121 void operator delete(void* p);
00122
00123
00124
00125
00126
00127 #if W_DEBUG_LEVEL > 2
00128 #define DEBUG_BLOCK_ALLOC_MARK_FOR_DELETION(p) if(p) (p)->debug_mark_for_deletion();
00129 #define CHECK_DEBUG_BLOCK_ALLOC_MARKED_FOR_DELETION(p) \
00130 if(p && p != no_error) {w_assert0((p)->debug_is_marked_for_deletion() ); }
00131 private:
00132 bool marked;
00133 void debug_mark_for_deletion() { marked = true; }
00134 bool debug_is_marked_for_deletion() const { return marked == true; }
00135 public:
00136 #else
00137 #define DEBUG_BLOCK_ALLOC_MARK_FOR_DELETION(p)
00138 #define CHECK_DEBUG_BLOCK_ALLOC_MARKED_FOR_DELETION(p)
00139 #endif
00140 #else
00141 #define CHECK_DEBUG_BLOCK_ALLOC_MARKED_FOR_DELETION(p)
00142 #endif
00143
00144 static w_error_t* make(
00145 const char* const filename,
00146 uint4_t line_num,
00147 err_num_t err_num,
00148 w_error_t* list = 0,
00149 const char* more_info = 0);
00150 static w_error_t* make(
00151 const char* const filename,
00152 uint4_t line_num,
00153 err_num_t err_num,
00154 uint4_t sys_err,
00155 w_error_t* list = 0,
00156 const char* more_info = 0);
00157
00158 static bool insert(
00159 const char *modulename,
00160 const info_t info[],
00161 uint4_t count);
00162
00163 static const w_error_t no_error_instance;
00164 static w_error_t* const no_error;
00165 static const char* error_string(err_num_t err_num);
00166 static const char* module_name(err_num_t err_num);
00167
00168 NORET ~w_error_t();
00169
00170 private:
00171 enum { max_range = 10, max_trace = 10 };
00172
00173
00174 private:
00175 const char* more_info_msg;
00176
00177 friend class w_rc_t;
00178
00179 uint4_t _trace_cnt;
00180 w_error_t* _next;
00181 const char* _trace_file[max_trace];
00182 uint4_t _trace_line[max_trace];
00183
00184 NORET w_error_t(
00185 const char* const filename,
00186 uint4_t line_num,
00187 err_num_t err_num,
00188 w_error_t* list,
00189 const char* more_info);
00190 NORET w_error_t(
00191 const char* const filename,
00192 uint4_t line_num,
00193 err_num_t err_num,
00194 uint4_t sys_err,
00195 w_error_t* list,
00196 const char* more_info);
00197
00198
00199 NORET w_error_t(const w_error_t&);
00200 w_error_t& operator=(const w_error_t&);
00201
00202 static const info_t* _range_start[max_range];
00203 static uint4_t _range_cnt[max_range];
00204 static const char * _range_name[max_range];
00205 static uint4_t _nreg;
00206
00207 static inline uint4_t classify(int err_num);
00208 public:
00209
00210 static const info_t error_info[];
00211 static ostream & print(ostream &out);
00212 private:
00213
00214 static void init_errorcodes();
00215
00216 };
00217
00218 extern ostream &operator<<(ostream &o, const w_error_t &obj);
00219
00220 #if W_DEBUG_LEVEL > 1
00221 #define CHECKIT do {\
00222 w_error_t* my = _next; \
00223 w_error_t* p = my; \
00224 while(p) { \
00225 if (p == p->_next || my == p->_next) { \
00226 cerr << "Recursive error detected:" << endl << *this << endl;\
00227 w_assert0(0); \
00228 } \
00229 p = p->_next; \
00230 } \
00231 } while(0)
00232
00233 #else
00234 #define CHECKIT
00235 #endif
00236
00237
00238 inline NORET
00239 w_error_t::~w_error_t()
00240 {
00241
00242 CHECK_DEBUG_BLOCK_ALLOC_MARKED_FOR_DELETION((w_error_t *)this)
00243 delete[] more_info_msg;
00244 more_info_msg = NULL;
00245 #if USE_BLOCK_ALLOC_FOR_W_ERROR_T
00246 w_error_t::operator delete(_next);
00247 #else
00248 delete _next;
00249 #endif
00250 _next = NULL;
00251 }
00252
00253
00254
00255 #endif