00001
00002
00003
00004
00005
00006
00007
00008
00012 #ifndef ZYPP_BASE_EXCEPTION_H
00013 #define ZYPP_BASE_EXCEPTION_H
00014
00015 #include <cerrno>
00016 #include <iosfwd>
00017 #include <list>
00018 #include <stdexcept>
00019
00021 namespace zypp
00022 {
00023
00024 namespace exception_detail
00025 {
00026
00030 struct CodeLocation
00031 {
00032 friend std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
00033
00035 CodeLocation()
00036 : _line( 0 )
00037 {}
00038
00040 CodeLocation( const std::string & file_r,
00041 const std::string & func_r,
00042 unsigned line_r )
00043 : _file( file_r ), _func( func_r ), _line( line_r )
00044 {}
00045
00047 std::string asString() const;
00048
00049 private:
00050 std::string _file;
00051 std::string _func;
00052 unsigned _line;
00053 };
00055
00057
00058 #define ZYPP_EX_CODELOCATION ::zypp::exception_detail::CodeLocation(( *__FILE__ == '/' ? strrchr( __FILE__, '/' ) + 1 : __FILE__ ),__FUNCTION__,__LINE__)
00059
00061 std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
00062
00064 }
00066
00068
00069
00141 class Exception : public std::exception
00142 {
00143 friend std::ostream & operator<<( std::ostream & str, const Exception & obj );
00144
00145 public:
00146 typedef exception_detail::CodeLocation CodeLocation;
00147 typedef std::list<std::string> History;
00148 typedef History::const_iterator HistoryIterator;
00149 typedef History::size_type HistorySize;
00150
00154 Exception();
00155
00159 Exception( const std::string & msg_r );
00160
00162 virtual ~Exception() throw();
00163
00165 const CodeLocation & where() const
00166 { return _where; }
00167
00169 void relocate( const CodeLocation & where_r ) const
00170 { _where = where_r; }
00171
00177 const std::string & msg() const
00178 { return _msg; }
00179
00181 std::string asString() const;
00182
00184 std::string asUserString() const;
00185
00186 public:
00194
00196 void remember( const Exception & old_r );
00197
00199 void addHistory( const std::string & msg_r );
00200
00202 HistoryIterator historyBegin() const
00203 { return _history.begin(); }
00204
00206 HistoryIterator historyEnd() const
00207 { return _history.end(); }
00208
00210 bool historyEmpty() const
00211 { return _history.empty(); }
00212
00214 HistorySize historySize() const
00215 { return _history.size(); }
00216
00227 std::string historyAsString() const;
00228
00230
00231 protected:
00232
00234 virtual std::ostream & dumpOn( std::ostream & str ) const;
00235
00236 public:
00238 static std::string strErrno( int errno_r );
00240 static std::string strErrno( int errno_r, const std::string & msg_r );
00241
00242 public:
00246 static void log( const Exception & excpt_r, const CodeLocation & where_r,
00247 const char *const prefix_r );
00248
00249 private:
00250 mutable CodeLocation _where;
00251 std::string _msg;
00252 History _history;
00253
00255 virtual const char * what() const throw()
00256 { return _msg.c_str(); }
00257
00262 std::ostream & dumpError( std::ostream & str ) const;
00263 };
00265
00267 std::ostream & operator<<( std::ostream & str, const Exception & obj );
00268
00270
00272 template<class _Excpt>
00273 void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r ) __attribute__((noreturn));
00274 template<class _Excpt>
00275 void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00276 {
00277 excpt_r.relocate( where_r );
00278 Exception::log( excpt_r, where_r, "THROW: " );
00279 throw( excpt_r );
00280 }
00281
00283 template<class _Excpt>
00284 void _ZYPP_CAUGHT( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00285 {
00286 Exception::log( excpt_r, where_r, "CAUGHT: " );
00287 }
00288
00290 template<class _Excpt>
00291 void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r ) __attribute__((noreturn));
00292 template<class _Excpt>
00293 void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00294 {
00295 Exception::log( excpt_r, where_r, "RETHROW: " );
00296 excpt_r.relocate( where_r );
00297 throw;
00298 }
00299
00301
00308 #define ZYPP_THROW(EXCPT)\
00309 _ZYPP_THROW( EXCPT, ZYPP_EX_CODELOCATION )
00310
00312 #define ZYPP_CAUGHT(EXCPT)\
00313 _ZYPP_CAUGHT( EXCPT, ZYPP_EX_CODELOCATION )
00314
00316 #define ZYPP_RETHROW(EXCPT)\
00317 _ZYPP_RETHROW( EXCPT, ZYPP_EX_CODELOCATION )
00318
00319
00321 #define ZYPP_THROW_MSG(EXCPTTYPE, MSG)\
00322 ZYPP_THROW( EXCPTTYPE( MSG ) )
00323
00325 #define ZYPP_THROW_ERRNO(EXCPTTYPE)\
00326 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno) ) )
00327
00329 #define ZYPP_THROW_ERRNO1(EXCPTTYPE, ERRNO)\
00330 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO) ) )
00331
00333 #define ZYPP_THROW_ERRNO_MSG(EXCPTTYPE, MSG)\
00334 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno,MSG) ) )
00335
00337 #define ZYPP_THROW_ERRNO_MSG1(EXCPTTYPE, ERRNO,MSG)\
00338 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO,MSG) ) )
00339
00340
00342 }
00344 #endif // ZYPP_BASE_EXCEPTION_H