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 
00164     virtual ~Exception() throw();
00165 
00167     const CodeLocation & where() const
00168     { return _where; }
00169 
00171     void relocate( const CodeLocation & where_r ) const
00172     { _where = where_r; }
00173 
00179     const std::string & msg() const
00180     { return _msg; }
00181 
00183     std::string asString() const;
00184 
00188     std::string asUserString() const;
00189 
00190   public:
00198 
00200     void remember( const Exception & old_r );
00201 
00203     void addHistory( const std::string & msg_r );
00204 
00206     HistoryIterator historyBegin() const
00207     { return _history.begin(); }
00208 
00210     HistoryIterator historyEnd() const
00211     { return _history.end(); }
00212 
00214     bool historyEmpty() const
00215     { return _history.empty(); }
00216 
00218     HistorySize historySize() const
00219     { return _history.size(); }
00220 
00231     std::string historyAsString() const;
00232 
00234     std::string asUserHistory() const;
00236 
00237   protected:
00238 
00240     virtual std::ostream & dumpOn( std::ostream & str ) const;
00241 
00242   public:
00244     static std::string strErrno( int errno_r );
00246     static std::string strErrno( int errno_r, const std::string & msg_r );
00247 
00248   public:
00252     static void log( const Exception & excpt_r, const CodeLocation & where_r,
00253                      const char *const prefix_r );
00254 
00255   private:
00256     mutable CodeLocation _where;
00257     std::string          _msg;
00258     History              _history;
00259 
00261     virtual const char * what() const throw()
00262     { return _msg.c_str(); }
00263 
00268     std::ostream & dumpError( std::ostream & str ) const;
00269   };
00271 
00273   std::ostream & operator<<( std::ostream & str, const Exception & obj );
00274 
00276 
00278   template<class _Excpt>
00279     void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r ) __attribute__((noreturn));
00280   template<class _Excpt>
00281     void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00282     {
00283       excpt_r.relocate( where_r );
00284       Exception::log( excpt_r, where_r, "THROW:   " );
00285       throw( excpt_r );
00286     }
00287 
00289   template<class _Excpt>
00290     void _ZYPP_CAUGHT( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00291     {
00292       Exception::log( excpt_r, where_r, "CAUGHT:  " );
00293     }
00294 
00296   template<class _Excpt>
00297     void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r ) __attribute__((noreturn));
00298   template<class _Excpt>
00299     void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
00300     {
00301       Exception::log( excpt_r, where_r, "RETHROW: " );
00302       excpt_r.relocate( where_r );
00303       throw;
00304     }
00305 
00307 
00314 #define ZYPP_THROW(EXCPT)\
00315   _ZYPP_THROW( EXCPT, ZYPP_EX_CODELOCATION )
00316 
00318 #define ZYPP_CAUGHT(EXCPT)\
00319   _ZYPP_CAUGHT( EXCPT, ZYPP_EX_CODELOCATION )
00320 
00322 #define ZYPP_RETHROW(EXCPT)\
00323   _ZYPP_RETHROW( EXCPT, ZYPP_EX_CODELOCATION )
00324 
00325 
00327 #define ZYPP_THROW_MSG(EXCPTTYPE, MSG)\
00328   ZYPP_THROW( EXCPTTYPE( MSG ) )
00329 
00331 #define ZYPP_THROW_ERRNO(EXCPTTYPE)\
00332   ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno) ) )
00333 
00335 #define ZYPP_THROW_ERRNO1(EXCPTTYPE, ERRNO)\
00336   ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO) ) )
00337 
00339 #define ZYPP_THROW_ERRNO_MSG(EXCPTTYPE, MSG)\
00340   ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno,MSG) ) )
00341 
00343 #define ZYPP_THROW_ERRNO_MSG1(EXCPTTYPE, ERRNO,MSG)\
00344   ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO,MSG) ) )
00345 
00346 
00348 } // namespace zypp
00350 #endif // ZYPP_BASE_EXCEPTION_H

doxygen