#include <set>
#include <algorithm>
#include <zypp/base/Logger.h>
+#include <zypp/base/String.h>
+#include <zypp/base/ReferenceCounted.h>
#include <zypp/Arch.h>
#include <zypp/Edition.h>
#include <zypp/Rel.h>
-#include <boost/regex.hpp>
-
-
using namespace std;
template<class _C>
void outc( const _C & cont, ostream & str )
namespace zypp
{
-
}
using namespace zypp;
+void chk( const std::string & ed )
+{
+ Edition e( ed );
+ MIL << e << endl;
+}
/******************************************************************
**
{
INT << "===[START]==========================================" << endl;
+ DBG << Edition() << endl;
+ DBG << Edition("") << endl;
+
+ DBG << Edition("","","") << endl;
+
+ chk( "1.2.3-4.5.6" );
+ chk( "3:1.2.3-4.5.6" );
+
+ chk( "3:1.2.3-4.5.6-3" );
+
INT << "===[END]============================================" << endl;
return 0;
AM_CXXFLAGS =
# gperf: -pg
-LDADD = $(top_srcdir)/zypp/lib@PACKAGE@.la
+LDADD = $(top_srcdir)/zypp/lib@PACKAGE@.la -lboost_regex
## ##################################################
#include "zypp/base/Logger.h"
#include "base/String.h"
+#include "base/Exception.h"
#include "zypp/Edition.h"
: _epoch( 0 )
{}
+ Impl( const std::string & edition_r )
+ : _epoch( 0 )
+ {
+ str::smatch what;
+ if( str::regex_match( edition_r.begin(), edition_r.end(),
+ what, _rxEdition ) )
+ {
+ // what[2] contains the epoch
+ // what[3] contains the version
+ // what[5] contains the release
+ if ( what[2].matched )
+ _epoch = strtoul( what[2].str().c_str(), NULL, 10 );
+ if ( what[3].matched )
+ _version = what[3].str();
+ if ( what[5].matched )
+ _release = what[5].str();
+ }
+ else
+ {
+ ZYPP_THROW( string("Invalid Edition: ")+edition_r );
+ }
+ }
+
Impl( const std::string & version_r,
const std::string & release_r,
epoch_t epoch_r )
, _release( release_r )
{}
+ Impl( const std::string & version_r,
+ const std::string & release_r,
+ const std::string & epoch_r )
+ : _epoch( strtoul( epoch_r.c_str(), NULL, 10 ) )
+ , _version( version_r )
+ , _release( release_r )
+ {
+#warning check legal VR
+ }
+
/** Dtor */
~Impl()
{}
epoch_t _epoch;
std::string _version;
std::string _release;
+
+ static const std::string _rxE;
+ static const std::string _rxVR;
+ static const str::regex _rxEdition;
};
///////////////////////////////////////////////////////////////////
+ const std::string Edition::Impl::_rxE( "([0-9]+):" );
+ const std::string Edition::Impl::_rxVR( "([^-]*)" );
+ const str::regex Edition::Impl::_rxEdition( str::form( "(%s)?%s(-%s)?",
+ _rxE.c_str(),
+ _rxVR.c_str(), _rxVR.c_str() ) );
+
+ ///////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : Edition
: _pimpl( new Impl )
{}
+ Edition::Edition( const std::string & edition_r )
+ : _pimpl( new Impl( edition_r ) )
+ {}
+
Edition::Edition( const std::string & version_r,
const std::string & release_r,
epoch_t epoch_r )
: _pimpl( new Impl( version_r, release_r, epoch_r ) )
{}
+ Edition::Edition( const std::string & version_r,
+ const std::string & release_r,
+ const std::string & epoch_r )
+ : _pimpl( new Impl( version_r, release_r, epoch_r ) )
+ {}
+
Edition::~Edition()
{}
* version, let the container use Edition::Less to compare.
*
* \ingroup g_BackendSpecific
- * \todo optimize implementation
+ * \todo Define exceptions.
+ * \todo optimize implementation(e.g don't store epoch if noepoch)
* \todo implement debian comparison and make choice backend specific
*/
class Edition
/** Default ctor. */
Edition();
- /** Ctor taking \a version_r, \a release_r and optional \a epoch_r */
+ /** Ctor taking edition as string.
+ * \throw INTERNAL if \a edition_r does not make a valid Edition.
+ */
+ Edition( const std::string & edition_r );
+
+ /** Ctor taking \a version_r, \a release_r and optional \a epoch_r
+ * \throw INTERNAL if \a version_r or \a release_r are not valid.
+ */
Edition( const std::string & version_r,
const std::string & release_r,
epoch_t epoch_r = noepoch );
+ /** Ctor taking \a version_r, \a release_r and optional \a epoch_r as string.
+ * \throw INTERNAL if \a version_r or \a release_r \a epoch_r are
+ * not valid.
+ */
+ Edition( const std::string & version_r,
+ const std::string & release_r,
+ const std::string & epoch_r );
+
/** Dtor */
~Edition();
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/base/Exception.cc
+ *
+*/
+#include <iostream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Exception.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace exceptinon_detail
+ { /////////////////////////////////////////////////////////////////
+
+ std::string CodeLocation::asString() const
+ {
+ return str::form( "%s(%s):%u",
+ _file.c_str(),
+ _func.c_str(),
+ _line );
+ }
+
+ std::ostream & operator<<( std::ostream & str, const CodeLocation & obj )
+ { return str << obj.asString(); }
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace exceptinon_detail
+ ///////////////////////////////////////////////////////////////////
+
+ Exception::Exception( const CodeLocation & where_r, const std::string & msg_r )
+ : _where( where_r ), _msg( msg_r )
+ {
+ INT << asString() << endl;
+ }
+
+ Exception::~Exception() throw()
+ {}
+
+ std::string Exception::asString() const
+ {
+ std::string ret( _where.asString() );
+ ret += ": ";
+ return ret += _msg;
+ }
+
+ std::string Exception::strErrno( int errno_r )
+ {
+ return str::strerror( errno_r );
+ }
+
+ std::string Exception::strErrno( int errno_r, const std::string & msg_r )
+ {
+ std::string ret( msg_r );
+ ret += ": ";
+ return ret += strErrno( errno_r );
+ }
+
+ void Exception::caught() const
+ {
+ INT << "Caught: " << asString() << endl;
+ }
+
+ std::ostream & operator<<( std::ostream & str, const Exception & obj )
+ { return str << obj.asString(); }
+
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/base/Exception.h
+ *
+*/
+#ifndef ZYPP_BASE_EXCEPTION_H
+#define ZYPP_BASE_EXCEPTION_H
+
+#include <iosfwd>
+#include <stdexcept>
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace exceptinon_detail
+ { /////////////////////////////////////////////////////////////////
+
+ /** Keep _FILE_, _FUNCTION_ and _LINE_.
+ * Construct it using the \ref ZYPP_EX_CODELOCATION macro.
+ */
+ struct CodeLocation
+ {
+ friend std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
+
+ /** Ctor */
+ CodeLocation( const std::string & file_r,
+ const std::string & func_r,
+ unsigned line_r )
+ : _file( file_r ), _func( func_r ), _line( line_r )
+ {}
+
+ /** Location as string */
+ std::string asString() const;
+
+ private:
+ std::string _file;
+ std::string _func;
+ unsigned _line;
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** Create CodeLocation object storing the current location. */
+ #define ZYPP_EX_CODELOCATION ::zypp::exceptinon_detail::CodeLocation(__FILE__,__FUNCTION__,__LINE__)
+
+ /** \relates CodeLocation Stream output */
+ std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace exceptinon_detail
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Exception
+ /** Exception stores message and \ref CodeLocation.
+ *
+ * Use \ref ZYPP_THROW to throw exceptions. Assuming this,
+ * the ctor logs it's creation, as it't the point where the
+ * exception is thrown. If you catch the Excetion, you may
+ * call \ref caught, to drop a logling telling so.
+ *
+ * \todo That's a draft to have a common way of throwing exceptions.
+ * Most probabely we'll finally use blocxx exceptions. Here, but not
+ * in the remaining code of zypp. If we can we should try to wrap
+ * the blocxx macros and typedef the classes in here.
+ **/
+ class Exception : public std::exception
+ {
+ friend std::ostream & operator<<( std::ostream & str, const Exception & obj );
+ typedef exceptinon_detail::CodeLocation CodeLocation;
+ public:
+
+ /** Ctor taking CodeLocation and message.
+ * Use \ref ZYPP_THROW to throw exceptions.
+ */
+ Exception( const CodeLocation & where_r, const std::string & msg_r );
+
+ /** Dtor. */
+ virtual ~Exception() throw();
+
+ /** Return CodeLocation. */
+ const CodeLocation & where() const
+ { return _where; }
+
+ /** Return message string. */
+ const std::string & msg() const
+ { return _msg; }
+
+ /** Return message string. */
+ virtual const char * what() const throw()
+ { return _msg.c_str(); }
+
+ /** Exception as string */
+ std::string asString() const;
+
+ /** Simply drops a log line. */
+ void caught() const;
+
+ public:
+ /** Make a string from \a errno_r. */
+ static std::string strErrno( int errno_r );
+ /** Make a string from \a errno_r and \a msg_r. */
+ static std::string strErrno( int errno_r, const std::string & msg_r );
+
+ private:
+ CodeLocation _where;
+ std::string _msg;
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** \relates Exception Stream output */
+ std::ostream & operator<<( std::ostream & str, const Exception & obj );
+
+ ///////////////////////////////////////////////////////////////////
+
+ /** Actually throw an Exception. */
+#define ZYPP_DOTHROW(EXCPT) throw( EXCPT )
+
+ /** \defgroup ZYPP_THROW ZYPP_THROW macros
+ * Macros for throwing Exception.
+ */
+ //@{
+ /** 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 errno provided as argument. */
+#define ZYPP_THROW_ERRNO1(ERRNO)\
+ ZYPP_DOTHROW( ::zypp::Exception( ZYPP_EX_CODELOCATION, ::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 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) ) )
+ //@}
+
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_BASE_EXCEPTION_H
include_HEADERS = \
KindOf.h \
Logger.h \
+ Exception.h \
NonCopyable.h \
PtrTypes.h \
ReferenceCounted.h \
lib@PACKAGE@_base_la_SOURCES = \
Logger.cc \
+ Exception.cc \
String.cc \
StringVal.cc
#include <iosfwd>
+#include "zypp/base/Exception.h"
#include "zypp/base/PtrTypes.h"
///////////////////////////////////////////////////////////////////
* \throw INTERNAL if reference count is not zero.
*/
virtual ~ReferenceCounted()
- { if ( _counter ) throw( "~ReferenceCounted: nonzero reference count" ); }
+ { if ( _counter ) ZYPP_THROW( "~ReferenceCounted: nonzero reference count" ); }
/** Assignment.
* Reference count remains untouched.
void unref() const
{
if ( !_counter )
- throw( "ReferenceCounted::unref: zero reference count" );
+ ZYPP_THROW( "ReferenceCounted::unref: zero reference count" );
if ( --_counter == 0 )
delete this;
}
return safe.asString();
}
+ /******************************************************************
+ **
+ ** FUNCTION NAME : toLower
+ ** FUNCTION TYPE : std::string
+ */
+ std::string strerror( int errno_r )
+ {
+ return form( "(%d)%s", errno_r, ::strerror( errno_r ) );
+ }
+
/******************************************************************
**
** FUNCTION NAME : toLower
#include <iosfwd>
#include <string>
+#include <boost/regex.hpp>
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
+ /** String related utilities and \ref ZYPP_STR_REGEX.
+ \see \ref ZYPP_STR_REGEX
+ */
namespace str
{ /////////////////////////////////////////////////////////////////
std::string form( const char * format, ... )
__attribute__ ((format (printf, 1, 2)));
+ /** Return string describing the \a error_r code.
+ * Like ::strerror, but the numerical value is included in
+ * the string as well.
+ */
+ std::string strerror( int errno_r );
+
+ /** \defgroup ZYPP_STR_REGEX Regular expressions
+ *
+ * Namespace zypp::str regular expressions \b using the
+ * boost regex library
+ * \url http://www.boost.org/libs/regex/doc/index.html.
+ *
+ * \li \c regex
+ * \li \c regex_match
+ * \li \c regex_search
+ * \li \c regex_replace
+ * \li \c match_results
+ * \li \c cmatch
+ * \li \c wcmatch
+ * \li \c smatch
+ * \li \c wsmatch
+ */
+
+ //@{
+ /** regex */
+ using boost::regex;
+ using boost::regex_match;
+ using boost::regex_search;
+ using boost::regex_replace;
+ using boost::match_results;
+ using boost::cmatch;
+ using boost::wcmatch;
+ using boost::smatch;
+ using boost::wsmatch;
+ //@}
+
/** Return lowercase version of \a s
* \todo improve
*/