ref: refs/heads/master
commit 2b060281952c78ce3b4990794819f03fe0f5b6af
Author: Michael Andres
Date: Mon Apr 20 16:47:57 2009 +0200
New classes wraping satsolver datamatcher (Match and sat::AttrMatcher)
- zypp::Match - string matching mode and option bit flags
- zypp::sat::AttrMatcher - string matching functor supporting STRING|SUBSTRING|GLOB|REGEX
---
tests/sat/AttrMatcher_test.cc | 131 ++++++++++++++
tests/sat/CMakeLists.txt | 2 +-
zypp/CMakeLists.txt | 2 +
zypp/sat/AttrMatcher.cc | 318 +++++++++++++++++++++++++++++++++
zypp/sat/AttrMatcher.h | 396 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 848 insertions(+), 1 deletions(-)
diff --git a/tests/sat/AttrMatcher_test.cc b/tests/sat/AttrMatcher_test.cc
new file mode 100644
index 0000000..05e0d88
--- /dev/null
+++ b/tests/sat/AttrMatcher_test.cc
@@ -0,0 +1,131 @@
+#include "TestSetup.h"
+#include
+#include
+#include
+
+///////////////////////////////////////////////////////////////////
+//
+// CLASS NAME : Matcher
+//
+///////////////////////////////////////////////////////////////////
+
+BOOST_AUTO_TEST_CASE(Match_default)
+{
+ Match m;
+ BOOST_CHECK( !m ); // eval in boolean context
+ BOOST_CHECK_EQUAL( m, Match::NOTHING );
+ BOOST_CHECK_EQUAL( m.get(), 0 );
+
+ // set the mode part
+ BOOST_CHECK_EQUAL( m |= Match::STRING, Match::STRING );
+
+ m.setModeSubstring();
+ BOOST_CHECK_EQUAL( m, Match::SUBSTRING );
+
+ m.setMode( Match::GLOB );
+ BOOST_CHECK_EQUAL( m, Match::GLOB );
+
+ BOOST_CHECK_EQUAL( m = Match::REGEX, Match::REGEX );
+
+ BOOST_CHECK( m.isModeRegex() );
+ m |= Match::NOCASE | Match::FILES;
+ BOOST_CHECK_EQUAL( m, Match::REGEX | Match::NOCASE | Match::FILES );
+
+ BOOST_CHECK( m.testAnyOf( Match::SUBSTRING | Match::NOCASE | Match::FILES ) );
+ BOOST_CHECK( !m.test( Match::SUBSTRING | Match::NOCASE | Match::FILES ) );
+ BOOST_CHECK( m.test( Match::REGEX | Match::NOCASE | Match::FILES ) );
+ BOOST_CHECK( m.test( Match::NOCASE | Match::FILES ) );
+ BOOST_CHECK( m != (Match::NOCASE | Match::FILES) );
+ BOOST_CHECK_EQUAL( m.flags(),Match::NOCASE | Match::FILES );
+
+ m -= Match::NOCASE; // remove flags
+ BOOST_CHECK( m.test( Match::REGEX | Match::FILES ) );
+ m -= Match::REGEX;
+ BOOST_CHECK_EQUAL( m, Match::FILES );
+}
+
+BOOST_AUTO_TEST_CASE(Match_operator)
+{
+ // Test whether implicit conversions from enum Match::Mode to
+ // Matcher work. There must be no difference in using mode and flag
+ // constants. These tests usually fail at compiletime, if some operator
+ // overload is missing.
+ //
+ // E.G.:
+ // inline Match operator|( const Match & lhs, const Match & rhs )
+ // this does not cover (REGEX|SUBSTRING), because if both arguments
+ // are enum Mode the compiler might want to use operator|(int,int)
+ // instead.
+
+ Match m( Match::GLOB );
+ m = Match::GLOB;
+
+ m |= Match::GLOB;
+ m = Match::SUBSTRING | Match::GLOB;
+
+ m -= Match::GLOB;
+ m = Match::SUBSTRING - Match::GLOB;
+}
+
+///////////////////////////////////////////////////////////////////
+//
+// CLASS NAME : AttrMatcher
+//
+///////////////////////////////////////////////////////////////////
+
+BOOST_AUTO_TEST_CASE(AttrMatcher_defaultconstructed)
+{
+ sat::AttrMatcher m;
+ BOOST_CHECK( !m ); // eval in boolean context
+ BOOST_CHECK( m.searchstring().empty() );
+ BOOST_CHECK_EQUAL( m.flags(), Match() );
+ // matches nothing:
+ BOOST_CHECK( !m( "" ) );
+ BOOST_CHECK( !m( " " ) );
+ BOOST_CHECK( !m( "a" ) );
+ BOOST_CHECK( !m( "default" ) );
+
+ m.setSearchstring( "fau" );
+ BOOST_CHECK( m ); // eval in boolean context
+}
+
+BOOST_AUTO_TEST_CASE(AttrMatcher_STRING)
+{
+ sat::AttrMatcher m( "fau" );
+ BOOST_CHECK_EQUAL( m.flags(), Match::STRING );
+ BOOST_CHECK( !m( "" ) );
+ BOOST_CHECK( !m( "a" ) );
+ BOOST_CHECK( m( "fau" ) );
+ BOOST_CHECK( !m( "default" ) );
+}
+
+BOOST_AUTO_TEST_CASE(AttrMatcher_REGEX)
+{
+ sat::AttrMatcher m( "fau" );
+
+ BOOST_CHECK( !m.isCompiled() );
+ BOOST_CHECK_NO_THROW( m.compile() );
+
+ m.setSearchstring( "wa[" );
+ BOOST_CHECK( !m.isCompiled() );
+ m.setFlags( Match::REGEX );
+ BOOST_CHECK( !m.isCompiled() );
+ BOOST_CHECK_THROW( m.compile(), MatchInvalidRegexException );
+ BOOST_CHECK( !m.isCompiled() );
+
+ m.setSearchstring( "wa[a]" );
+ BOOST_CHECK_NO_THROW( m.compile() );
+ BOOST_CHECK( m.isCompiled() );
+
+ BOOST_CHECK( !m( "was" ) );
+ BOOST_CHECK( !m( "qwasq" ) );
+ BOOST_CHECK( m( "qwaaq" ) );
+}
+
+#if 0
+BOOST_AUTO_TEST_CASE(AttrMatcher_)
+{
+ base::LogControl::TmpLineWriter shutUp( new log::FileLineWriter( "/tmp/YLOG" ) );
+ MIL << "GO" << endl;
+}
+#endif
diff --git a/tests/sat/CMakeLists.txt b/tests/sat/CMakeLists.txt
index 60775d4..1e34860 100644
--- a/tests/sat/CMakeLists.txt
+++ b/tests/sat/CMakeLists.txt
@@ -2,6 +2,6 @@
# to find the KeyRingTest receiver
INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/tests/zypp )
-ADD_TESTS(Solvable SolvParsing WhatProvides WhatObsoletes LookupAttr)
+ADD_TESTS(Solvable SolvParsing WhatProvides WhatObsoletes LookupAttr AttrMatcher)
diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt
index 68c0102..addd92d 100644
--- a/zypp/CMakeLists.txt
+++ b/zypp/CMakeLists.txt
@@ -508,6 +508,7 @@ SET( zypp_sat_SRCS
sat/LocaleSupport.cc
sat/LookupAttr.cc
sat/SolvAttr.cc
+ sat/AttrMatcher.cc
)
SET( zypp_sat_HEADERS
@@ -521,6 +522,7 @@ SET( zypp_sat_HEADERS
sat/LookupAttr.h
sat/LookupAttrTools.h
sat/SolvAttr.h
+ sat/AttrMatcher.h
)
INSTALL( FILES
diff --git a/zypp/sat/AttrMatcher.cc b/zypp/sat/AttrMatcher.cc
new file mode 100644
index 0000000..026f2ba
--- /dev/null
+++ b/zypp/sat/AttrMatcher.cc
@@ -0,0 +1,318 @@
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/sat/AttrMatcher.cc
+ *
+*/
+extern "C"
+{
+#include "satsolver/repo.h"
+}
+
+#include <iostream>
+#include <sstream>
+#include
+
+#include "zypp/base/LogTools.h"
+#include "zypp/base/Gettext.h"
+#include "zypp/base/String.h"
+
+#include "zypp/sat/AttrMatcher.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Match
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ const int Match::_modemask = SEARCH_STRINGMASK;
+ const int Match::_flagmask = ~_modemask;
+
+ // option flags
+ const Match Match::NOCASE (SEARCH_NOCASE);
+ const Match Match::NO_STORAGE_SOLVABLE(SEARCH_NO_STORAGE_SOLVABLE);
+ const Match Match::SUB (SEARCH_SUB);
+ const Match Match::ARRAYSENTINEL (SEARCH_ARRAYSENTINEL);
+ const Match Match::SKIP_KIND (SEARCH_SKIP_KIND);
+ const Match Match::FILES (SEARCH_FILES);
+
+ Match::Mode Match::mode() const
+ {
+ switch ( modeval() )
+ {
+ case 0: return NOTHING; break;
+ case SEARCH_STRING: return STRING; break;
+ case SEARCH_SUBSTRING: return SUBSTRING; break;
+ case SEARCH_GLOB: return GLOB; break;
+ case SEARCH_REGEX: return REGEX; break;
+ }
+ return OTHER;
+ }
+
+ int Match::modeval( Mode mode_r )
+ {
+ switch ( mode_r )
+ {
+ case NOTHING: return 0; break;
+ case STRING: return SEARCH_STRING; break;
+ case SUBSTRING: return SEARCH_SUBSTRING; break;
+ case GLOB: return SEARCH_GLOB; break;
+ case REGEX: return SEARCH_REGEX; break;
+ case OTHER: return SEARCH_STRINGMASK; break;
+ }
+ return SEARCH_STRINGMASK;
+ }
+
+ std::string Match::asString() const
+ { std::ostringstream str; str << *this; return str.str(); }
+
+ std::ostream & operator<<( std::ostream & str, Match::Mode obj )
+ {
+ switch ( obj )
+ {
+#define OUTS(V) case Match::V: return str << #V; break
+ OUTS( NOTHING );
+ OUTS( STRING );
+ OUTS( SUBSTRING );
+ OUTS( GLOB );
+ OUTS( REGEX );
+ OUTS( OTHER );
+#undef OUTS
+ }
+ return str << "Match::Mode::UNKNOWN";
+ }
+
+ std::ostream & operator<<( std::ostream & str, const Match & obj )
+ {
+ if ( ! obj )
+ return str << "NOTHING";
+
+ const char * sep = "|";
+
+ int val = obj.modeval();
+ switch ( val )
+ {
+ case 0: sep = 0; break;
+ case SEARCH_STRING: str << "STRING"; break;
+ case SEARCH_SUBSTRING: str << "SUBSTRING"; break;
+ case SEARCH_GLOB: str << "GLOB"; break;
+ case SEARCH_REGEX: str << "REGEX"; break;
+ default:
+ str << "OTHER("< _matcher;
+
+ private:
+ friend Impl * rwcowClone<Impl>( const Impl * rhs );
+ /** clone for RWCOW_pointer */
+ Impl * clone() const
+ { return new Impl( _search, _flags ); }
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** \relates AttrMatcher::Impl Stream output */
+ inline std::ostream & operator<<( std::ostream & str, const AttrMatcher::Impl & obj )
+ {
+ return str << "\"" << obj.searchstring() << "\"{" << obj.flags() << "}";
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : AttrMatcher
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ AttrMatcher::AttrMatcher()
+ : _pimpl( new Impl )
+ {}
+
+ AttrMatcher::AttrMatcher( const std::string & search_r )
+ : _pimpl( new Impl( search_r, Match::STRING ) )
+ {}
+
+ AttrMatcher::AttrMatcher( const std::string & search_r, const Match & flags_r )
+ : _pimpl( new Impl( search_r, flags_r ) )
+ {}
+
+ AttrMatcher::AttrMatcher( const std::string & search_r, int flags_r )
+ : _pimpl( new Impl( search_r, Match(flags_r) ) )
+ {}
+
+ void AttrMatcher::compile() const
+ { return _pimpl->compile(); }
+
+ bool AttrMatcher::isCompiled() const
+ { return _pimpl->isCompiled(); }
+
+ bool AttrMatcher::doMatch( const char * string_r ) const
+ { return _pimpl->doMatch( string_r ); }
+
+ const std::string & AttrMatcher::searchstring() const
+ { return _pimpl->searchstring(); }
+
+ void AttrMatcher::setSearchstring( const std::string & string_r )
+ { _pimpl->setSearchstring( string_r ); }
+
+ void AttrMatcher::setSearchstring( const std::string & string_r, const Match & flags_r )
+ {
+ _pimpl->setSearchstring( string_r );
+ _pimpl->setFlags( flags_r );
+ }
+
+ const Match & AttrMatcher::flags() const
+ { return _pimpl->flags(); }
+
+ void AttrMatcher::setFlags( const Match & flags_r )
+ { _pimpl->setFlags( flags_r ); }
+
+ /******************************************************************
+ **
+ ** FUNCTION NAME : operator<<
+ ** FUNCTION TYPE : std::ostream &
+ */
+ std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj )
+ {
+ return str << *obj._pimpl;
+ }
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace sat
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/sat/AttrMatcher.h b/zypp/sat/AttrMatcher.h
new file mode 100644
index 0000000..155733a
--- /dev/null
+++ b/zypp/sat/AttrMatcher.h
@@ -0,0 +1,396 @@
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/sat/AttrMatcher.h
+ *
+*/
+#ifndef ZYPP_SAT_ATTRMATCHER_H
+#define ZYPP_SAT_ATTRMATCHER_H
+
+extern "C"
+{
+struct _Datamatcher;
+}
+
+#include <iosfwd>
+#include <string>
+
+#include "zypp/base/PtrTypes.h"
+#include "zypp/base/SafeBool.h"
+#include "zypp/base/Exception.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Match
+ //
+ /** String matching option flags as used e.g. by \ref sat::AttrMatcher.
+ *
+ *
+ *
+ * \code
+ * Match mode( Match::GLOB | Match::NOCASE );
+ * \endcode
+ */
+ class Match : private base::SafeBool<Match>
+ {
+ private:
+ static const int _modemask;
+ static const int _flagmask;
+
+ public:
+ /** Mode flags (mutual exclusive). */
+ enum Mode
+ {
+ NOTHING, //!< Match nothing
+ STRING, //!< Excat matching
+ SUBSTRING, //!< Match substring
+ GLOB, //!< Glob
+ REGEX, //!< Regular Expression
+ OTHER //!< Something else.
+ };
+
+ /** \name Option flags
+ * Some flags are actually \ref sat::LookupAttr specific, as they tell
+ * how to retrieve the attribute values. The plain \ref sat::AttrMatcher
+ * will ignore those flags and use the ones related to string matching only
+ * (like \ref NOCASE).
+ */
+ //@{
+ /** If set, match case insensitive. */
+ static const Match NOCASE;
+ /** internal */
+ static const Match NO_STORAGE_SOLVABLE;
+ /** internal */
+ static const Match SUB;
+ /** internal */
+ static const Match ARRAYSENTINEL;
+ /** If set, skip any \c kind: prefix when looking at a \ref Solvable name. */
+ static const Match SKIP_KIND;
+ /** If set, match full path when matching in filelists, otherwise just the basenames. */
+ static const Match FILES;
+ //@}
+
+ public:
+ /** Default ctor \c 0 or \ref NOTHING. */
+ Match()
+ : _val( 0 )
+ {}
+
+ /** Ctor from \ref Mode value. */
+ Match( Mode val_r )
+ : _val( modeval( val_r ) )
+ {}
+
+ /** Just in case one needs it. */
+ explicit Match( int val_r )
+ : _val( val_r )
+ {}
+
+#ifndef SWIG // Swig treats it as syntax error
+ /** Evaluate in a boolean context <tt>( != 0 )</tt>. */
+ using base::SafeBool<Match>::operator bool_type;
+#endif
+
+ public:
+ /** Test whether \c all of the \a rhs bits are set (same mode if \a rhs has one). */
+ bool test( const Match & rhs ) const
+ { return ( ( flagval() & rhs.flagval() ) == rhs.flagval() )
+ && ( !rhs.modeval() || rhs.modeval() == modeval() ); }
+
+ /** Whether at least one of the \a rhs bits is set (or the same mode). */
+ bool testAnyOf( const Match & rhs ) const
+ { return ( flagval() & rhs.flagval() )
+ || ( rhs.modeval() && rhs.modeval() == modeval() ); }
+
+ /** Set all of the \a rhs bits (setting a new mode if \a rhs has one). */
+ void set( const Match & rhs )
+ {
+ if ( rhs.modeval() )
+ _val = rhs._val | flagval(); // also set the rhs mode
+ else
+ _val |= rhs._val; // just set the flags
+ }
+
+ /** Unset all of the \a rhs bits (unsets mode if the same as \a rhs). */
+ void unset( const Match & rhs )
+ {
+ if ( modeval() == rhs.modeval() )
+ _val = flagval() & ~rhs.flagval(); // also unset mode
+ else
+ _val &= ~rhs.flagval(); // just unset falgs
+ }
+
+ /** Depending on the value of \a onoff, set or unset flags. */
+ void turn( const Match & rhs, bool onoff )
+ { onoff ? set( rhs ) : unset( rhs ); }
+
+ /** Add flags. */
+ Match & operator|=( const Match & rhs )
+ { set( rhs ); return *this; }
+
+ /** Remove flags.*/
+ Match & operator-=( const Match & rhs )
+ { unset( rhs ); return *this; }
+
+ public:
+ /** Return the \c mode part. */
+ Mode mode() const;
+
+ /** Return the \c flags part. */
+ Match flags() const
+ { return Match( flagval() ); }
+
+ public:
+ /** \name Low level integer representation. */
+ //@{
+ /** Return the integer representation. */
+ int get() const { return _val; }
+ /** Return the modes integer representation. */
+ int modeval() const { return _val & _modemask; }
+ /** Return the flags integer representation. */
+ int flagval() const { return _val & _flagmask; }
+ //@}
+
+ public:
+ /** \name Mode flag manip/query convenience. */
+ //@{
+ /** Whether this has mode \a rhs */
+ bool isMode( Mode rhs ) const
+ { return modeval() == modeval( rhs ); }
+ /** Whether this has mode \ref STRING. */
+ bool isModeString() const
+ { return isMode( STRING ); }
+ /** Whether this has mode \ref SUBSTRING. */
+ bool isModeSubstring() const
+ { return isMode( SUBSTRING ); }
+ /** Whether this has mode \ref GLOB. */
+ bool isModeGlob() const
+ { return isMode( GLOB ); }
+ /** Whether this has mode \ref REGEX. */
+ bool isModeRegex() const
+ { return isMode( REGEX ); }
+
+ /** Set the mode part to \a rhs . */
+ void setMode( Mode rhs )
+ { _val = modeval( rhs ) | flagval(); }
+ /** Set the mode \ref STRING. */
+ void setModeString()
+ { setMode( STRING ); }
+ /** Set the mode \ref SUBSTRING. */
+ void setModeSubstring()
+ { setMode( SUBSTRING ); }
+ /** Set the mode \ref GLOB. */
+ void setModeGlob()
+ { setMode( GLOB ); }
+ /** Set the mode \ref REGEX. */
+ void setModeRegex()
+ { setMode( REGEX ); }
+ //@}
+
+ /** String representation. */
+ std::string asString() const;
+
+ private:
+ friend base::SafeBool<Match>::operator bool_type() const;
+ bool boolTest() const { return _val; }
+
+ /** Numeric value for enum (short for <tt>Match(m).get()</tt>). */
+ static int modeval( Mode mode_r );
+
+ private:
+ int _val;
+ };
+
+ /** \relates Match */
+ inline bool operator==( const Match & lhs, const Match & rhs )
+ { return lhs.get() == rhs.get(); }
+ /** \relates Match */
+ inline bool operator!=( const Match & lhs, const Match & rhs )
+ { return lhs.get() != rhs.get(); }
+
+ /** \relates Match */
+ inline Match operator|( const Match & lhs, const Match & rhs )
+ { return Match(lhs) |= rhs; }
+ /** \relates Match \overload to disambiguate 'int|int'. */
+ inline Match operator|( Match::Mode lhs, Match::Mode rhs )
+ { return Match(lhs) |= rhs; }
+
+ /** \relates Match */
+ inline Match operator-( const Match & lhs, const Match & rhs )
+ { return Match(lhs) -= rhs; }
+ /** \relates Match \overload to disambiguate 'int-int'. */
+ inline Match operator-( Match::Mode lhs, Match::Mode rhs )
+ { return Match(lhs) -= rhs; }
+
+ /** \relates Match::Mode Stream output */
+ std::ostream & operator<<( std::ostream & str, Match::Mode obj );
+
+ /** \relates Match Stream output */
+ std::ostream & operator<<( std::ostream & str, const Match & obj );
+
+
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : MatchException
+ //
+ /** Exceptions thrown from attribute matching. */
+ struct MatchException : public Exception
+ {
+ /** Supplied message. */
+ explicit MatchException( const std::string & msg_r ) : Exception( msg_r ) {}
+ };
+
+ /** Unknown match mode. */
+ struct MatchUnknownModeException : public MatchException
+ {
+ /** Supplied message. */
+ explicit MatchUnknownModeException( const std::string & msg_r ) : MatchException( msg_r ) {}
+
+ /** Build message including the \a mode and optional the pattern string. */
+ MatchUnknownModeException( const Match & mode_r, const std::string & msg_r = std::string() );
+ };
+
+ /** Invalid regular expression (failed ::regcomp). */
+ struct MatchInvalidRegexException : public MatchException
+ {
+ /** Supplied message. */
+ explicit MatchInvalidRegexException( const std::string & msg_r ) : MatchException( msg_r ) {}
+
+ /** Build message including the \a regex and \c ::regcomp returncode (use \c 0 if unknown). */
+ MatchInvalidRegexException( const std::string & regex_r, int regcomp_r );
+ };
+
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ namespace sat
+ { /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : AttrMatcher
+ //
+ /** String matching (STRING|SUBSTRING|GLOB|REGEX).
+ *
+ * Used by e.g. \ref PoolQuery and \ref LookupAttr for queries,
+ * but it can also be used for matching arbitrary strings.
+ *
+ * \code
+ * AttrMatcher matches( "foo" );
+ * for_( it, stringlist.begin(), stringlist().end() )
+ * {
+ * if ( matches( *it ) )
+ * cout << *it << " has substring 'foo'" << endl;
+ * }
+ * \endcode
+ *
+ * \Note Those flags are always set: <tt>REG_EXTENDED | REG_NOSUB | REG_NEWLINE</tt>
+ */
+ class AttrMatcher : private base::SafeBool<AttrMatcher>
+ {
+ friend std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj );
+
+ public:
+ typedef MatchException Exception;
+
+ public:
+ /** Implementation */
+ class Impl;
+
+ public:
+ /** Default ctor matches nothing. */
+ AttrMatcher();
+
+ /** Ctor from string matches in \ref Match::STRING mode per default. */
+ AttrMatcher( const std::string & search_r );
+
+ /** Ctor taking string and \ref Match flags. */
+ AttrMatcher( const std::string & search_r, const Match & flags_r );
+
+ /** Low level interface wraps \a flags into \ref Match. */
+ AttrMatcher( const std::string & search_r, int flags_r );
+
+#ifndef SWIG // Swig treats it as syntax error
+ /** Evaluate in a boolean context <tt>( ! searchstring().empty() )</tt>. */
+ using base::SafeBool<AttrMatcher>::operator bool_type;
+#endif
+
+ public:
+ /** Return whether string matches.
+ * You can use it with any class that impements \c c_str.
+ * (\c std::string, \ref Pathname, \ref IdString, ...).
+ * \Note \c NULL never matches.
+ */
+ template<class _Tp>
+ bool operator()( const _Tp & string_r ) const
+ { return doMatch( string_r.c_str() ); }
+ /** \overload */
+ bool operator()( const char * string_r ) const
+ { return doMatch( string_r ); }
+
+ public:
+ /** The current searchstring. */
+ const std::string & searchstring() const;
+
+ /** Set a new searchstring. */
+ void setSearchstring( const std::string & string_r );
+
+ /** Set a new searchstring and flags. */
+ void setSearchstring( const std::string & string_r, const Match & flags_r );
+
+ /** The current search flags. */
+ const Match & flags() const;
+
+ /** Set new search flags. */
+ void setFlags( const Match & flags_r );
+
+ public:
+ /** Compile the pattern e.g. in case of \c REGEX.
+ * \throws MatchUnknownModeException If the \ref Match flag more than
+ * one mode bit set.
+ * \throws MatchInvalidRegexException If \ref Match::REGEX is set
+ * and \ref searchstring is not a valid regular expression.
+ */
+ void compile() const;
+
+ /** Whether the \ref AttrMatcher is already compiled. */
+ bool isCompiled() const;
+
+ /** Return whether string matches.
+ * Compiles the \ref AttrMatcher if this was not yet done.
+ * \throws MatchException Any of the exceptions thrown by \ref AttrMatcher::compile.
+ */
+ bool doMatch( const char * string_r ) const;
+
+ private:
+ friend base::SafeBool<AttrMatcher>::operator bool_type() const;
+ bool boolTest() const
+ { return !searchstring().empty(); }
+
+ private:
+ /** Pointer to implementation */
+ RWCOW_pointer<Impl> _pimpl;
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** \relates AttrMatcher Stream output */
+ std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj );
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace sat
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_SAT_ATTRMATCHER_H
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org