00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef DIVINE_ERROR_HH
00020 #define DIVINE_ERROR_HH
00021
00022 #ifndef DOXYGEN_PROCESSING
00023 #include <iostream>
00024 #include <string>
00025 #include <vector>
00026 #include <memory>
00027 #include "common/inttostr.hh"
00028 #include "common/types.hh"
00029 #include "common/deb.hh"
00030
00031 namespace divine {
00032 #endif //DOXYGEN_PROCESSING
00033
00035 typedef const char * ERR_char_string_t;
00036 typedef const std::string ERR_std_string_t;
00038 typedef unsigned int ERR_nbr_t;
00040 typedef int ERR_id_t;
00042 typedef int ERR_type_t;
00046 struct ERR_throw_t {
00047 ERR_type_t type;
00048 ERR_id_t id;
00049 ERR_throw_t(const ERR_type_t type_arg, const ERR_id_t id_arg):
00050 type(type_arg), id(id_arg) {}
00051 };
00052
00056 const ERR_id_t ERR_UNKNOWN_ID = 1;
00060 const ERR_type_t ERR_UNKNOWN_TYPE = 1;
00061
00062 class error_vector_t;
00063
00065
00071 typedef void (*ERR_psh_callback_t)(error_vector_t & terr, const ERR_throw_t);
00073
00079 typedef void (*ERR_thr_callback_t)(error_vector_t & terr, const ERR_throw_t);
00080
00082
00091 void ERR_default_psh_callback(error_vector_t & terr, const ERR_throw_t);
00093
00103 void ERR_default_thr_callback(error_vector_t & terr, const ERR_throw_t);
00104
00106
00111 class error_string_t
00112 {
00113 private:
00114 std::string * s;
00115 static divine::size_int_t alloc_str_count;
00116 template<class T>
00117
00118 error_string_t & plus(const T i)
00119 {
00120 char * numstr = create_string_from<T>(i);
00121 s->append(numstr);
00122 dispose_string(numstr);
00123 return (*this);
00124 }
00125 public:
00126 static divine::size_int_t allocated_strings() { return alloc_str_count; }
00127 error_string_t() { recreate(); }
00128 void recreate () { s = new std::string; alloc_str_count++;};
00129 error_string_t(const error_string_t & s2) { s = s2.s; }
00130 error_string_t(error_string_t & s2) { s = s2.s; }
00131
00132
00133 void delete_content()
00134 { delete s; alloc_str_count--;
00135 DEB(std::cerr << "error_string_t object deallocated!" << std::endl;) }
00136 std::string & operator*() { return *s; }
00137 friend const std::string & operator*(const error_string_t & errstr)
00138 { return *errstr.s; }
00139 error_string_t & operator<<(const unsigned long int i)
00140 { return plus<unsigned long int>(i); }
00141 error_string_t & operator<<(const signed long int i)
00142 { return plus<signed long int>(i); }
00143 error_string_t & operator<<(const unsigned int i)
00144 { return plus<unsigned long int>(i); }
00145 error_string_t & operator<<(const int i)
00146 { return plus<signed long int>(i); }
00147 friend std::ostream & operator<<(std::ostream & ostr, const error_string_t s)
00148 { return(ostr << (*s)); }
00149 error_string_t & operator<<(const ERR_char_string_t second_str)
00150 { s->append(second_str); return (*this); }
00151 error_string_t & operator<<(const ERR_std_string_t & second_str)
00152 { s->append(second_str); return (*this); }
00153 error_string_t & operator<<(const error_string_t second_str)
00154 { s->append(*second_str); return (*this); }
00155 std::string * operator->() { return s; }
00156 };
00157
00159
00160
00173 struct thr
00174 { ERR_id_t c; ERR_type_t t;
00175 thr(ERR_type_t tt = ERR_UNKNOWN_TYPE, ERR_id_t i = ERR_UNKNOWN_ID):
00176 c(i),t(tt) {}
00177 };
00178
00180
00192 struct psh
00193 { ERR_id_t c; ERR_type_t t;
00194 psh(ERR_type_t tt = ERR_UNKNOWN_TYPE, ERR_id_t i = ERR_UNKNOWN_ID):
00195 c(i),t(tt) {}
00196 };
00197
00200
00203 struct ERR_triplet_t {
00204 const ERR_char_string_t message;
00205 const ERR_id_t id;
00206 const ERR_type_t type;
00207 ERR_triplet_t(const ERR_char_string_t mes,
00208 const ERR_type_t tt = ERR_UNKNOWN_TYPE,
00209 const ERR_id_t num = ERR_UNKNOWN_ID):
00210 message(mes), id(num), type(tt) {};
00211 };
00212
00214 typedef const ERR_triplet_t ERR_c_triplet_t;
00215
00217
00239 class error_vector_t
00240 {
00241 private:
00242
00243 struct Pair {
00244 error_string_t message;
00245 ERR_id_t id;
00246 Pair(error_string_t mes, const ERR_id_t num):
00247 message(mes), id(num) {};
00248 };
00249
00250 typedef std::vector<Pair> vector_t;
00251
00252 vector_t err_vector;
00253 error_string_t string_err;
00254 ERR_thr_callback_t throw_callback;
00255 ERR_psh_callback_t push_callback;
00256 bool is_silent;
00257
00258 public:
00260
00262 error_vector_t(): throw_callback(ERR_default_thr_callback),
00263 push_callback(ERR_default_psh_callback),
00264 is_silent(false) {};
00266
00268
00269 ~error_vector_t() { DEBAUX(std::cerr << "BEGIN of destructor of error_vector_t" << std::endl;) string_err.delete_content(); clear(); DEBAUX(std::cerr << "END of destructor of error_vector_t" << std::endl;) }
00270
00272 void set_push_callback(const ERR_psh_callback_t func);
00274 void set_throw_callback(const ERR_thr_callback_t func);
00275
00276
00279
00284 void that(const ERR_c_triplet_t & st);
00285
00286
00288
00293 void that(error_string_t & mes, const ERR_type_t err_type = ERR_UNKNOWN_TYPE,
00294 const ERR_id_t id = ERR_UNKNOWN_ID);
00295
00297
00302 void push(error_string_t& mes, const ERR_id_t id = ERR_UNKNOWN_ID);
00303
00305
00308 void pop_back(const ERR_nbr_t n);
00309
00311
00314 void pop_front(const ERR_nbr_t n);
00315
00317 void pop_back();
00318
00320 void pop_front();
00321
00323
00326 void pop(const ERR_nbr_t index);
00327
00329
00332 void pop(const ERR_nbr_t begin, const ERR_nbr_t end);
00333
00335 void clear() { pop_back(0); }
00336
00338
00341 void flush();
00342
00344 bool empty()
00345 { return bool(err_vector.size()); }
00346
00348 ERR_nbr_t count()
00349 { return err_vector.size(); }
00350
00352 void print(ERR_char_string_t mes);
00353
00356 void perror(const ERR_nbr_t i);
00357
00360 void perror_front();
00361
00364 void perror_back();
00365
00368 void perror(ERR_char_string_t mes, const ERR_nbr_t i);
00369
00372 void perror_front(ERR_char_string_t mes);
00373
00376 void perror_back(ERR_char_string_t mes);
00377
00379 const error_string_t string_back();
00380
00383 const error_string_t string_front();
00384
00387 const error_string_t string(const ERR_nbr_t i);
00388
00390 ERR_id_t id_back();
00391
00394 ERR_id_t id_front();
00395
00398 ERR_id_t id(const ERR_nbr_t i);
00399
00401
00405 void operator<<(const thr & e);
00407
00411 void operator<<(const psh & e);
00412
00414 error_vector_t & operator<<(const ERR_char_string_t second_str)
00415 { string_err<<second_str; return (*this); }
00416
00418 error_vector_t & operator<<(const ERR_std_string_t & second_str)
00419 { string_err<<second_str; return (*this); }
00420
00422 error_vector_t & operator<<(const error_string_t second_str)
00423 { string_err<<second_str; return (*this); }
00424
00427 error_vector_t & operator<<(const unsigned long int i)
00428 {string_err<<i; return (*this);}
00429
00432 error_vector_t & operator<<(const signed long int i)
00433 { string_err<<i; return (*this); }
00434
00437 error_vector_t & operator<<(const unsigned int i)
00438 { string_err<<i; return (*this); }
00439
00442 error_vector_t & operator<<(const int i)
00443 { string_err<<i; return (*this); }
00444
00446 void set_silent(const bool be_silent) { is_silent = be_silent; }
00447
00449 bool get_silent() const { return is_silent; }
00450 };
00451
00453
00457 extern error_vector_t gerr;
00458
00459 template<typename T> inline T noreturn() { return T(); }
00460 #define UNIMPLEMENTED(type) \
00461 do { \
00462 gerr << "unimplemented " << __FILE__ << ":" << __LINE__ << thr(); \
00463 return noreturn<type>(); \
00464 } while(0)
00465
00466 #ifndef DOXYGEN_PROCESSING
00467 };
00468 #include "common/undeb.hh"
00469 #endif //DOXYGEN_PROCESSING
00470
00471 #endif
00472