Changeset 1067:47939f501c81 in lemon-0.x for src/work/klao/error.h
- Timestamp:
- 01/10/05 00:28:18 (20 years ago)
- Branch:
- default
- Phase:
- public
- Convert:
- svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1463
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/work/klao/error.h
r1061 r1067 20 20 //! \ingroup misc 21 21 //! \file 22 //! \brief Basic e rror handling (signaling) routines.22 //! \brief Basic exception classes and error handling. 23 23 24 24 #include <exception> 25 25 #include <string> 26 26 #include <sstream> 27 #include <iostream> 28 #include <cstdlib> 27 29 28 30 #include <boost/shared_ptr.hpp> … … 31 33 32 34 /// Exception-safe convenient "error message" class. 35 36 /// Helper class which provides a convenient ostream-like (operator << 37 /// based) interface to create a string message. Mostly useful in 38 /// exception classes (therefore the name). 33 39 class ErrorMessage { 34 40 protected: 35 ///\e41 ///\e 36 42 boost::shared_ptr<std::ostringstream> buf; 37 43 38 ///\e44 ///\e 39 45 bool init() throw() { 40 46 try { … … 49 55 public: 50 56 51 ///\e57 ///\e 52 58 ErrorMessage() throw() { init(); } 53 59 54 ///\e60 ///\e 55 61 ErrorMessage(const char *message) throw() { 56 62 init(); … … 58 64 } 59 65 60 ///\e66 ///\e 61 67 ErrorMessage(const std::string &message) throw() { 62 68 init(); … … 64 70 } 65 71 66 ///\e72 ///\e 67 73 template <typename T> 68 74 ErrorMessage& operator<<(const T &t) throw() { … … 77 83 } 78 84 79 ///\e85 ///\e 80 86 const char* message() throw() { 81 87 if( !buf ) return 0; … … 96 102 * Base class for exceptions used in LEMON. 97 103 */ 98 class Exception : public std::exception, public ErrorMessage { 99 public: 100 ///\e 101 Exception() throw() {} 102 ///\e 103 explicit Exception(const std::string &s) throw() 104 : ErrorMessage(s) {} 105 ///\e 104 class Exception : public std::exception { 105 protected: 106 ///\e 107 const char *message; 108 109 public: 110 ///\e 111 Exception() throw() : message(0) {} 112 ///\e 113 explicit Exception(const char *msg) throw() 114 : message(msg) {} 115 ///\e 106 116 virtual ~Exception() throw() {} 107 117 108 ///\e118 ///\e 109 119 virtual const char* what() const throw() { 110 const char *mes = message(); 111 if( mes ) return mes; 120 if( message ) return message; 112 121 return "lemon::Exception"; 113 122 } … … 116 125 ///\e 117 126 class LogicError : public Exception { 118 ///\e 119 explicit LogicError(const std::string &s) 127 public: 128 ///\e 129 explicit LogicError() {} 130 ///\e 131 explicit LogicError(const char *s) 120 132 : Exception(s) {} 121 133 }; … … 123 135 ///\e 124 136 class RuntimeError : public Exception { 125 ///\e 126 explicit RuntimeError(const std::string &s) 137 public: 138 ///\e 139 explicit RuntimeError() {} 140 ///\e 141 explicit RuntimeError(const char *s) 127 142 : Exception(s) {} 128 143 }; 129 144 130 ///\e 145 ///\e 131 146 class RangeError : public RuntimeError { 132 ///\e 133 explicit RangeError(const std::string &s) 147 public: 148 ///\e 149 explicit RangeError(const char *s) 134 150 : RuntimeError(s) {} 135 151 }; … … 137 153 ///\e 138 154 class IOError : public RuntimeError { 139 ///\e 140 explicit IOError(const std::string &s) 155 public: 156 ///\e 157 explicit IOError(const char *s) 141 158 : RuntimeError(s) {} 142 159 }; … … 144 161 ///\e 145 162 class DataFormatError : public IOError { 146 ///\e 147 explicit DataFormatError(const std::string &message) 148 : IOError(message) : line(0) {} 149 ///\e 163 protected: 164 int line; 165 boost::shared_ptr<std::string> file; 166 167 public: 168 ///\e 169 explicit DataFormatError(const char *message) 170 : IOError(message), line(0) {} 171 ///\e 150 172 DataFormatError(const std::string &file_name, int line_num, 151 const std::string &message)173 const char *message) 152 174 : IOError(message), line(line_num) { set_file(file_name); } 153 175 154 ///\e176 ///\e 155 177 void set_line(int line_num) { line=line_num; } 156 ///\e178 ///\e 157 179 void set_file(const std::string &file_name) { 158 180 try { … … 165 187 } 166 188 167 ///\e 168 virtual const char* what() const { 189 ///\e 190 int get_line() const { return line; } 191 192 /// \brief Returns the filename. 193 /// 194 /// Returns "(unknown)" if the filename was not specified. 195 const char* get_file() const { 196 if( file ) 197 return file->c_str(); 198 else 199 return "(unknown)"; 200 } 201 202 ///\e 203 virtual const char* what() const throw() { 169 204 const char *mes = 0; 170 205 try { … … 173 208 if( file || line ) { 174 209 ostr << " ("; 175 if( file ) ostr << "in file" << *file; 176 if( line ) ostr << " at line" << line; 210 if( file ) ostr << "in file '" << *file << "'"; 211 if( file && line ) ostr << " "; 212 if( line ) ostr << "at line " << line; 213 ostr << ")"; 177 214 } 178 215 mes = ostr.str().c_str(); … … 182 219 return "lemon::DataFormatError"; 183 220 } 184 }; 185 221 222 virtual ~DataFormatError() throw() {} 223 }; 224 225 226 class AssertionFailedError : public LogicError { 227 protected: 228 const char *assertion; 229 const char *file; 230 int line; 231 const char *function; 232 const char *message; 233 public: 234 ///\e 235 AssertionFailedError(const char *_file, int _line, const char *func, 236 const char *msg, const char *_assertion = 0) : 237 assertion(_assertion), file(_file), line(_line), function(func), 238 message(msg) {} 239 240 ///\e 241 const char* get_assertion() const { return assertion; } 242 ///\e 243 const char* get_message() const { return message; } 244 ///\e 245 const char* get_file() const { return file; } 246 ///\e 247 const char* get_function() const { return function; } 248 ///\e 249 int get_line() const { return line; } 250 251 252 virtual const char* what() const throw() { 253 const char *mes = 0; 254 try { 255 std::ostringstream ostr; 256 ostr << file << ":" << line << ": "; 257 if( function ) 258 ostr << function << ": "; 259 ostr << message; 260 if( assertion ) 261 ostr << " (assertion '" << assertion << "' failed)"; 262 mes = ostr.str().c_str(); 263 } 264 catch(...) {} 265 if( mes ) return mes; 266 return "lemon::AssertionFailedError"; 267 } 268 269 virtual ~AssertionFailedError() throw() {} 270 }; 186 271 187 272 … … 189 274 190 275 191 /** 192 * \brief Macro for assertions with customizable message 193 */ 194 195 # define lemon_assert(exp, msg) \ 196 if(!(exp)) { \ 197 std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \ 198 abort; \ 199 } 200 201 202 /** 203 * \brief Macro for mark not yet implemented features. 204 * 205 * \todo Is this the right place for this? It should be used only in 206 * modules under development. 207 */ 208 209 # define FIXME(msg) lemon_assert(0, "FIXME: " msg) 276 inline 277 void assert_fail(const char *file, int line, const char *func, 278 const char *message, const char *assertion = 0, 279 bool do_abort=true) 280 { 281 using namespace std; 282 cerr << file << ":" << line << ": "; 283 if( func ) 284 cerr << func << ": "; 285 cerr << message; 286 if( assertion ) 287 cerr << " (assertion '" << assertion << "' failed)"; 288 cerr << endl; 289 if(do_abort) 290 abort(); 291 } 292 293 inline 294 void assert_fail_throw(const char *file, int line, const char *func, 295 const char *message, const char *assertion = 0, 296 bool = true) 297 { 298 throw AssertionFailedError(file, line, func, message, assertion); 299 } 300 210 301 211 302 } 212 303 #endif // LEMON_ERROR_H 304 305 #undef LEMON_ASSERT 306 #undef LEMON_FIXME 307 308 #ifndef LEMON_ASSERT_ABORT 309 # define LEMON_ASSERT_ABORT 1 310 #endif 311 312 #ifndef LEMON_ASSERT_HANDLER 313 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail 314 #endif 315 316 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS) 317 318 # define LEMON_ASSERT(exp, msg) (static_cast<void> (0)) 319 320 #else 321 322 /** 323 * \brief Macro for assertions with customizable message 324 * 325 * \todo __PRETTY_FUNCTION__ should be replaced by something 326 * compiler-independant, like BOOST_CURRENT_FUNCTION 327 */ 328 329 # define LEMON_ASSERT(exp, msg) \ 330 (static_cast<void> (!!(exp) ? 0 : ( \ 331 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ 332 __PRETTY_FUNCTION__, \ 333 (msg), #exp, LEMON_ASSERT_ABORT), 0))) 334 335 # endif // NDEBUG 336 337 /** 338 * \brief Macro for mark not yet implemented features. 339 * 340 * \todo Is this the right place for this? It should be used only in 341 * modules under development. 342 * 343 * \todo __PRETTY_FUNCTION__ should be replaced by something 344 * compiler-independant, like BOOST_CURRENT_FUNCTION 345 */ 346 347 # define LEMON_FIXME(msg) \ 348 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ 349 "FIXME: " msg))
Note: See TracChangeset
for help on using the changeset viewer.