libzypp  10.5.0
Exception.h
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #ifndef ZYPP_BASE_EXCEPTION_H
00013 #define ZYPP_BASE_EXCEPTION_H
00014 
00015 #include <iosfwd>
00016 #include <string>
00017 #include <list>
00018 #include <stdexcept>
00019 
00020 #include "zypp/base/Errno.h"
00021 
00023 namespace zypp
00024 { 
00025 
00026   namespace exception_detail
00027   { 
00028 
00032     struct CodeLocation
00033     {
00034       friend std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
00035 
00037       CodeLocation()
00038       : _line( 0 )
00039       {}
00040 
00042       CodeLocation( const std::string & file_r,
00043                     const std::string & func_r,
00044                     unsigned            line_r )
00045       : _file( file_r ), _func( func_r ), _line( line_r )
00046       {}
00047 
00049       std::string asString() const;
00050 
00051     private:
00052       std::string _file;
00053       std::string _func;
00054       unsigned    _line;
00055     };
00057 
00059     //#define ZYPP_EX_CODELOCATION ::zypp::exception_detail::CodeLocation(__FILE__,__FUNCTION__,__LINE__)
00060 #define ZYPP_EX_CODELOCATION ::zypp::exception_detail::CodeLocation(( *__FILE__ == '/' ? strrchr( __FILE__, '/' ) + 1 : __FILE__ ),__FUNCTION__,__LINE__)
00061 
00063     std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
00064 
00066   } // namespace exception_detail
00068 
00070   //
00071   //    CLASS NAME : Exception
00143   class Exception : public std::exception
00144   {
00145     friend std::ostream & operator<<( std::ostream & str, const Exception & obj );
00146 
00147   public:
00148     typedef exception_detail::CodeLocation CodeLocation;
00149     typedef std::list<std::string>         History;
00150     typedef History::const_iterator        HistoryIterator;
00151     typedef History::size_type             HistorySize;
00152 
00156     Exception();
00157 
00161     Exception( const std::string & msg_r );
00162 
00167     Exception( const std::string & msg_r, const Exception & history_r );
00168 
00170     virtual ~Exception() throw();
00171 
00173     const CodeLocation & where() const
00174     { return _where; }
00175 
00177     void relocate( const CodeLocation & where_r ) const
00178     { _where = where_r; }
00179 
00185     const std::string & msg() const
00186     { return _msg; }
00187 
00189     std::string asString() const;
00190 
00194     std::string asUserString() const;
00195 
00196   public:
00204 
00206     void remember( const Exception & old_r );
00207 
00209     void addHistory( const std::string & msg_r );
00210 
00212     HistoryIterator historyBegin() const
00213     { return _history.begin(); }
00214 
00216     HistoryIterator historyEnd() const
00217     { return _history.end(); }
00218 
00220     bool historyEmpty() const
00221     { return _history.empty(); }
00222 
00224     HistorySize historySize() const
00225     { return _history.size(); }
00226 
00237     std::string historyAsString() const;
00238 
00240     std::string asUserHistory() const;
00242 
00243   protected:
00244 
00246     virtual std::ostream & dumpOn( std::ostream & str ) const;
00247 
00248   public:
00250     static std::string strErrno( int errno_r );
00252     static std::string strErrno( int errno_r, const std::string & msg_r );
00253 
00254   public:
00258     static void log( const Exception & excpt_r, const CodeLocation & where_r,
00259                      const char *const prefix_r );
00260 
00261   private:
00262     mutable CodeLocation _where;
00263     std::string          _msg;
00264     History              _history;
00265 
00267     virtual const char * what() const throw()
00268     { return _msg.c_str(); }
00269 
00274     std::ostream & dumpError( std::ostream & str ) const;
00275   };
00277 
00279   std::ostream & operator<<( std::ostream & str, const Exception & obj );
00280 
00282 
00284   template<class _Excpt>
00285     void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r ) __attribute__((noreturn));
00286   template<class _Excpt>
00287     void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00288     {
00289       excpt_r.relocate( where_r );
00290       Exception::log( excpt_r, where_r, "THROW:   " );
00291       throw( excpt_r );
00292     }
00293 
00295   template<class _Excpt>
00296     void _ZYPP_CAUGHT( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00297     {
00298       Exception::log( excpt_r, where_r, "CAUGHT:  " );
00299     }
00300 
00302   template<class _Excpt>
00303     void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r ) __attribute__((noreturn));
00304   template<class _Excpt>
00305     void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00306     {
00307       Exception::log( excpt_r, where_r, "RETHROW: " );
00308       excpt_r.relocate( where_r );
00309       throw;
00310     }
00311 
00313 
00320 #define ZYPP_THROW(EXCPT)\
00321   _ZYPP_THROW( EXCPT, ZYPP_EX_CODELOCATION )
00322 
00324 #define ZYPP_CAUGHT(EXCPT)\
00325   _ZYPP_CAUGHT( EXCPT, ZYPP_EX_CODELOCATION )
00326 
00328 #define ZYPP_RETHROW(EXCPT)\
00329   _ZYPP_RETHROW( EXCPT, ZYPP_EX_CODELOCATION )
00330 
00331 
00333 #define ZYPP_THROW_MSG(EXCPTTYPE, MSG)\
00334   ZYPP_THROW( EXCPTTYPE( MSG ) )
00335 
00337 #define ZYPP_THROW_ERRNO(EXCPTTYPE)\
00338   ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno) ) )
00339 
00341 #define ZYPP_THROW_ERRNO1(EXCPTTYPE, ERRNO)\
00342   ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO) ) )
00343 
00345 #define ZYPP_THROW_ERRNO_MSG(EXCPTTYPE, MSG)\
00346   ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno,MSG) ) )
00347 
00349 #define ZYPP_THROW_ERRNO_MSG1(EXCPTTYPE, ERRNO,MSG)\
00350   ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO,MSG) ) )
00351 
00352 
00354 } // namespace zypp
00356 #endif // ZYPP_BASE_EXCEPTION_H