1.1 --- a/src/work/klao/error.h Thu Feb 03 16:08:56 2005 +0000
1.2 +++ b/src/work/klao/error.h Thu Feb 03 19:24:42 2005 +0000
1.3 @@ -102,99 +102,112 @@
1.4 * Base class for exceptions used in LEMON.
1.5 */
1.6 class Exception : public std::exception {
1.7 - protected:
1.8 - ///\e
1.9 - const char *message;
1.10 -
1.11 public:
1.12 ///\e
1.13 - Exception() throw() : message(0) {}
1.14 - ///\e
1.15 - explicit Exception(const char *msg) throw()
1.16 - : message(msg) {}
1.17 + Exception() {}
1.18 ///\e
1.19 virtual ~Exception() throw() {}
1.20 +
1.21 + ///\e
1.22 + virtual const char* exceptionName() const {
1.23 + return "lemon::Exception";
1.24 + }
1.25
1.26 ///\e
1.27 virtual const char* what() const throw() {
1.28 - if( message ) return message;
1.29 - return "lemon::Exception";
1.30 + return exceptionName();
1.31 }
1.32 };
1.33
1.34 - ///\e
1.35 + /**
1.36 + * \brief One of the two main subclasses of \ref Exception.
1.37 + *
1.38 + * Logic errors represent problems in the internal logic of a program;
1.39 + * in theory, these are preventable, and even detectable before the
1.40 + * program runs (e.g., violations of class invariants).
1.41 + *
1.42 + * For a typical example \see UninitializedParameterError.
1.43 + */
1.44 class LogicError : public Exception {
1.45 public:
1.46 - ///\e
1.47 - explicit LogicError() {}
1.48 - ///\e
1.49 - explicit LogicError(const char *s)
1.50 - : Exception(s) {}
1.51 + virtual const char* exceptionName() const {
1.52 + return "lemon::LogicError";
1.53 + }
1.54 };
1.55
1.56 - ///\e
1.57 +
1.58 + /**
1.59 + * \brief One of the two main subclasses of \ref Exception.
1.60 + *
1.61 + * Runtime errors represent problems outside the scope of a program;
1.62 + * they cannot be easily predicted and can generally only be caught as
1.63 + * the program executes.
1.64 + */
1.65 class RuntimeError : public Exception {
1.66 public:
1.67 - ///\e
1.68 - explicit RuntimeError() {}
1.69 - ///\e
1.70 - explicit RuntimeError(const char *s)
1.71 - : Exception(s) {}
1.72 + virtual const char* exceptionName() const {
1.73 + return "lemon::RuntimeError";
1.74 + }
1.75 };
1.76
1.77 ///\e
1.78 class RangeError : public RuntimeError {
1.79 public:
1.80 - ///\e
1.81 - explicit RangeError(const char *s)
1.82 - : RuntimeError(s) {}
1.83 + virtual const char* exceptionName() const {
1.84 + return "lemon::RangeError";
1.85 + }
1.86 };
1.87
1.88 ///\e
1.89 class IOError : public RuntimeError {
1.90 public:
1.91 - ///\e
1.92 - explicit IOError(const char *s)
1.93 - : RuntimeError(s) {}
1.94 + virtual const char* exceptionName() const {
1.95 + return "lemon::IOError";
1.96 + }
1.97 };
1.98
1.99 ///\e
1.100 class DataFormatError : public IOError {
1.101 protected:
1.102 - int line;
1.103 - boost::shared_ptr<std::string> file;
1.104 + const char *_message;
1.105 + int _line;
1.106 + boost::shared_ptr<std::string> _file;
1.107
1.108 public:
1.109 ///\e
1.110 - explicit DataFormatError(const char *message)
1.111 - : IOError(message), line(0) {}
1.112 + explicit DataFormatError(const char *the_message)
1.113 + : _message(the_message), _line(0) {}
1.114 ///\e
1.115 DataFormatError(const std::string &file_name, int line_num,
1.116 - const char *message)
1.117 - : IOError(message), line(line_num) { set_file(file_name); }
1.118 + const char *the_message)
1.119 + : _message(the_message), _line(line_num) { file(file_name); }
1.120
1.121 ///\e
1.122 - void set_line(int line_num) { line=line_num; }
1.123 + void line(int line_num) { _line=line_num; }
1.124 ///\e
1.125 - void set_file(const std::string &file_name) {
1.126 + void message(char *the_message) { _message=the_message; }
1.127 + ///\e
1.128 + void file(const std::string &file_name) {
1.129 try {
1.130 - file.reset(new std::string);
1.131 - *file = file_name;
1.132 + _file.reset(new std::string);
1.133 + *_file = file_name;
1.134 }
1.135 catch(...) {
1.136 - file.reset();
1.137 + _file.reset();
1.138 }
1.139 }
1.140
1.141 ///\e
1.142 - int get_line() const { return line; }
1.143 + int line() const { return _line; }
1.144 + ///\e
1.145 + const char* message() const { return _message; }
1.146
1.147 /// \brief Returns the filename.
1.148 ///
1.149 /// Returns \e "(unknown)" if the filename was not specified.
1.150 - const char* get_file() const {
1.151 - if( file )
1.152 - return file->c_str();
1.153 + const char* file() const {
1.154 + if( _file )
1.155 + return _file->c_str();
1.156 else
1.157 return "(unknown)";
1.158 }
1.159 @@ -204,18 +217,22 @@
1.160 const char *mes = 0;
1.161 try {
1.162 std::ostringstream ostr;
1.163 - ostr << IOError::what();
1.164 - if( file || line ) {
1.165 + ostr << _message;
1.166 + if( _file || _line ) {
1.167 ostr << " (";
1.168 - if( file ) ostr << "in file '" << *file << "'";
1.169 - if( file && line ) ostr << " ";
1.170 - if( line ) ostr << "at line " << line;
1.171 + if( _file ) ostr << "in file '" << *_file << "'";
1.172 + if( _file && _line ) ostr << " ";
1.173 + if( _line ) ostr << "at line " << _line;
1.174 ostr << ")";
1.175 }
1.176 mes = ostr.str().c_str();
1.177 }
1.178 catch(...) {}
1.179 if( mes ) return mes;
1.180 + return exceptionName();
1.181 + }
1.182 +
1.183 + virtual const char* exceptionName() const {
1.184 return "lemon::DataFormatError";
1.185 }
1.186
1.187 @@ -264,6 +281,10 @@
1.188 }
1.189 catch(...) {}
1.190 if( mes ) return mes;
1.191 + return exceptionName();
1.192 + }
1.193 +
1.194 + virtual const char* exceptionName() const {
1.195 return "lemon::AssertionFailedError";
1.196 }
1.197
1.198 @@ -311,7 +332,11 @@
1.199 #endif
1.200
1.201 #ifndef LEMON_ASSERT_HANDLER
1.202 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
1.203 +# ifdef LEMON_ASSERT_EXCEPTION
1.204 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
1.205 +# else
1.206 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
1.207 +# endif
1.208 #endif
1.209
1.210 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
1.211 @@ -323,6 +348,18 @@
1.212 /**
1.213 * \brief Macro for assertions with customizable message
1.214 *
1.215 + * Macro for assertions with customizable message.
1.216 + *
1.217 + * The behaviour can be customized with LEMON_ASSERT_HANDLER,
1.218 + * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
1.219 + * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
1.220 + *
1.221 + * \todo We should provide some way to reset to the default behaviour,
1.222 + * shouldn't we?
1.223 + *
1.224 + * \todo This whole 'assert' business should be placed in a separate
1.225 + * include file.
1.226 + *
1.227 * \todo __PRETTY_FUNCTION__ should be replaced by something
1.228 * compiler-independant, like BOOST_CURRENT_FUNCTION
1.229 */
1.230 @@ -333,7 +370,7 @@
1.231 __PRETTY_FUNCTION__, \
1.232 (msg), #exp, LEMON_ASSERT_ABORT), 0)))
1.233
1.234 -# endif // NDEBUG
1.235 +#endif // NDEBUG || LEMON_DISABLE_ASSERTS
1.236
1.237 /**
1.238 * \brief Macro for mark not yet implemented features.
2.1 --- a/src/work/klao/error_test.cc Thu Feb 03 16:08:56 2005 +0000
2.2 +++ b/src/work/klao/error_test.cc Thu Feb 03 19:24:42 2005 +0000
2.3 @@ -15,8 +15,8 @@
2.4 parse_line();
2.5 }
2.6 catch(lemon::DataFormatError &e) {
2.7 - e.set_file(fn);
2.8 - e.set_line(5);
2.9 + e.file(fn);
2.10 + e.line(5);
2.11 throw;
2.12 }
2.13 }
2.14 @@ -27,26 +27,47 @@
2.15 try {
2.16 parse_file("input.txt");
2.17 }
2.18 + catch(lemon::Exception &e) {
2.19 + cerr << "Exception '" << e.exceptionName()
2.20 + << "' caught: " << endl;
2.21 + cerr << e.what() << endl;
2.22 + }
2.23 catch(exception &e) {
2.24 cerr << "Exception caught: " << endl;
2.25 cerr << e.what() << endl;
2.26 }
2.27
2.28 try {
2.29 + throw lemon::LogicError();
2.30 + }
2.31 + catch(lemon::Exception &e) {
2.32 + cerr << "Exception '" << e.exceptionName()
2.33 + << "' caught: " << endl;
2.34 + cerr << e.what() << endl;
2.35 + }
2.36 +
2.37 + try {
2.38 fail_assert();
2.39 }
2.40 + catch(lemon::Exception &e) {
2.41 + cerr << "Exception '" << e.exceptionName()
2.42 + << "' caught: " << endl;
2.43 + cerr << e.what() << endl;
2.44 + }
2.45 catch(exception &e) {
2.46 cerr << "Exception caught: " << endl;
2.47 cerr << e.what() << endl;
2.48 }
2.49
2.50 + cerr << endl;
2.51 +
2.52 // assert(1==0);
2.53 LEMON_ASSERT(1==0, "Ellentmondas");
2.54 LEMON_FIXME("Nincs kesz");
2.55 }
2.56
2.57 #undef LEMON_ASSERT_HANDLER
2.58 -#define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
2.59 +#define LEMON_ASSERT_EXCEPTION
2.60
2.61 #include <error.h>
2.62