1 /*********************************************************************/ 2 // dar - disk archive - a backup/restoration program 3 // Copyright (C) 2002-2052 Denis Corbin 4 // 5 // This program is free software; you can redistribute it and/or 6 // modify it under the terms of the GNU General Public License 7 // as published by the Free Software Foundation; either version 2 8 // of the License, or (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 // 19 // to contact the author : http://dar.linux.free.fr/email.html 20 /*********************************************************************/ 21 22 /// \file erreurs.hpp 23 /// \brief contains all the excetion class thrown by libdar 24 /// \ingroup API 25 26 #ifndef ERREURS_HPP 27 #define ERREURS_HPP 28 29 #include "../my_config.h" 30 31 #include <string> 32 #include <list> 33 #include "integers.hpp" 34 #include "erreurs.hpp" 35 36 namespace libdar 37 { 38 39 /// \addtogroup API 40 /// @{ 41 42 /// a routine to change NLS domaine forth and back for inline routines 43 extern const char *dar_gettext(const char *); 44 45 /// this is the parent class of all exception classes. 46 47 /// this is a pure virtual class that provide some simple 48 /// mechanisme to carry the information about the cause of the exception, 49 /// as well as some a complex mechanim which not used often in libdar 50 /// that keep trace, for each exception throwing process, of the different 51 /// calls by which the current exception has been exiting. 52 class Egeneric 53 { 54 public : 55 /// the constructor 56 Egeneric(const std::string &source, const std::string &message); 57 /// the destructor ~Egeneric()58 virtual ~Egeneric() {}; 59 60 /// add more detailed couple of information to the exception stack(const std::string & passage,const std::string & message="")61 virtual void stack(const std::string & passage, const std::string & message = "") { pile.push_back(niveau(passage, message)); }; 62 63 /// get the message explaing the nature of the exception 64 65 /// This is probably the only method you will use for all the 66 /// the exception, as you will not have to create such objects 67 /// and will only need to get the error message thanks to this 68 /// method get_message() const69 const std::string & get_message() const { return pile.front().objet; }; 70 71 /// get the call function which has thrown this exception get_source() const72 const std::string & get_source() const { return pile.front().lieu; }; 73 74 /// retrieve the objet (object) associated to a given "lieu" (location) from the stack 75 76 /// \param[in] location key to look for the value of 77 /// \return returns an empty string if key is not found in the stack 78 const std::string & find_object(const std::string & location) const; 79 80 /// prepend error message by the given string 81 void prepend_message(const std::string & context); 82 83 /// dump all information of the exception to the standard error 84 /// 85 /// \note deprecated call, replaced by dump_str() 86 void dump() const; 87 88 /// return a string result of the exception information dump 89 std::string dump_str() const; 90 91 protected : 92 virtual std::string exceptionID() const = 0; 93 94 private : 95 struct niveau 96 { niveaulibdar::Egeneric::niveau97 niveau(const std::string &ou, const std::string &quoi) { lieu = ou; objet = quoi; }; 98 std::string lieu, objet; 99 }; 100 101 std::list<niveau> pile; 102 103 static const std::string empty_string; 104 }; 105 106 107 /// exception used when memory has been exhausted 108 109 /// the inherited get_message() method is probably 110 /// the only one you will need to use 111 class Ememory : public Egeneric 112 { 113 public: Ememory(const std::string & source)114 Ememory(const std::string &source) : Egeneric(source, dar_gettext("Lack of Memory")) {}; 115 116 protected: Ememory(const std::string & source,const std::string & message)117 Ememory(const std::string &source, const std::string & message) : Egeneric(source, message) {}; exceptionID() const118 std::string exceptionID() const { return "MEMORY"; }; 119 }; 120 121 /// exception used when secure memory has been exhausted 122 123 class Esecu_memory : public Ememory 124 { 125 public: Esecu_memory(const std::string & source)126 Esecu_memory(const std::string &source) : Ememory(source, dar_gettext("Lack of Secured Memory")) {}; 127 128 protected: exceptionID() const129 std::string exceptionID() const { return "SECU_MEMORY"; }; 130 }; 131 132 133 #define SRC_BUG Ebug(__FILE__, __LINE__) 134 // #define XMT_BUG(exception, call) exception.stack(call, __FILE__, __LINE__) 135 136 /// exception used to signal a bug. A bug is triggered when reaching some code that should never be reached 137 class Ebug : public Egeneric 138 { 139 public : 140 Ebug(const std::string & file, S_I line); 141 142 using Egeneric::stack; // to avoid warning with clang 143 void stack(const std::string & passage, const std::string & file, const std::string & line); 144 145 protected : exceptionID() const146 std::string exceptionID() const { return "BUG"; }; 147 }; 148 149 /// exception used when arithmetic error is detected when operating on infinint 150 151 /// the inherited get_message() method is probably 152 /// the only one you will need to use 153 class Einfinint : public Egeneric 154 { 155 public : Einfinint(const std::string & source,const std::string & message)156 Einfinint(const std::string & source, const std::string & message) : Egeneric(source, message) {}; 157 158 protected : exceptionID() const159 std::string exceptionID() const { return "INFININT"; }; 160 }; 161 162 /// exception used when a limitint overflow is detected, the maximum value of the limitint has been exceeded 163 164 /// the inherited get_message() method is probably 165 /// the only one you will need to use 166 class Elimitint : public Egeneric 167 { 168 public : Elimitint()169 Elimitint() : Egeneric("", dar_gettext("Cannot handle such a too large integer. Use a full version of libdar (compiled to rely on the \"infinint\" integer type) to solve this problem")) {}; 170 171 protected : exceptionID() const172 std::string exceptionID() const { return "LIMITINT"; }; 173 }; 174 175 /// exception used to signal range error 176 177 /// the inherited get_message() method is probably 178 /// the only one you will need to use 179 class Erange : public Egeneric 180 { 181 public : Erange(const std::string & source,const std::string & message)182 Erange(const std::string & source, const std::string & message) : Egeneric(source, message) {}; 183 184 protected : exceptionID() const185 std::string exceptionID() const { return "RANGE"; }; 186 }; 187 188 /// exception used to signal convertion problem between infinint and string (decimal representation) 189 190 /// the inherited get_message() method is probably 191 /// the only one you will need to use 192 /// see also the class deci 193 class Edeci : public Egeneric 194 { 195 public : Edeci(const std::string & source,const std::string & message)196 Edeci(const std::string & source, const std::string & message) : Egeneric(source, message) {}; 197 198 protected : exceptionID() const199 std::string exceptionID() const { return "DECI"; }; 200 }; 201 202 /// exception used when a requested feature is not (yet) implemented 203 204 /// the inherited get_message() method is probably 205 /// the only one you will need to use 206 class Efeature : public Egeneric 207 { 208 public : Efeature(const std::string & message)209 Efeature(const std::string & message) : Egeneric("", message) {}; 210 211 protected : exceptionID() const212 std::string exceptionID() const { return "UNIMPLEMENTED FEATURE"; }; 213 }; 214 215 /// exception used when hardware problem is found 216 217 /// the inherited get_message() method is probably 218 /// the only one you will need to use 219 class Ehardware : public Egeneric 220 { 221 public : Ehardware(const std::string & source,const std::string & message)222 Ehardware(const std::string & source, const std::string & message) : Egeneric(source, message) {}; 223 224 protected : exceptionID() const225 std::string exceptionID() const { return "HARDWARE ERROR"; }; 226 }; 227 228 /// exception used to signal that the user has aborted the operation 229 230 /// the inherited get_message() method is probably 231 /// the only one you will need to use 232 class Euser_abort : public Egeneric 233 { 234 public : Euser_abort(const std::string & msg)235 Euser_abort(const std::string & msg) : Egeneric("",msg) {}; 236 237 protected : exceptionID() const238 std::string exceptionID() const { return "USER ABORTED OPERATION"; }; 239 }; 240 241 242 /// exception used when an error concerning the treated data has been met 243 244 /// the inherited get_message() method is probably 245 /// the only one you will need to use 246 class Edata : public Egeneric 247 { 248 public : Edata(const std::string & msg)249 Edata(const std::string & msg) : Egeneric("", msg) {}; 250 251 protected : exceptionID() const252 std::string exceptionID() const { return "ERROR IN TREATED DATA"; }; 253 }; 254 255 /// exception used when error the inter-slice user command returned an error code 256 257 /// the inherited get_message() method is probably 258 /// the only one you will need to use 259 class Escript : public Egeneric 260 { 261 public : Escript(const std::string & source,const std::string & msg)262 Escript(const std::string & source, const std::string & msg) : Egeneric(source ,msg) {}; 263 264 protected : exceptionID() const265 std::string exceptionID() const { return "USER ABORTED OPERATION"; }; 266 }; 267 268 /// exception used to signal an error in the argument given to libdar call of the API 269 270 /// the inherited get_message() method is probably 271 /// the only one you will need to use 272 class Elibcall : public Egeneric 273 { 274 public : Elibcall(const std::string & source,const std::string & msg)275 Elibcall(const std::string & source, const std::string & msg) : Egeneric(source ,msg) {}; 276 277 protected : exceptionID() const278 std::string exceptionID() const { return "USER ABORTED OPERATION"; }; 279 }; 280 281 /// exception used when a requested fearture has not beed activated at compilation time 282 283 /// the inherited get_message() method is probably 284 /// the only one you will need to use 285 class Ecompilation : public Egeneric 286 { 287 public : Ecompilation(const std::string & msg)288 Ecompilation(const std::string & msg) : Egeneric("" ,msg) {}; 289 290 protected : exceptionID() const291 std::string exceptionID() const { return "FEATURE DISABLED AT COMPILATION TIME"; }; 292 }; 293 294 295 /// exception used when the thread libdar is running in is asked to stop 296 297 class Ethread_cancel : public Egeneric 298 { 299 public: Ethread_cancel(bool now,U_64 x_flag)300 Ethread_cancel(bool now, U_64 x_flag) : Egeneric("", now ? dar_gettext("Thread cancellation requested, aborting as soon as possible") : dar_gettext("Thread cancellation requested, aborting as properly as possible")) { immediate = now; flag = x_flag; }; 301 immediate_cancel() const302 bool immediate_cancel() const { return immediate; }; get_flag() const303 U_64 get_flag() const { return flag; }; 304 305 protected: exceptionID() const306 std::string exceptionID() const { return "THREAD CANCELLATION REQUESTED, ABORTING"; }; 307 308 private: 309 bool immediate; 310 U_64 flag; 311 }; 312 313 /// exception used to carry system error 314 315 class Esystem : public Egeneric 316 { 317 public: 318 enum io_error 319 { 320 io_exist, //< file already exists (write mode) 321 io_absent, //< file does not exist (read mode) 322 io_access //< permission denied (any mode) 323 }; 324 325 Esystem(const std::string & source, const std::string & message, io_error code); 326 get_code() const327 io_error get_code() const { return x_code; }; 328 329 protected: exceptionID() const330 virtual std::string exceptionID() const { return "SYSTEM ERROR MET"; }; 331 332 private: 333 io_error x_code; 334 }; 335 336 337 /// @} 338 339 } // end of namespace 340 341 #endif 342