contrib/mul/mbl/mbl_exception.h
Go to the documentation of this file.
00001 #ifndef mbl_exception_h_
00002 #define mbl_exception_h_
00003 //:
00004 // \file
00005 // \brief Exceptions thrown by mbl, and a mechanism for turning them off.
00006 // \author Ian Scott.
00007 
00008 #include <vcl_string.h>
00009 #include <vcl_cstdlib.h>
00010 #include <vcl_iostream.h>
00011 #if VCL_HAS_EXCEPTIONS
00012 # include <vcl_stdexcept.h>
00013 #endif
00014 
00015 
00016 //: Throw an exception indicating a real problem.
00017 // If exceptions have been disabled, this function
00018 // may abort.
00019 template <class T>
00020 void mbl_exception_error(T exception)
00021 {
00022   vcl_cerr << "\nERROR: " << exception.what() << vcl_endl;
00023 #if !defined MBL_EXCEPTIONS_DISABLE  && VCL_HAS_EXCEPTIONS
00024   throw exception;
00025 #else
00026   vcl_abort();
00027 #endif
00028 }
00029 
00030 //: Throw an exception indicating a potential problem.
00031 // If exceptions have been disabled, this function
00032 // may return.
00033 template <class T>
00034 void mbl_exception_warning(T exception)
00035 {
00036   vcl_cerr << "\nWARNING: " << exception.what() << vcl_endl;
00037 #if !defined MBL_EXCEPTIONS_DISABLE  && VCL_HAS_EXCEPTIONS
00038   throw exception;
00039 #endif
00040 }
00041 
00042 
00043 #if !VCL_HAS_EXCEPTIONS
00044 
00045   //: Indicates that mbl_cloneables_factory has not heard of value name.
00046   class mbl_exception_no_name_in_factory
00047   {
00048     vcl_string msg_;
00049    public:
00050     mbl_exception_no_name_in_factory(vcl_string failed_name, vcl_string valid_names)
00051       : msg_(vcl_string("No such value: ")+failed_name+"\nValid values are: ["+valid_names+"]") {}
00052     const char * what() const {return msg_.c_str();}
00053   };
00054 
00055 #else
00056 
00057   //: Indicates that mbl_cloneables_factory has not heard of value name.
00058   class mbl_exception_no_name_in_factory : public vcl_logic_error
00059   {
00060    public:
00061     vcl_string failed_value, valid_values;
00062     mbl_exception_no_name_in_factory(const vcl_string& failed_name, const vcl_string& valid_names):
00063       vcl_logic_error(vcl_string("No such value: ") +failed_name + "\nValid values are: ["+valid_names+"]"),
00064         failed_value(failed_name), valid_values(valid_names) {}
00065     virtual ~mbl_exception_no_name_in_factory() throw() {}
00066   };
00067 
00068 #endif
00069 
00070 
00071 #if !VCL_HAS_EXCEPTIONS
00072 
00073   //: General purpose - a replacement for vcl_abort.
00074   // The only point of catching this exception, is to
00075   // give you a chance to save your data. If this exception
00076   // is thrown, then the program correctness is in doubt.
00077   class mbl_exception_abort
00078   {
00079     vcl_string msg_;
00080    public:
00081     mbl_exception_abort(const vcl_string& comment);
00082     const char * what() const {return msg_.c_str();}
00083   };
00084 
00085 #else
00086 
00087   //: General purpose - a replacement for vcl_abort.
00088   // The only point of catching this exception, is to
00089   // give you a chance to save your data. If this exception
00090   // is thrown, then the program correctness is in doubt.
00091   class mbl_exception_abort : public vcl_logic_error
00092   {
00093    public:
00094     mbl_exception_abort(const vcl_string& comment);
00095     virtual ~mbl_exception_abort() throw() {}
00096   };
00097 
00098 #endif
00099 
00100 
00101 #if !VCL_HAS_EXCEPTIONS
00102 
00103   //: Indicates a problem whilst parsing text configuration data.
00104   class mbl_exception_parse_error
00105   {
00106     vcl_string msg_;
00107    public:
00108     mbl_exception_parse_error(const vcl_string &msg)
00109       : msg_(msg) {}
00110     const char * what() const {return msg_.c_str();}
00111   };
00112 
00113 #else
00114 
00115   //: Indicates a problem whilst parsing text configuration data.
00116   class mbl_exception_parse_error: public vcl_runtime_error
00117   {
00118    public:
00119     mbl_exception_parse_error(const vcl_string &msg)
00120       : vcl_runtime_error(msg) {}
00121     virtual ~mbl_exception_parse_error() throw() {}
00122   };
00123 
00124 #endif
00125 
00126 #if !VCL_HAS_EXCEPTIONS
00127 
00128   //: Indicates a problem whilst parsing a file.
00129   class mbl_exception_parse_file_error
00130   {
00131     vcl_string msg_;
00132     vcl_string filename_;
00133    public:
00134      mbl_exception_parse_file_error(const vcl_string &msg, const vcl_string& filename)
00135       : msg_(msg+" "+filename), filename_(filename) {}
00136     const char * what() const {return msg_.c_str();}
00137     const char * filename() const {return filename_.c_str();}
00138   };
00139 
00140 #else
00141 
00142   //: Indicates a problem whilst parsing a file.
00143   class mbl_exception_parse_file_error: public mbl_exception_parse_error
00144   {
00145     vcl_string filename_;
00146    public:
00147      mbl_exception_parse_file_error(const vcl_string &msg, const vcl_string& filename):
00148        mbl_exception_parse_error(filename.empty() ? msg : msg+" in "+filename), filename_(filename) {}
00149     const char * filename() const {return filename_.c_str();}
00150     virtual ~mbl_exception_parse_file_error() throw() {}
00151   };
00152 
00153 #endif
00154 
00155 #if !VCL_HAS_EXCEPTIONS
00156 
00157   //: Data from two sources or files was inconsistent.
00158   class mbl_exception_inconsistent_external_data
00159   {
00160     vcl_string msg_;
00161     vcl_string source1_, source2_;
00162    public:
00163      mbl_exception_inconsistent_external_data(const vcl_string &msg,
00164        const vcl_string& source1, const vcl_string& source2)
00165       : msg_(source1.empty() && source2.empty() ? msg : msg+" between "+source1+" and "+source2),
00166         source1_(source1), source2_(source2) {}
00167     const char * what() const {return msg_.c_str();}
00168     const char * source1() const {return source1_.c_str();}
00169     const char * source2() const {return source2_.c_str();}
00170   };
00171 
00172 #else
00173 
00174   //: Data from two sources or files was inconsistent.
00175   // This is distinct from a parse error, which can be used when the data within
00176   // in a single config file is inconsistent. This is most useful at algorithm run time,
00177   // when there are several external data files, and some external agent has broken the
00178   // consistency invariant by modifying one of them. The application can then report that
00179   // someone has messed up its data.
00180   class mbl_exception_inconsistent_external_data: public vcl_runtime_error
00181   {
00182     vcl_string source1_, source2_;
00183    public:
00184     mbl_exception_inconsistent_external_data(const vcl_string &msg,
00185       const vcl_string& source1 = "", const vcl_string& source2 = "")
00186       : vcl_runtime_error( source1.empty() && source2.empty()
00187           ? msg : msg+" between "+source1+" and "+source2),
00188         source1_(source1), source2_(source2) {}
00189     const char * source1() const {return source1_.c_str();}
00190     const char * source2() const {return source2_.c_str();}
00191     virtual ~mbl_exception_inconsistent_external_data() throw() {}
00192   };
00193 
00194 #endif
00195 
00196 
00197 #if !VCL_HAS_EXCEPTIONS
00198 
00199   //: Indicates that an expected property label was missing.
00200   class mbl_exception_missing_property
00201   {
00202     vcl_string msg_;
00203    public:
00204     mbl_exception_missing_property(const vcl_string &missing)
00205       : msg_(vcl_string("Couldn't find expected property label: \""+missing+'\"')) {}
00206     const char * what() const {return msg_.c_str();}
00207   };
00208 
00209 #else
00210 
00211   //: Indicates a problem whilst parsing text configuration data.
00212   class mbl_exception_missing_property: public mbl_exception_parse_error
00213   {
00214    public:
00215    vcl_string missing_label;
00216     mbl_exception_missing_property(const vcl_string &missing)
00217       : mbl_exception_parse_error(
00218           vcl_string("Couldn't find expected property label: \""+missing+'\"')),
00219         missing_label(missing)
00220     {}
00221     virtual ~mbl_exception_missing_property() throw() {}
00222   };
00223 
00224 #endif
00225 
00226 #if !VCL_HAS_EXCEPTIONS
00227 
00228   //: Indicates that mbl_exception_look_for_unused_props found some unused properties.
00229   class mbl_exception_unused_props
00230   {
00231     vcl_string msg_;
00232    public:
00233     mbl_exception_unused_props(const vcl_string &function_name, const vcl_string &unused_props)
00234       : msg_(function_name + ": Unused properties found:\n" + unused_props) {}
00235     const char * what() const {return msg_.c_str();}
00236   };
00237 
00238 #else
00239 
00240   //: Indicates that mbl_exception_look_for_unused_props found some unused properties.
00241   class mbl_exception_unused_props : public mbl_exception_parse_error
00242   {
00243    public:
00244     vcl_string function_name, unused_properties;
00245     mbl_exception_unused_props(const vcl_string &fn_name, const vcl_string &unused_props)
00246       : mbl_exception_parse_error(fn_name + ": Unused properties found:\n" + unused_props),
00247         function_name(fn_name), unused_properties(unused_props) {}
00248     virtual ~mbl_exception_unused_props() throw() {}
00249   };
00250 
00251 #endif
00252 
00253 
00254 #if !VCL_HAS_EXCEPTIONS
00255 
00256   //: Indicates a problem whilst parsing text configuration data into an mbl_read_props object.
00257   class mbl_exception_read_props_parse_error
00258   {
00259     vcl_string msg_;
00260    public:
00261     mbl_exception_read_props_parse_error(const vcl_string &msg)
00262       : msg_(vcl_string("mbl_read_props: ") + msg) {}
00263     const char * what() const {return msg_.c_str();}
00264   };
00265 
00266 #else
00267 
00268   //: Indicates a problem whilst parsing text configuration data into an mbl_read_props object.
00269   class mbl_exception_read_props_parse_error: public mbl_exception_parse_error
00270   {
00271    public:
00272     mbl_exception_read_props_parse_error(const vcl_string &msg)
00273       : mbl_exception_parse_error(vcl_string("mbl_read_props: ") + msg) {}
00274     virtual ~mbl_exception_read_props_parse_error() throw() {}
00275   };
00276 
00277 #endif
00278 
00279 #if !VCL_HAS_EXCEPTIONS
00280 
00281   //: Indicates a problem whilst parsing a block of text configuration data.
00282   class mbl_exception_parse_block_parse_error
00283   {
00284     vcl_string msg_;
00285    public:
00286     mbl_exception_parse_block_parse_error(const vcl_string &msg,
00287       const vcl_string &contents)
00288     : msg_(vcl_string("mbl_parse_block: ") + msg +
00289       "Contents of block:\n" + contents) {}
00290     const char * what() const {return msg_.c_str();}
00291   };
00292 
00293 #else
00294 
00295   //: Indicates a problem whilst parsing a block of text configuration data.
00296   class mbl_exception_parse_block_parse_error: public mbl_exception_parse_error
00297   {
00298    public:
00299     //: Description of problem
00300     vcl_string msg;
00301     //: Contents of string which failed to be parsed.
00302     vcl_string contents;
00303     mbl_exception_parse_block_parse_error(const vcl_string &msg,
00304       const vcl_string &contents)
00305     : mbl_exception_parse_error(vcl_string("mbl_parse_block: ") + msg +
00306       "Contents of block:\n" + contents), msg(msg), contents(contents) {}
00307     virtual ~mbl_exception_parse_block_parse_error() throw() {}
00308   };
00309 
00310 #endif
00311 
00312 //:Throw mbl_exception_os_error or one of its derivatives, based on errno.
00313 // If exceptions are disabled, this behaves like mbl_exception_warning() above.
00314 void mbl_exception_throw_os_error(const vcl_string& filename,
00315                                   const vcl_string& additional_comment="");
00316 
00317 
00318 #if !VCL_HAS_EXCEPTIONS
00319 
00320   //: Indicates a problem reported during an OS call.
00321   class mbl_exception_os_error
00322   {
00323     vcl_string msg_;
00324    public:
00325     //: Reported errno
00326     int errno;
00327     //: System supplied error message.
00328     vcl_string error_message;
00329     //: Filename or pathname or other id on which OS call failed.
00330     vcl_string filename;
00331     //: Optional additional comments.
00332     vcl_string additional_comment;
00333     mbl_exception_os_error(int err_no, const vcl_string &file_name,
00334       const vcl_string &comment="");
00335     virtual ~mbl_exception_os_error() throw() {}
00336     const char * what() const {return msg_.c_str();}
00337   };
00338 
00339 #else
00340 
00341   //: Indicates a problem reported during an OS call.
00342   class mbl_exception_os_error: public vcl_runtime_error
00343   {
00344    public:
00345     //: Reported errno
00346     int err_no;
00347     //: System supplied error message.
00348     vcl_string error_message;
00349     //: Filename or pathname or other id on which OS call failed.
00350     vcl_string filename;
00351     //: Optional additional comments.
00352     vcl_string additional_comment;
00353     mbl_exception_os_error(int errnum, const vcl_string &file_name,
00354       const vcl_string &comment="");
00355     virtual ~mbl_exception_os_error() throw() {}
00356   };
00357 
00358 #endif
00359 
00360 
00361 #define MACRO( E ) \
00362 class E : public mbl_exception_os_error{ public: \
00363   E (int err_no, const vcl_string &file_name, const vcl_string &comment=""): \
00364     mbl_exception_os_error(err_no, file_name, comment) {} }
00365 
00366 MACRO(mbl_exception_os_no_such_file_or_directory);
00367 MACRO(mbl_exception_os_permission_denied);
00368 MACRO(mbl_exception_os_file_exists);
00369 MACRO(mbl_exception_os_not_a_directory);
00370 MACRO(mbl_exception_os_is_a_directory);
00371 MACRO(mbl_exception_os_no_space_left_on_device);
00372 MACRO(mbl_exception_os_invalid_value);
00373 
00374 #undef MACRO
00375 
00376 #endif // mbl_exception_h_
00377