Adjusted Exceptions.
authorMichael Andres <ma@suse.de>
Thu, 8 Dec 2005 10:02:15 +0000 (10:02 +0000)
committerMichael Andres <ma@suse.de>
Thu, 8 Dec 2005 10:02:15 +0000 (10:02 +0000)
devel/devel.ma/Main.cc
zypp/CapFactory.cc
zypp/Edition.cc
zypp/Rel.cc
zypp/base/Exception.cc
zypp/base/Exception.h
zypp/base/ReferenceCounted.h
zypp/source/yum/YUMSource.cc

index e7cab49699ce1758c92a801708bf6e2e6678a7a7..c8c82544a0e0a542b9c7f1d7e171da2b14d57cbf 100644 (file)
-#include <iosfwd>
+#include <iostream>
+#include "zypp/base/Logger.h"
 #include "zypp/base/PtrTypes.h"
+#include "zypp/base/Exception.h"
 
-///////////////////////////////////////////////////////////////////
-// MyClass.h
-///////////////////////////////////////////////////////////////////
-namespace zypp
-{
-  ///////////////////////////////////////////////////////////////////
-  /** Simple class using a RWCOW_pointer to implementation.
-   *
-   * MyClass maintains an int value, manipulated via get/set.
-   * RWCOW_pointer provides the 'copy on write' functionality.
-  */
-  class MyClass
-  {
-  public:
-    /** Implementation (public, but hidden in MyClass.cc) */
-    struct Impl;
+using namespace std;
+using namespace zypp;
 
+class MediaException : public Exception
+{
   public:
-    MyClass( int val = 0 );
-
-    int get() const;
-
-    void set( int val );
+    MediaException( const std::string & msg_r )
+    : Exception( msg_r )
+    {}
+};
 
-  private:
-    /** Pointer to implementation */
-    RWCOW_pointer<Impl> _pimpl;
-  };
-  ///////////////////////////////////////////////////////////////////
+void ex()
+{
+  try
+    {
+      ZYPP_THROW( Exception, "plain exeption" );
+    }
+  catch ( Exception & excpt )
+    {
+      ZYPP_CAUGHT( excpt );
+    }
 }
-///////////////////////////////////////////////////////////////////
-
-
 
-///////////////////////////////////////////////////////////////////
-// MyClass.cc
-///////////////////////////////////////////////////////////////////
-#include <zypp/base/Debug.h>
-
-using std::endl;
-
-namespace zypp
+void mex()
 {
-  ///////////////////////////////////////////////////////////////////
-  //
-  namespace debug
-  {
-    /** Forward decl. Implemented after MyClass::Impl is defined,
-     * if you want to dynamic_cast TraceCAD<MyClass::Impl> back into
-     * MyClass::Impl. Otherwise you could implement it here.
-     */
-    template<>
-      void traceCAD( TraceCADBase::What what_r,
-                     const TraceCAD<MyClass::Impl> & self_r,
-                     const TraceCAD<MyClass::Impl> & rhs_r );
-  }
-  //
-  ///////////////////////////////////////////////////////////////////
-
-  ///////////////////////////////////////////////////////////////////
-  /** Implementation of MyClass providing the int value.
-   *
-   * To debug via TraceCAD, simply derive. Per default TraceCAD
-   * drops loglines. In this example we overload traceCAD<Impl>,
-   * to do a bit more stuff.
-  */
-  struct MyClass::Impl : public debug::TraceCAD<Impl>
-  {
-    Impl( int val = 0 )
-    : _value( val )
-    {}
-
-    int _value;
-
-  private:
-    friend Impl * rwcowClone<Impl>( const Impl * rhs );
-    /** clone for RWCOW_pointer */
-    Impl * clone() const
-    { return new Impl( *this ); }
-  };
-  ///////////////////////////////////////////////////////////////////
-
-  inline std::ostream & operator<<( std::ostream & str, const MyClass::Impl & obj )
-  { return str << "MyClass::Impl[" << &obj << "] value: " << obj._value; }
-
-  ///////////////////////////////////////////////////////////////////
-
-  ///////////////////////////////////////////////////////////////////
-  // class MyClass
-  ///////////////////////////////////////////////////////////////////
-
-  MyClass::MyClass( int val )
-  : _pimpl( new Impl( val ) )
-  {
-    // e.g _PING to indicate ctor is done.
-    _pimpl->_PING();
-  }
-
-  /** Impl access via 'operator->() const' (readonly) */
-  int MyClass::get() const
-  { return _pimpl->_value; }
-
-  /** Impl access via 'operator->()' (write, creates a copy iff shared) */
-  void MyClass::set( int val )
-  { _pimpl->_value = val; }
-
-  ///////////////////////////////////////////////////////////////////
-  //
-  namespace debug
-  {
-    /** Performs all possible casts of self_r/rhs_r back into
-     * MyClass::Impl.
-     *
-     * CTOR,DTOR: self_r can't be casted, because MyClass::Impl
-     * is not yet constructed (TraceCAD is base class), or already
-     * deleted. rhs_r is meaningless (==self_r).
-     *
-     * COPYCTOR: self_r can't be casted (not yet constructed).
-     * rhs_r can be casted into MyClass::Impl. It's the object
-     * we copy from.
-     *
-     * ASSIGN: self_r and rhs_r can be casted. If MyClass::Impl
-     * defines an operator==, you have to alter the code to call
-     * TraceCAD::operator=. Otherwise it won't be triggered.
-     *
-     * PING: self_r can be casted, rhs_r is meaningless (==self_r).
-     * You have to alter MyClass::Impl to call '_PING()' to recieve
-     * the trigger. The only purpose is to provide an easy way to
-     * trigger some action, without much changes to the original code.
-     * Call _PING there and perfrorm the action here, if possible.
-    */
-    template<>
-      void traceCAD( TraceCADBase::What what_r,
-                     const TraceCAD<MyClass::Impl> & self_r,
-                     const TraceCAD<MyClass::Impl> & rhs_r )
-      {
-        static unsigned instanceCouter = 0;
-        // lazy #define ;)
-#define STATS "\t(total " << instanceCouter << ")"
-
-        switch( what_r )
-          {
-          case TraceCADBase::CTOR:
-            ++instanceCouter;
-            SEC << self_r << what_r << STATS << std::endl;
-            break;
-
-          case TraceCADBase::DTOR:
-            --instanceCouter;
-            SEC << self_r << what_r << STATS << std::endl;
-            break;
-
-          case TraceCADBase::PING:
-            SEC << dynamic_cast<const MyClass::Impl &>(self_r)
-                << what_r << STATS << std::endl;
-            break;
-
-          case TraceCADBase::COPYCTOR:
-            ++instanceCouter;
-            SEC << self_r << what_r << "( "
-                << dynamic_cast<const MyClass::Impl &>(rhs_r)
-                << ")" << STATS << std::endl;
-            break;
-
-          case TraceCADBase::ASSIGN:
-            SEC << dynamic_cast<const MyClass::Impl &>(self_r)
-                << what_r << "( "
-                << dynamic_cast<const MyClass::Impl &>(rhs_r)
-                << ")" << STATS << std::endl;
-            break;
-          }
-      }
-  }
-  //
-  ///////////////////////////////////////////////////////////////////
+  try
+    {
+      ZYPP_THROW( MediaException, "media error" );
+    }
+  catch ( MediaException & excpt )
+    {
+      SEC << "CAUGHT MediaException" << endl;
+      ZYPP_CAUGHT( excpt );
+    }
+  catch ( Exception & excpt )
+    {
+      ZYPP_CAUGHT( excpt );
+    }
 }
-///////////////////////////////////////////////////////////////////
+
 
 /******************************************************************
 **
@@ -190,41 +55,10 @@ namespace zypp
 int main( int argc, char * argv[] )
 {
   INT << "===[START]==========================================" << endl;
-  using zypp::MyClass;
-
-  MyClass c; // MyClass::Impl CTOR
-  MyClass d( c ); // shares Impl
-  MyClass e( d ); // shares Impl
-
-  MIL << "c.get" << c.get() << endl;
-  MIL << "d.get" << d.get() << endl;
-  MIL << "e.get" << e.get() << endl;
-
-  DBG << "will d.set( 4 )..." << endl;
-  d.set( 4 ); // performs COW
-  DBG << "done d.set( 4 )" << endl;
-
-  MIL << "c.get" << c.get() << endl;
-  MIL << "d.get" << d.get() << endl;
-  MIL << "e.get" << e.get() << endl;
-
-  DBG << "will e=d..." << endl;
-  e = d; // shares Impl
-  DBG << "done e=d" << endl;
-
-  MIL << "c.get" << c.get() << endl;
-  MIL << "d.get" << d.get() << endl;
-  MIL << "e.get" << e.get() << endl;
-
-  DBG << "will e.set( 1 )..." << endl;
-  e.set( 1 ); // performs COW
-  DBG << "done e.set( c )" << endl;
 
-  MIL << "c.get" << c.get() << endl;
-  MIL << "d.get" << d.get() << endl;
-  MIL << "e.get" << e.get() << endl;
+  ex();
+  mex();
 
   INT << "===[END]============================================" << endl;
   return 0;
-  // Tree times MyClass::Impl DTOR
 }
index c298375037339253233d1edfcb30b3968089f9d2..ea371ffa1683655a500d378f25d18c4bb1227794 100644 (file)
@@ -131,7 +131,7 @@ namespace zypp
     static void assertResKind( const Resolvable::Kind & refers_r )
     {
       if ( refers_r == Resolvable::Kind() )
-        ZYPP_THROW( "Missing or empty  Resolvable::Kind in Capability." );
+        ZYPP_THROW( Exception, "Missing or empty  Resolvable::Kind in Capability." );
     }
 
     /** Check whether \a op_r and \a edition_r make a valid edition spec.
@@ -155,7 +155,7 @@ namespace zypp
           break;
 
         case Rel::NONE_e:
-          ZYPP_THROW( "Operator NONE is not allowed in Capability " );
+          ZYPP_THROW( Exception, "Operator NONE is not allowed in Capability " );
           break;
 
         case Rel::EQ_e:
@@ -168,7 +168,7 @@ namespace zypp
           break;
         }
       // SHOULD NOT GET HERE
-      ZYPP_THROW( "Unknow Operator NONE is not allowed in Capability " );
+      ZYPP_THROW( Exception, "Unknow Operator NONE is not allowed in Capability " );
       return false; // not reached
     }
 
index d6228439df4e35d8082fbc7d3bd96c2ed1a96dbf..22a871021f8883377b692a0ce69766722133818b 100644 (file)
@@ -162,7 +162,7 @@ namespace zypp
         }
       else
         {
-          ZYPP_THROW( string("Invalid Edition: ")+edition_r );
+          ZYPP_THROW( Exception, string("Invalid Edition: ")+edition_r );
         }
     }
 
@@ -195,7 +195,7 @@ namespace zypp
       char * endptr = NULL;
       epoch_t ret = strtoul( epoch_r.c_str(), &endptr, 10 );
       if ( *endptr != '\0' )
-        ZYPP_THROW( string("Invalid eopch: ")+epoch_r );
+        ZYPP_THROW( Exception, string("Invalid eopch: ")+epoch_r );
       return ret;
     }
 
@@ -204,7 +204,7 @@ namespace zypp
     {
       str::smatch what;
       if( ! str::regex_match( vr_r.begin(), vr_r.end(), what, _rxVR ) )
-        ZYPP_THROW( string("Invalid version/release: ")+vr_r );
+        ZYPP_THROW( Exception, string("Invalid version/release: ")+vr_r );
       return vr_r;
     }
 
index 7979d75d3f86fa0c4c84a6d4ec991c474c0b170c..dcea484e3a61c938930239ebd947df088c87dcfd 100644 (file)
@@ -45,7 +45,7 @@ namespace
       = _table.find( strval_r );
     if ( it == _table.end() )
       {
-        ZYPP_THROW( "Rel parse: illegal string value" );
+        ZYPP_THROW( Exception, "Rel parse: illegal string value" );
       }
     return it->second;
   }
index 3b8210bf32c63e2b62061d3f6e1f987b0d97aed4..c27f19e77aeda9b8f6b56e51db6141ef7bd1dbd1 100644 (file)
@@ -39,8 +39,8 @@ namespace zypp
   } // namespace exception_detail
   ///////////////////////////////////////////////////////////////////
 
-  Exception::Exception( const CodeLocation & where_r, const std::string & msg_r )
-  : _where( where_r ), _msg( msg_r )
+  Exception::Exception( const std::string & msg_r )
+  : _msg( msg_r )
   {}
 
   Exception::~Exception() throw()
@@ -65,11 +65,6 @@ namespace zypp
     return ret += strErrno( errno_r );
   }
 
-  void Exception::relocate( Exception & excpt_r, const CodeLocation & where_r )
-  {
-    excpt_r._where = where_r;
-  }
-
   void Exception::log( const Exception & excpt_r, const CodeLocation & where_r,
                        const char *const prefix_r )
   {
index 437ee49a739e4b3090c854d1de92cb27f21acf59..151ce89c87c55d923726abdd2187f3a5464bb5ee 100644 (file)
@@ -29,6 +29,11 @@ namespace zypp
     {
       friend std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
 
+      /** Ctor */
+      CodeLocation()
+      : _line( 0 )
+      {}
+
       /** Ctor */
       CodeLocation( const std::string & file_r,
                     const std::string & func_r,
@@ -97,13 +102,13 @@ namespace zypp
   class Exception : public std::exception
   {
     friend std::ostream & operator<<( std::ostream & str, const Exception & obj );
-    typedef exception_detail::CodeLocation CodeLocation;
   public:
+    typedef exception_detail::CodeLocation CodeLocation;
 
-    /** Ctor taking CodeLocation and message.
+    /** Ctor taking a message.
      * Use \ref ZYPP_THROW to throw exceptions.
     */
-    Exception( const CodeLocation & where_r, const std::string & msg_r );
+    Exception( const std::string & msg_r );
 
     /** Dtor. */
     virtual ~Exception() throw();
@@ -112,6 +117,10 @@ namespace zypp
     const CodeLocation & where() const
     { return _where; }
 
+    /** Exchange location on rethrow. */
+    void relocate( const CodeLocation & where_r ) const
+    { _where = where_r; }
+
     /** Return message string. */
     const std::string & msg() const
     { return _msg; }
@@ -130,15 +139,12 @@ namespace zypp
     static std::string strErrno( int errno_r, const std::string & msg_r );
 
   public:
-    /** Exchange location on rethrow. */
-    static void relocate( Exception & excpt_r, const CodeLocation & where_r );
-
     /** Drop a logline. */
     static void log( const Exception & excpt_r, const CodeLocation & where_r,
                      const char *const prefix_r );
 
   private:
-    CodeLocation _where;
+    mutable CodeLocation _where;
     std::string _msg;
   };
   ///////////////////////////////////////////////////////////////////
@@ -152,6 +158,7 @@ namespace zypp
   template<class _Excpt>
     void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
     {
+      excpt_r.relocate( where_r );
       Exception::log( excpt_r, where_r, "THROW:   " );
       throw( excpt_r );
     }
@@ -165,16 +172,13 @@ namespace zypp
 
   /** Helper for \ref ZYPP_THROW. */
   template<class _Excpt>
-    void _ZYPP_RETHROW( _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
+    void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
     {
       Exception::log( excpt_r, where_r, "RETHROW: " );
-      excpt_r.relocate( excpt_r, where_r );
+      excpt_r.relocate( where_r );
       throw excpt_r;
     }
 
-  /** Helper for \ref ZYPP_THROW. */
-#define ZYPP_DOTHROW(EXCPT) _ZYPP_THROW( EXCPT, ZYPP_EX_CODELOCATION )
-
   ///////////////////////////////////////////////////////////////////
 
   /** \defgroup ZYPP_THROW ZYPP_THROW macros
@@ -182,6 +186,10 @@ namespace zypp
    * \see \ref zypp::Exception for an example.
   */
   //@{
+  /** Drops a logline and throws the Exception. */
+#define ZYPP_DOTHROW(EXCPT)\
+  _ZYPP_THROW( EXCPT, ZYPP_EX_CODELOCATION )
+
   /** Drops a logline telling the Exception was caught (in order to handle it). */
 #define ZYPP_CAUGHT(EXCPT)\
   _ZYPP_CAUGHT( EXCPT, ZYPP_EX_CODELOCATION )
@@ -191,26 +199,25 @@ namespace zypp
   _ZYPP_RETHROW( EXCPT, ZYPP_EX_CODELOCATION )
 
 
+  /** Throw Exception built from a message string. */
+#define ZYPP_THROW(EXCPTTYPE, MSG)\
+  ZYPP_DOTHROW( EXCPTTYPE( MSG ) )
 
-  /** Throw a message string. */
-#define ZYPP_THROW(MSG)\
-  ZYPP_DOTHROW( ::zypp::Exception( ZYPP_EX_CODELOCATION, MSG ) )
-
-  /** Throw errno. */
-#define ZYPP_THROW_ERRNO\
-  ZYPP_DOTHROW( ::zypp::Exception( ZYPP_EX_CODELOCATION, ::zypp::Exception::strErrno(errno) ) )
+  /** Throw Exception built from errno. */
+#define ZYPP_THROW_ERRNO(EXCPTTYPE)\
+  ZYPP_DOTHROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno) ) )
 
-  /** Throw errno provided as argument. */
-#define ZYPP_THROW_ERRNO1(ERRNO)\
-  ZYPP_DOTHROW( ::zypp::Exception( ZYPP_EX_CODELOCATION, ::zypp::Exception::strErrno(ERRNO) ) )
+  /** Throw Exception built from errno provided as argument. */
+#define ZYPP_THROW_ERRNO1(EXCPTTYPE, ERRNO)\
+  ZYPP_DOTHROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO) ) )
 
-  /** Throw errno and a message string. */
-#define ZYPP_THROW_ERRNO_MSG(MSG)\
-  ZYPP_DOTHROW( ::zypp::Exception( ZYPP_EX_CODELOCATION, ::zypp::Exception::strErrno(errno,MSG) ) )
+  /** Throw Exception built from errno and a message string. */
+#define ZYPP_THROW_ERRNO_MSG(EXCPTTYPE, MSG)\
+  ZYPP_DOTHROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno,MSG) ) )
 
-  /** Throw errno provided as argument and a message string */
-#define ZYPP_THROW_ERRNO_MSG1(ERRNO,MSG)\
-  ZYPP_DOTHROW( ::zypp::Exception( ZYPP_EX_CODELOCATION, ::zypp::Exception::strErrno(ERRNO,MSG) ) )
+  /** Throw Exception built from errno provided as argument and a message string */
+#define ZYPP_THROW_ERRNO_MSG1(EXCPTTYPE, ERRNO,MSG)\
+  ZYPP_DOTHROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO,MSG) ) )
   //@}
 
   /////////////////////////////////////////////////////////////////
index bd58b66fb4fd656bb20ee4511e7a374a288aea75..9fe8596f6e8592bf0047a3c46f277afc173cd2b6 100644 (file)
@@ -54,7 +54,7 @@ namespace zypp
        * \throw INTERNAL if reference count is not zero.
       */
       virtual ~ReferenceCounted()
-      { if ( _counter ) ZYPP_THROW( "~ReferenceCounted: nonzero reference count" ); }
+      { if ( _counter ) ZYPP_THROW( Exception, "~ReferenceCounted: nonzero reference count" ); }
 
       /** Assignment.
        * Reference count remains untouched.
@@ -78,7 +78,7 @@ namespace zypp
       void unref() const
       {
         if ( !_counter )
-          ZYPP_THROW( "ReferenceCounted::unref: zero reference count" );
+          ZYPP_THROW( Exception, "ReferenceCounted::unref: zero reference count" );
         if ( --_counter == 0 )
           delete this;
       }
index 1127396124ef58b46c5e7ad6bd7cc9e5ff8cd7c8..44d1f7eaae6d28b9ff2255df884cb77d08494052 100644 (file)
@@ -87,7 +87,7 @@ namespace zypp
        catch (...)
        {
        ERR << "Cannot read repomd file, cannot initialize source" << endl;
-//     ZYPP_THROW( "Cannot read repomd file, cannot initialize source" );
+//     ZYPP_THROW( Exception, "Cannot read repomd file, cannot initialize source" );
        }
        try {
        // now put other and filelist data to structures for easier find