-#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 );
+ }
}
-///////////////////////////////////////////////////////////////////
+
/******************************************************************
**
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
}
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.
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:
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
}
}
else
{
- ZYPP_THROW( string("Invalid Edition: ")+edition_r );
+ ZYPP_THROW( Exception, string("Invalid Edition: ")+edition_r );
}
}
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;
}
{
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;
}
= _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;
}
} // 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()
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 )
{
{
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,
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();
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; }
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;
};
///////////////////////////////////////////////////////////////////
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 );
}
/** 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
* \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 )
_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) ) )
//@}
/////////////////////////////////////////////////////////////////
* \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.
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;
}
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