src/work/klao/error.h
changeset 1120 5d8d64bde9c5
parent 1068 e0b0dcee5e17
equal deleted inserted replaced
3:93f2408b4f12 4:ceb03fda6d91
   100    * \brief Generic exception class.
   100    * \brief Generic exception class.
   101    *
   101    *
   102    * Base class for exceptions used in LEMON.
   102    * Base class for exceptions used in LEMON.
   103    */
   103    */
   104   class Exception : public std::exception {
   104   class Exception : public std::exception {
   105   protected:
   105   public:
   106     ///\e
   106     ///\e 
   107     const char *message;
   107     Exception() {}
   108 
       
   109   public:
       
   110     ///\e 
       
   111     Exception() throw() : message(0) {}
       
   112     ///\e 
       
   113     explicit Exception(const char *msg) throw()
       
   114       : message(msg) {}
       
   115     ///\e 
   108     ///\e 
   116     virtual ~Exception() throw() {}
   109     virtual ~Exception() throw() {}
       
   110 
       
   111     ///\e
       
   112     virtual const char* exceptionName() const {
       
   113       return "lemon::Exception";
       
   114     }
   117     
   115     
   118     ///\e 
   116     ///\e 
   119     virtual const char* what() const throw() {
   117     virtual const char* what() const throw() {
   120       if( message ) return message;
   118       return exceptionName();
   121       return "lemon::Exception";
   119     }
   122     }
   120   };
   123   };
   121 
   124 
   122   /**
   125   ///\e 
   123    * \brief One of the two main subclasses of \ref Exception.
       
   124    *
       
   125    * Logic errors represent problems in the internal logic of a program;
       
   126    * in theory, these are preventable, and even detectable before the
       
   127    * program runs (e.g., violations of class invariants).
       
   128    *
       
   129    * For a typical example \see UninitializedParameterError.
       
   130    */
   126   class LogicError : public Exception {
   131   class LogicError : public Exception {
   127   public:
   132   public:
   128     ///\e 
   133     virtual const char* exceptionName() const {
   129     explicit LogicError() {}
   134       return "lemon::LogicError";
   130     ///\e 
   135     }
   131     explicit LogicError(const char *s)
   136   };
   132       : Exception(s) {}
   137 
   133   };
   138   
   134 
   139   /**
   135   ///\e 
   140    * \brief One of the two main subclasses of \ref Exception.
       
   141    *
       
   142    * Runtime errors represent problems outside the scope of a program;
       
   143    * they cannot be easily predicted and can generally only be caught as
       
   144    * the program executes.
       
   145    */
   136   class RuntimeError : public Exception {
   146   class RuntimeError : public Exception {
   137   public:
   147   public:
   138     ///\e
   148     virtual const char* exceptionName() const {
   139     explicit RuntimeError() {}
   149       return "lemon::RuntimeError";
   140     ///\e
   150     }
   141     explicit RuntimeError(const char *s)
       
   142       : Exception(s) {}
       
   143   };
   151   };
   144 
   152 
   145   ///\e
   153   ///\e
   146   class RangeError : public RuntimeError {
   154   class RangeError : public RuntimeError {
   147   public:
   155   public:
   148     ///\e 
   156     virtual const char* exceptionName() const {
   149     explicit RangeError(const char *s)
   157       return "lemon::RangeError";
   150       : RuntimeError(s) {}
   158     }
   151   };
   159   };
   152 
   160 
   153   ///\e 
   161   ///\e 
   154   class IOError : public RuntimeError {
   162   class IOError : public RuntimeError {
   155   public:
   163   public:
   156     ///\e 
   164     virtual const char* exceptionName() const {
   157     explicit IOError(const char *s)
   165       return "lemon::IOError";
   158       : RuntimeError(s) {}
   166     }
   159   };
   167   };
   160 
   168 
   161   ///\e 
   169   ///\e 
   162   class DataFormatError : public IOError {
   170   class DataFormatError : public IOError {
   163   protected:
   171   protected:
   164     int line;
   172     const char *_message;
   165     boost::shared_ptr<std::string> file;
   173     int _line;
   166 
   174     boost::shared_ptr<std::string> _file;
   167   public:
   175 
   168     ///\e 
   176   public:
   169     explicit DataFormatError(const char *message)
   177     ///\e 
   170       : IOError(message), line(0) {}
   178     explicit DataFormatError(const char *the_message)
       
   179       : _message(the_message), _line(0) {}
   171     ///\e 
   180     ///\e 
   172     DataFormatError(const std::string &file_name, int line_num,
   181     DataFormatError(const std::string &file_name, int line_num,
   173 		    const char *message)
   182 		    const char *the_message)
   174       : IOError(message), line(line_num) { set_file(file_name); }
   183       : _message(the_message), _line(line_num) { file(file_name); }
   175 
   184 
   176     ///\e 
   185     ///\e 
   177     void set_line(int line_num) { line=line_num; }
   186     void line(int line_num) { _line=line_num; }
   178     ///\e 
   187     ///\e 
   179     void set_file(const std::string &file_name) {
   188     void message(char *the_message) { _message=the_message; }
   180       try {
   189     ///\e 
   181 	file.reset(new std::string);
   190     void file(const std::string &file_name) {
   182 	*file = file_name;
   191       try {
       
   192 	_file.reset(new std::string);
       
   193 	*_file = file_name;
   183       }
   194       }
   184       catch(...) {
   195       catch(...) {
   185 	file.reset();
   196 	_file.reset();
   186       }
   197       }
   187     }
   198     }
   188 
   199 
   189     ///\e
   200     ///\e
   190     int get_line() const { return line; }
   201     int line() const { return _line; }
       
   202     ///\e
       
   203     const char* message() const { return _message; }
   191 
   204 
   192     /// \brief Returns the filename.
   205     /// \brief Returns the filename.
   193     ///
   206     ///
   194     /// Returns \e "(unknown)" if the filename was not specified.
   207     /// Returns \e "(unknown)" if the filename was not specified.
   195     const char* get_file() const {
   208     const char* file() const {
   196       if( file )
   209       if( _file )
   197 	return file->c_str();
   210 	return _file->c_str();
   198       else
   211       else
   199 	return "(unknown)";
   212 	return "(unknown)";
   200     }
   213     }
   201 
   214 
   202     ///\e 
   215     ///\e 
   203     virtual const char* what() const throw() {
   216     virtual const char* what() const throw() {
   204       const char *mes = 0;
   217       const char *mes = 0;
   205       try {
   218       try {
   206 	std::ostringstream ostr;
   219 	std::ostringstream ostr;
   207 	ostr << IOError::what();
   220 	ostr << _message;
   208 	if( file || line ) {
   221 	if( _file || _line ) {
   209 	  ostr << " (";
   222 	  ostr << " (";
   210 	  if( file ) ostr << "in file '" << *file << "'";
   223 	  if( _file ) ostr << "in file '" << *_file << "'";
   211 	  if( file && line ) ostr << " ";
   224 	  if( _file && _line ) ostr << " ";
   212 	  if( line ) ostr << "at line " << line;
   225 	  if( _line ) ostr << "at line " << _line;
   213 	  ostr << ")";
   226 	  ostr << ")";
   214 	}
   227 	}
   215 	mes = ostr.str().c_str();
   228 	mes = ostr.str().c_str();
   216       }
   229       }
   217       catch(...) {}
   230       catch(...) {}
   218       if( mes ) return mes;
   231       if( mes ) return mes;
       
   232       return exceptionName();
       
   233     }
       
   234 
       
   235     virtual const char* exceptionName() const {
   219       return "lemon::DataFormatError";
   236       return "lemon::DataFormatError";
   220     }
   237     }
   221 
   238 
   222     virtual ~DataFormatError() throw() {}
   239     virtual ~DataFormatError() throw() {}
   223   };
   240   };
   262 	  ostr << " (assertion '" << assertion << "' failed)";
   279 	  ostr << " (assertion '" << assertion << "' failed)";
   263 	mes = ostr.str().c_str();
   280 	mes = ostr.str().c_str();
   264       }
   281       }
   265       catch(...) {}
   282       catch(...) {}
   266       if( mes ) return mes;
   283       if( mes ) return mes;
       
   284       return exceptionName();
       
   285     }
       
   286 
       
   287     virtual const char* exceptionName() const {
   267       return "lemon::AssertionFailedError";
   288       return "lemon::AssertionFailedError";
   268     }
   289     }
   269 
   290 
   270     virtual ~AssertionFailedError() throw() {}
   291     virtual ~AssertionFailedError() throw() {}
   271   };
   292   };
   309 #ifndef LEMON_ASSERT_ABORT
   330 #ifndef LEMON_ASSERT_ABORT
   310 #  define LEMON_ASSERT_ABORT 1
   331 #  define LEMON_ASSERT_ABORT 1
   311 #endif
   332 #endif
   312 
   333 
   313 #ifndef LEMON_ASSERT_HANDLER
   334 #ifndef LEMON_ASSERT_HANDLER
   314 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail
   335 #  ifdef LEMON_ASSERT_EXCEPTION
       
   336 #    define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
       
   337 #  else
       
   338 #    define LEMON_ASSERT_HANDLER ::lemon::assert_fail
       
   339 #  endif
   315 #endif
   340 #endif
   316 
   341 
   317 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
   342 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
   318 
   343 
   319 #  define LEMON_ASSERT(exp, msg)  (static_cast<void> (0))
   344 #  define LEMON_ASSERT(exp, msg)  (static_cast<void> (0))
   320 
   345 
   321 #else
   346 #else
   322 
   347 
   323 /**
   348 /**
   324  * \brief Macro for assertions with customizable message
   349  * \brief Macro for assertions with customizable message
       
   350  *
       
   351  * Macro for assertions with customizable message.
       
   352  *
       
   353  * The behaviour can be customized with LEMON_ASSERT_HANDLER,
       
   354  * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
       
   355  * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
       
   356  *
       
   357  * \todo We should provide some way to reset to the default behaviour,
       
   358  * shouldn't we?
       
   359  *
       
   360  * \todo This whole 'assert' business should be placed in a separate
       
   361  * include file.
   325  *
   362  *
   326  * \todo __PRETTY_FUNCTION__ should be replaced by something
   363  * \todo __PRETTY_FUNCTION__ should be replaced by something
   327  * compiler-independant, like BOOST_CURRENT_FUNCTION
   364  * compiler-independant, like BOOST_CURRENT_FUNCTION
   328  */
   365  */
   329 
   366 
   331      (static_cast<void> (!!(exp) ? 0 : (         \
   368      (static_cast<void> (!!(exp) ? 0 : (         \
   332        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
   369        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
   333                             __PRETTY_FUNCTION__, \
   370                             __PRETTY_FUNCTION__, \
   334 			    (msg), #exp, LEMON_ASSERT_ABORT), 0)))
   371 			    (msg), #exp, LEMON_ASSERT_ABORT), 0)))
   335 
   372 
   336 # endif // NDEBUG
   373 #endif // NDEBUG || LEMON_DISABLE_ASSERTS
   337 
   374 
   338 /**
   375 /**
   339  * \brief Macro for mark not yet implemented features.
   376  * \brief Macro for mark not yet implemented features.
   340  *
   377  *
   341  * \todo Is this the right place for this? It should be used only in
   378  * \todo Is this the right place for this? It should be used only in