Exception.h
Go to the documentation of this file.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 #include <string.h>
00020
00022 namespace zypp
00023 {
00024
00025 namespace exception_detail
00026 {
00027
00031 struct CodeLocation
00032 {
00033 friend std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
00034
00036 CodeLocation()
00037 : _line( 0 )
00038 {}
00039
00041 CodeLocation( const std::string & file_r,
00042 const std::string & func_r,
00043 unsigned line_r )
00044 : _file( file_r ), _func( func_r ), _line( line_r )
00045 {}
00046
00048 std::string asString() const;
00049
00050 private:
00051 std::string _file;
00052 std::string _func;
00053 unsigned _line;
00054 };
00056
00058
00059 #define ZYPP_EX_CODELOCATION ::zypp::exception_detail::CodeLocation(( *__FILE__ == '/' ? strrchr( __FILE__, '/' ) + 1 : __FILE__ ),__FUNCTION__,__LINE__)
00060
00062 std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
00063
00065 }
00067
00069
00070
00142 class Exception : public std::exception
00143 {
00144 friend std::ostream & operator<<( std::ostream & str, const Exception & obj );
00145
00146 public:
00147 typedef exception_detail::CodeLocation CodeLocation;
00148 typedef std::list<std::string> History;
00149 typedef History::const_iterator HistoryIterator;
00150 typedef History::size_type HistorySize;
00151
00155 Exception();
00156
00160 Exception( const std::string & msg_r );
00161
00163 virtual ~Exception() throw();
00164
00166 const CodeLocation & where() const
00167 { return _where; }
00168
00170 void relocate( const CodeLocation & where_r ) const
00171 { _where = where_r; }
00172
00178 const std::string & msg() const
00179 { return _msg; }
00180
00182 std::string asString() const;
00183
00187 std::string asUserString() const;
00188
00189 public:
00197
00199 void remember( const Exception & old_r );
00200
00202 void addHistory( const std::string & msg_r );
00203
00205 HistoryIterator historyBegin() const
00206 { return _history.begin(); }
00207
00209 HistoryIterator historyEnd() const
00210 { return _history.end(); }
00211
00213 bool historyEmpty() const
00214 { return _history.empty(); }
00215
00217 HistorySize historySize() const
00218 { return _history.size(); }
00219
00230 std::string historyAsString() const;
00231
00233 std::string asUserHistory() const;
00235
00236 protected:
00237
00239 virtual std::ostream & dumpOn( std::ostream & str ) const;
00240
00241 public:
00243 static std::string strErrno( int errno_r );
00245 static std::string strErrno( int errno_r, const std::string & msg_r );
00246
00247 public:
00251 static void log( const Exception & excpt_r, const CodeLocation & where_r,
00252 const char *const prefix_r );
00253
00254 private:
00255 mutable CodeLocation _where;
00256 std::string _msg;
00257 History _history;
00258
00260 virtual const char * what() const throw()
00261 { return _msg.c_str(); }
00262
00267 std::ostream & dumpError( std::ostream & str ) const;
00268 };
00270
00272 std::ostream & operator<<( std::ostream & str, const Exception & obj );
00273
00275
00277 template<class _Excpt>
00278 void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r ) __attribute__((noreturn));
00279 template<class _Excpt>
00280 void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00281 {
00282 excpt_r.relocate( where_r );
00283 Exception::log( excpt_r, where_r, "THROW: " );
00284 throw( excpt_r );
00285 }
00286
00288 template<class _Excpt>
00289 void _ZYPP_CAUGHT( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00290 {
00291 Exception::log( excpt_r, where_r, "CAUGHT: " );
00292 }
00293
00295 template<class _Excpt>
00296 void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r ) __attribute__((noreturn));
00297 template<class _Excpt>
00298 void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00299 {
00300 Exception::log( excpt_r, where_r, "RETHROW: " );
00301 excpt_r.relocate( where_r );
00302 throw;
00303 }
00304
00306
00313 #define ZYPP_THROW(EXCPT)\
00314 _ZYPP_THROW( EXCPT, ZYPP_EX_CODELOCATION )
00315
00317 #define ZYPP_CAUGHT(EXCPT)\
00318 _ZYPP_CAUGHT( EXCPT, ZYPP_EX_CODELOCATION )
00319
00321 #define ZYPP_RETHROW(EXCPT)\
00322 _ZYPP_RETHROW( EXCPT, ZYPP_EX_CODELOCATION )
00323
00324
00326 #define ZYPP_THROW_MSG(EXCPTTYPE, MSG)\
00327 ZYPP_THROW( EXCPTTYPE( MSG ) )
00328
00330 #define ZYPP_THROW_ERRNO(EXCPTTYPE)\
00331 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno) ) )
00332
00334 #define ZYPP_THROW_ERRNO1(EXCPTTYPE, ERRNO)\
00335 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO) ) )
00336
00338 #define ZYPP_THROW_ERRNO_MSG(EXCPTTYPE, MSG)\
00339 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno,MSG) ) )
00340
00342 #define ZYPP_THROW_ERRNO_MSG1(EXCPTTYPE, ERRNO,MSG)\
00343 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO,MSG) ) )
00344
00345
00347 }
00349 #endif // ZYPP_BASE_EXCEPTION_H