The implementation uses libsolv, but the class is not sat:: specific as it matches arbitrary strings.
INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/tests/zypp )
ADD_TESTS(
- AttrMatcher
IdString
LookupAttr
Pool
#include "TestSetup.h"
#include <zypp/sat/LookupAttr.h>
-#include <zypp/sat/AttrMatcher.h>
+#include <zypp/base/StrMatcher.h>
#include <zypp/ResObjects.h>
static TestSetup test( Arch_x86_64 );
{
sat::LookupAttr q( sat::SolvAttr::name );
- BOOST_CHECK_THROW( q.setAttrMatcher( sat::AttrMatcher("[]ypper",Match::REGEX) ), MatchInvalidRegexException );
- BOOST_CHECK( ! q.attrMatcher() );
- BOOST_CHECK_NO_THROW( q.setAttrMatcher( sat::AttrMatcher("[zZ]ypper",Match::REGEX) ) );
- BOOST_CHECK( q.attrMatcher() );
+ BOOST_CHECK_THROW( q.setStrMatcher( StrMatcher("[]ypper",Match::REGEX) ), MatchInvalidRegexException );
+ BOOST_CHECK( ! q.strMatcher() );
+ BOOST_CHECK_NO_THROW( q.setStrMatcher( StrMatcher("[zZ]ypper",Match::REGEX) ) );
+ BOOST_CHECK( q.strMatcher() );
BOOST_CHECK_EQUAL( q.size(), 9 );
for_(it,q.begin(),q.end())
ResKind
ResStatus
Selectable
+ StrMatcher
Target
Url
Vendor
#include "TestSetup.h"
#include <zypp/sat/LookupAttr.h>
-#include <zypp/sat/AttrMatcher.h>
+#include <zypp/base/StrMatcher.h>
#include <zypp/ResObjects.h>
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//
-// CLASS NAME : AttrMatcher
+// CLASS NAME : StrMatcher
//
///////////////////////////////////////////////////////////////////
-BOOST_AUTO_TEST_CASE(AttrMatcher_defaultconstructed)
+BOOST_AUTO_TEST_CASE(StrMatcher_defaultconstructed)
{
- sat::AttrMatcher m;
+ StrMatcher m;
BOOST_CHECK_EQUAL( m.flags(), Match::NOTHING );
BOOST_CHECK( !m ); // eval in boolean context
BOOST_CHECK( m.searchstring().empty() );
BOOST_CHECK( m ); // eval in boolean context
}
-BOOST_AUTO_TEST_CASE(AttrMatcher_OTHER)
+BOOST_AUTO_TEST_CASE(StrMatcher_OTHER)
{
- sat::AttrMatcher m( "fau", Match::OTHER );
+ StrMatcher m( "fau", Match::OTHER );
BOOST_CHECK_THROW( m.compile(), MatchUnknownModeException );
}
-BOOST_AUTO_TEST_CASE(AttrMatcher_STRING)
+BOOST_AUTO_TEST_CASE(StrMatcher_STRING)
{
- sat::AttrMatcher m( "fau" );
+ StrMatcher m( "fau" );
BOOST_CHECK_EQUAL( m.flags(), Match::STRING );
BOOST_CHECK( !m( "" ) );
BOOST_CHECK( !m( "a" ) );
BOOST_CHECK( !m( "default" ) );
}
-BOOST_AUTO_TEST_CASE(AttrMatcher_STRINGSTART)
+BOOST_AUTO_TEST_CASE(StrMatcher_STRINGSTART)
{
- sat::AttrMatcher m( "fau", Match::STRINGSTART );
+ StrMatcher m( "fau", Match::STRINGSTART );
BOOST_CHECK( !m( "" ) );
BOOST_CHECK( !m( "a" ) );
BOOST_CHECK( m( "fau" ) );
BOOST_CHECK( !m( "default" ) );
}
-BOOST_AUTO_TEST_CASE(AttrMatcher_STRINGEND)
+BOOST_AUTO_TEST_CASE(StrMatcher_STRINGEND)
{
- sat::AttrMatcher m( "fau", Match::STRINGEND );
+ StrMatcher m( "fau", Match::STRINGEND );
BOOST_CHECK( !m( "" ) );
BOOST_CHECK( !m( "a" ) );
BOOST_CHECK( m( "fau" ) );
BOOST_CHECK( !m( "default" ) );
}
-BOOST_AUTO_TEST_CASE(AttrMatcher_REGEX)
+BOOST_AUTO_TEST_CASE(StrMatcher_REGEX)
{
- sat::AttrMatcher m( "fau" );
+ StrMatcher m( "fau" );
BOOST_CHECK( !m.isCompiled() );
BOOST_CHECK_NO_THROW( m.compile() );
}
#if 0
-BOOST_AUTO_TEST_CASE(AttrMatcher_)
+BOOST_AUTO_TEST_CASE(StrMatcher_)
{
base::LogControl::TmpLineWriter shutUp( new log::FileLineWriter( "/tmp/YLOG" ) );
MIL << "GO" << endl;
base/InputStream.cc
base/ReferenceCounted.cc
base/String.cc
+ base/StrMatcher.h
+ base/StrMatcher.cc
base/Regex.cc
base/Unit.cc
base/ExternalDataSource.cc
base/SafeBool.h
base/Signal.h
base/String.h
+ base/StrMatcher.h
base/Regex.h
base/Sysconfig.h
base/Tr1hash.h
sat/LocaleSupport.cc
sat/LookupAttr.cc
sat/SolvAttr.cc
- sat/AttrMatcher.cc
)
SET( zypp_sat_HEADERS
sat/LookupAttr.h
sat/LookupAttrTools.h
sat/SolvAttr.h
- sat/AttrMatcher.h
)
INSTALL( FILES
#include "zypp/sat/Pool.h"
#include "zypp/sat/Solvable.h"
-#include "zypp/sat/AttrMatcher.h"
+#include "zypp/base/StrMatcher.h"
#include "zypp/PoolQuery.h"
/////////////////////////////////////////////////////////////////
/** Match data per attribtue.
*
- * This includes the attribute itself, an optional \ref sat::AttrMatcher
+ * This includes the attribute itself, an optional \ref StrMatcher
* to restrict the query to certain string values, and an optional
* boolean \ref Predicate that may apply further restrictions that can
- * not be expressed by the \ref attrMatcher.
+ * not be expressed by the \ref strMatcher.
*
* Example for such a \ref predicate would be an additional edition range
- * check whan looking for dependencies. The \ref attrMatcher would
+ * check whan looking for dependencies. The \ref strMatcher would
* find potential matches by looking at the dependencies name, the
* predicate will then check the edition ranges.
*
AttrMatchData()
{}
- AttrMatchData( sat::SolvAttr attr_r, const sat::AttrMatcher & attrMatcher_r )
+ AttrMatchData( sat::SolvAttr attr_r, const StrMatcher & strMatcher_r )
: attr( attr_r )
- , attrMatcher( attrMatcher_r )
+ , strMatcher( strMatcher_r )
{}
- AttrMatchData( sat::SolvAttr attr_r, const sat::AttrMatcher & attrMatcher_r,
+ AttrMatchData( sat::SolvAttr attr_r, const StrMatcher & strMatcher_r,
const Predicate & predicate_r, const std::string & predicateStr_r )
: attr( attr_r )
- , attrMatcher( attrMatcher_r )
+ , strMatcher( strMatcher_r )
, predicate( predicate_r )
, predicateStr( predicateStr_r )
{}
{
std::string ret( "AttrMatchData" );
str::appendEscaped( ret, attr.asString() );
- str::appendEscaped( ret, attrMatcher.searchstring() );
+ str::appendEscaped( ret, strMatcher.searchstring() );
// TODO: Actually the flag should be serialized too, but for PoolQuery
// it's by now sufficient to differ between mode OTHER and others,
// i.e. whether to compile or not compile.
- str::appendEscaped( ret, attrMatcher.flags().mode() == Match::OTHER ? "C" : "X" );
+ str::appendEscaped( ret, strMatcher.flags().mode() == Match::OTHER ? "C" : "X" );
str::appendEscaped( ret, predicateStr );
return ret;
}
AttrMatchData ret;
ret.attr = sat::SolvAttr( words[1] );
- ret.attrMatcher = sat::AttrMatcher( words[2] );
+ ret.strMatcher = StrMatcher( words[2] );
if ( words[3] == "C" )
- ret.attrMatcher.setFlags( Match::OTHER );
+ ret.strMatcher.setFlags( Match::OTHER );
ret.predicateStr = words[4];
// now the predicate
}
sat::SolvAttr attr;
- sat::AttrMatcher attrMatcher;
+ StrMatcher strMatcher;
Predicate predicate;
std::string predicateStr;
};
/** \relates AttrMatchData */
inline std::ostream & operator<<( std::ostream & str, const AttrMatchData & obj )
{
- str << obj.attr << ": " << obj.attrMatcher;
+ str << obj.attr << ": " << obj.strMatcher;
if ( obj.predicate )
str << " +(" << obj.predicateStr << ")";
return str;
inline bool operator==( const AttrMatchData & lhs, const AttrMatchData & rhs )
{
return ( lhs.attr == rhs.attr
- && lhs.attrMatcher == rhs.attrMatcher
+ && lhs.strMatcher == rhs.strMatcher
&& lhs.predicateStr == rhs.predicateStr );
}
{
if ( lhs.attr != rhs.attr )
return ( lhs.attr < rhs.attr );
- if ( lhs.attrMatcher != rhs.attrMatcher )
- return ( lhs.attrMatcher < rhs.attrMatcher );
+ if ( lhs.strMatcher != rhs.strMatcher )
+ return ( lhs.strMatcher < rhs.strMatcher );
if ( lhs.predicateStr != rhs.predicateStr )
return ( lhs.predicateStr < rhs.predicateStr );
return false;
public:
/** Compile the regex.
* Basically building the \ref _attrMatchList from strings.
- * \throws MatchException Any of the exceptions thrown by \ref AttrMatcher::compile.
+ * \throws MatchException Any of the exceptions thrown by \ref StrMatcher::compile.
*/
void compile() const;
- /** AttrMatcher per attribtue. */
+ /** StrMatcher per attribtue. */
mutable AttrMatchList _attrMatchList;
private:
if (joined.size() > 1) // switch to regex for multiple strings
cflags.setModeRegex();
_attrMatchList.push_back( AttrMatchData( _attrs.begin()->first,
- sat::AttrMatcher( rcstrings, cflags ) ) );
+ StrMatcher( rcstrings, cflags ) ) );
}
// // MULTIPLE ATTRIBUTES
}
if (joined.size() > 1) // switch to regex for multiple strings
cflags.setModeRegex();
- // May use the same AttrMatcher for all
- sat::AttrMatcher matcher( rcstrings, cflags );
+ // May use the same StrMatcher for all
+ StrMatcher matcher( rcstrings, cflags );
for_( ai, _attrs.begin(), _attrs.end() )
{
_attrMatchList.push_back( AttrMatchData( ai->first, matcher ) );
if (joined.size() > 1) // switch to regex for multiple strings
cflags.setModeRegex();
_attrMatchList.push_back( AttrMatchData( ai->first,
- sat::AttrMatcher( s, cflags ) ) );
+ StrMatcher( s, cflags ) ) );
}
}
}
invokeOnEach( _strings.begin(), _strings.end(), EmptyFilter(), MyInserter(global) );
for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
{
- if ( it->attrMatcher.flags().mode() == Match::OTHER )
+ if ( it->strMatcher.flags().mode() == Match::OTHER )
{
// need to compile:
StrContainer joined( global );
- const std::string & mstr( it->attrMatcher.searchstring() );
+ const std::string & mstr( it->strMatcher.searchstring() );
if ( ! mstr.empty() )
joined.insert( mstr );
cflags.setModeRegex();
_attrMatchList.push_back( AttrMatchData( it->attr,
- sat::AttrMatcher( rcstrings, cflags ),
+ StrMatcher( rcstrings, cflags ),
it->predicate, it->predicateStr ) );
}
else
if ( _strings.size() > 1 ) // switch to regex for multiple strings
cflags.setModeRegex();
_attrMatchList.push_back( AttrMatchData( sat::SolvAttr::allAttr,
- sat::AttrMatcher( rcstrings, cflags ) ) );
+ StrMatcher( rcstrings, cflags ) ) );
}
// Finally check here, whether all involved regex compile.
for_( it, _attrMatchList.begin(), _attrMatchList.end() )
{
- it->attrMatcher.compile(); // throws on error
+ it->strMatcher.compile(); // throws on error
}
//DBG << asString() << endl;
}
// Match::OTHER indicates need to compile
// (merge global search strings into name).
- AttrMatchData attrMatchData( attr, sat::AttrMatcher( name, Match::OTHER ) );
+ AttrMatchData attrMatchData( attr, StrMatcher( name, Match::OTHER ) );
if ( isDependencyAttribute( attr ) )
attrMatchData.addPredicate( EditionRangePredicate( op, edition, arch ) );
return;
// Matches STRING per default. (won't get compiled!)
- AttrMatchData attrMatchData( attr, sat::AttrMatcher( cap.name().asString() ) );
+ AttrMatchData attrMatchData( attr, StrMatcher( cap.name().asString() ) );
if ( isDependencyAttribute( attr ) )
attrMatchData.addPredicate( CapabilityMatchPredicate( cap_r ) );
{
const AttrMatchData & matchData( *mi );
sat::LookupAttr q( matchData.attr, inSolvable );
- if ( matchData.attrMatcher ) // an empty searchstring matches always
- q.setAttrMatcher( matchData.attrMatcher );
+ if ( matchData.strMatcher ) // an empty searchstring matches always
+ q.setStrMatcher( matchData.strMatcher );
if ( ! q.empty() ) // there are matches.
{
_edition = query_r->_edition;
// Status restriction:
_status_flags = query_r->_status_flags;
- // AttrMatcher
+ // StrMatcher
_attrMatchList = query_r->_attrMatchList;
}
{
const AttrMatchData & matchData( _attrMatchList.front() );
q.setAttr( matchData.attr );
- if ( matchData.attrMatcher ) // empty searchstring matches always
- q.setAttrMatcher( matchData.attrMatcher );
+ if ( matchData.strMatcher ) // empty searchstring matches always
+ q.setStrMatcher( matchData.strMatcher );
}
else // more than 1 attr (but not all)
{
{
const AttrMatchData & matchData( *mi );
sat::LookupAttr q( matchData.attr, inSolvable );
- if ( matchData.attrMatcher ) // an empty searchstring matches always
- q.setAttrMatcher( matchData.attrMatcher );
+ if ( matchData.strMatcher ) // an empty searchstring matches always
+ q.setStrMatcher( matchData.strMatcher );
if ( ! q.empty() ) // there are matches.
{
Edition _edition;
/** Installed status filter flags. \see PoolQuery::StatusFilter */
int _status_flags;
- /** AttrMatcher per attribtue. */
+ /** StrMatcher per attribtue. */
AttrMatchList _attrMatchList;
};
///////////////////////////////////////////////////////////////////
#include "zypp/sat/SolvIterMixin.h"
#include "zypp/sat/LookupAttr.h"
-#include "zypp/sat/AttrMatcher.h"
+#include "zypp/base/StrMatcher.h"
#include "zypp/sat/Pool.h"
///////////////////////////////////////////////////////////////////
/// \defgroup ZYPP_STR_REGEX Regular expression matching
/// \brief Regular expressions using the glibc regex library.
///
- /// \see also \ref sat::AttrMatcher string matcher also supporting globing, etc.
+ /// \see also \ref StrMatcher string matcher also supporting globing, etc.
///
/// \code
/// str::regex rxexpr( "^(A)?([0-9]*) im" );
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/base/StrMatcher.cc
+ *
+*/
+extern "C"
+{
+#include <solv/repo.h>
+}
+
+#include <iostream>
+#include <sstream>
+
+#include "zypp/base/LogTools.h"
+#include "zypp/base/Gettext.h"
+#include "zypp/base/String.h"
+
+#include "zypp/base/StrMatcher.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{
+ ///////////////////////////////////////////////////////////////////
+ // class Match
+ ///////////////////////////////////////////////////////////////////
+
+ const int Match::_modemask = SEARCH_STRINGMASK;
+ const int Match::_flagmask = ~_modemask;
+
+ // option flags
+ const Match Match::NOCASE (SEARCH_NOCASE);
+
+ // sat::LookupAttr option flags
+ 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::DISABLED_REPOS (SEARCH_DISABLED_REPOS);
+ const Match Match::COMPLETE_FILELIST (SEARCH_COMPLETE_FILELIST);
+ const Match Match::SKIP_KIND (SEARCH_SKIP_KIND);
+ const Match Match::FILES (SEARCH_FILES);
+ const Match Match::CHECKSUMS (SEARCH_CHECKSUMS);
+
+ Match::Mode Match::mode() const
+ {
+ switch ( modeval() )
+ {
+ case 0: return NOTHING; break;
+ case SEARCH_STRING: return STRING; break;
+ case SEARCH_STRINGSTART: return STRINGSTART; break;
+ case SEARCH_STRINGEND: return STRINGEND; 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 STRINGSTART: return SEARCH_STRINGSTART; break;
+ case STRINGEND: return SEARCH_STRINGEND; 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( STRINGSTART );
+ OUTS( STRINGEND );
+ 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 = "|";
+ Match::Mode mode( obj.mode() );
+ switch ( mode )
+ {
+ case Match::NOTHING:
+ sep = 0; // suppress 'NOTHING|'
+ break;
+ case Match::OTHER:
+ str << mode<<"("<<obj.modeval()<<")"; // check whether libsolv has introduced new modes!
+ break;
+ default:
+ str << mode;
+ break;
+ }
+
+ int val = obj.flagval();
+ if ( val )
+ {
+#define OUTS(V) if ( val & Match::V.get() ) { val &= ~Match::V.get(); if ( sep ) str << sep; else sep = "|"; str << #V; }
+ OUTS( NOCASE );
+ OUTS( NO_STORAGE_SOLVABLE );
+ OUTS( SUB );
+ OUTS( ARRAYSENTINEL );
+ OUTS( DISABLED_REPOS );
+ OUTS( COMPLETE_FILELIST );
+ OUTS( SKIP_KIND );
+ OUTS( FILES );
+ OUTS( CHECKSUMS );
+#undef OUTS
+ if ( val )
+ {
+ if ( sep ) str << sep;
+ str << zypp::str::hexstring( val ); // check whether libsolv has introduced new flags.
+ }
+ }
+ return str;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ // class MatchException
+ ///////////////////////////////////////////////////////////////////
+
+ MatchUnknownModeException::MatchUnknownModeException( const Match & mode_r, const std::string & msg_r )
+ : MatchException( msg_r.empty() ? str::form(_("Unknown match mode '%s'"), mode_r.asString().c_str() )
+ : str::form(_("Unknown match mode '%s' for pattern '%s'"), mode_r.asString().c_str(), msg_r.c_str() ) )
+ {}
+
+ MatchInvalidRegexException::MatchInvalidRegexException( const std::string & regex_r, int regcomp_r )
+ : MatchException( regcomp_r ? str::form(_("Invalid regular expression '%s': regcomp returned %d"), regex_r.c_str(), regcomp_r )
+ : str::form(_("Invalid regular expression '%s'"), regex_r.c_str() ) )
+ {}
+
+ ///////////////////////////////////////////////////////////////////
+ /// \class StrMatcher::Impl
+ /// \brief StrMatcher implementation.
+ ///
+ /// \note Take care to release any allocated regex by calling
+ /// \c ::datamatcher_free.
+ ///////////////////////////////////////////////////////////////////
+ struct StrMatcher::Impl
+ {
+ Impl()
+ {}
+
+ Impl( const std::string & search_r, const Match & flags_r )
+ : _search( search_r )
+ , _flags( flags_r )
+ {}
+
+ ~Impl()
+ { invalidate(); }
+
+ /** Compile the pattern. */
+ void compile() const
+ {
+ if ( !_matcher )
+ {
+ if ( _flags.mode() == Match::OTHER )
+ ZYPP_THROW( MatchUnknownModeException( _flags, _search ) );
+
+ _matcher.reset( new ::_Datamatcher );
+ int res = ::datamatcher_init( _matcher.get(), _search.c_str(), _flags.get() );
+ if ( res )
+ {
+ _matcher.reset();
+ ZYPP_THROW( MatchInvalidRegexException( _search, res ) );
+ }
+ }
+ }
+
+ /** Whether the pattern is already compiled. */
+ bool isCompiled() const
+ { return _matcher; }
+
+ /** Return whether string matches. */
+ bool doMatch( const char * string_r ) const
+ {
+ compile(); // nop if already compiled.
+
+ if ( ! string_r )
+ return false; // NULL never matches
+ return ::datamatcher_match( _matcher.get(), string_r );
+ }
+
+ /** The current searchstring. */
+ const std::string & searchstring() const
+ { return _search; }
+
+ /** Set a new searchstring. */
+ void setSearchstring( const std::string & string_r )
+ { invalidate(); _search = string_r; }
+
+ /** The current search flags. */
+ const Match & flags() const
+ { return _flags; }
+
+ /** Set new search flags. */
+ void setFlags( const Match & flags_r )
+ { invalidate(); _flags = flags_r; }
+
+ private:
+ /** Has to be called if _search or _flags change. */
+ void invalidate()
+ {
+ if ( _matcher )
+ ::datamatcher_free( _matcher.get() );
+ _matcher.reset();
+ }
+
+ private:
+ std::string _search;
+ Match _flags;
+ mutable scoped_ptr< ::_Datamatcher> _matcher;
+
+ private:
+ friend Impl * rwcowClone<Impl>( const Impl * rhs );
+ /** clone for RWCOW_pointer */
+ Impl * clone() const
+ { return new Impl( _search, _flags ); }
+ };
+
+ /** \relates StrMatcher::Impl Stream output */
+ inline std::ostream & operator<<( std::ostream & str, const StrMatcher::Impl & obj )
+ {
+ return str << "\"" << obj.searchstring() << "\"{" << obj.flags() << "}";
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ // class StrMatcher
+ ///////////////////////////////////////////////////////////////////
+
+ StrMatcher::StrMatcher()
+ : _pimpl( new Impl )
+ {}
+
+ StrMatcher::StrMatcher( const std::string & search_r )
+ : _pimpl( new Impl( search_r, Match::STRING ) )
+ {}
+
+ StrMatcher::StrMatcher( const std::string & search_r, const Match & flags_r )
+ : _pimpl( new Impl( search_r, flags_r ) )
+ {}
+
+ StrMatcher::StrMatcher( const std::string & search_r, const Match::Mode & flags_r )
+ : _pimpl( new Impl( search_r, flags_r ) )
+ {}
+
+ StrMatcher::StrMatcher( const std::string & search_r, int flags_r )
+ : _pimpl( new Impl( search_r, Match(flags_r) ) )
+ {}
+
+ void StrMatcher::compile() const
+ { return _pimpl->compile(); }
+
+ bool StrMatcher::isCompiled() const
+ { return _pimpl->isCompiled(); }
+
+ bool StrMatcher::doMatch( const char * string_r ) const
+ { return _pimpl->doMatch( string_r ); }
+
+ const std::string & StrMatcher::searchstring() const
+ { return _pimpl->searchstring(); }
+
+ void StrMatcher::setSearchstring( const std::string & string_r )
+ { _pimpl->setSearchstring( string_r ); }
+
+ void StrMatcher::setSearchstring( const std::string & string_r, const Match & flags_r )
+ {
+ _pimpl->setSearchstring( string_r );
+ _pimpl->setFlags( flags_r );
+ }
+
+ const Match & StrMatcher::flags() const
+ { return _pimpl->flags(); }
+
+ void StrMatcher::setFlags( const Match & flags_r )
+ { _pimpl->setFlags( flags_r ); }
+
+ std::ostream & operator<<( std::ostream & str, const StrMatcher & obj )
+ { return str << *obj._pimpl; }
+
+ bool operator==( const StrMatcher & lhs, const StrMatcher & rhs )
+ {
+ return ( lhs.flags() == rhs.flags()
+ && lhs.searchstring() == rhs.searchstring() );
+ }
+
+ bool operator<( const StrMatcher & lhs, const StrMatcher & rhs )
+ {
+ if ( lhs.flags().get() != rhs.flags().get() )
+ return ( lhs.flags().get() < rhs.flags().get() );
+
+ return ( lhs.searchstring() < rhs.searchstring() );
+ }
+
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/base/StrMatcher.h
+ *
+*/
+#ifndef ZYPP_BASE_STRMATCHER_H
+#define ZYPP_BASE_STRMATCHER_H
+
+#include <iosfwd>
+#include <string>
+
+#include "zypp/base/PtrTypes.h"
+#include "zypp/base/SafeBool.h"
+#include "zypp/base/Exception.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{
+ ///////////////////////////////////////////////////////////////////
+ /// \class Match
+ /// \brief String matching option flags as used e.g. by \ref StrMatcher.
+ ///
+ /// \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
+ STRINGSTART, //!< Match at string start
+ STRINGEND, //!< Match at string end
+ SUBSTRING, //!< Match substring
+ GLOB, //!< Glob
+ REGEX, //!< Regular Expression
+ OTHER //!< Something else.
+ };
+
+ /** \name \ref Option flags
+ * Most flags are actually \ref sat::LookupAttr specific, as they tell
+ * how to retrieve the attribute values from solv-files. The plain
+ * \ref StrMatcher will ignore those flags and use the ones related
+ * to string matching only.
+ */
+ //@{
+ static const Match NOCASE; //!< If set, match case insensitive.
+ //@}
+
+ /** \name \ref sat::LookupAttr option flags
+ * These flags are actually \ref sat::LookupAttr specific, as they tell
+ * how to retrieve the attribute values from solv-files. The plain
+ * \ref StrMatcher will ignore these flags and use the ones related
+ * to string matching only.
+ */
+ //@{
+ static const Match NO_STORAGE_SOLVABLE; //!< LookupAttr: internal
+ static const Match SUB; //!< LookupAttr: internal
+ static const Match ARRAYSENTINEL; //!< LookupAttr: internal
+ static const Match DISABLED_REPOS; //!< LookupAttr: internal
+ static const Match COMPLETE_FILELIST; //!< LookupAttr: internal
+ static const Match SKIP_KIND; //!< LookupAttr: skip any \c kind: prefix when looking at a \ref Solvable name.
+ static const Match FILES; //!< LookupAttr: match full path when matching in filelists, otherwise just the basenames.
+ static const Match CHECKSUMS; //!< LookupAttr: also look for matches in checksums
+ //@}
+
+ 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 STRINGSTART. */
+ bool isModeStringstart() const
+ { return isMode( STRINGSTART ); }
+ /** Whether this has mode \ref STRINGEND. */
+ bool isModeStringend() const
+ { return isMode( STRINGEND ); }
+ /** 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 STRINGSTART. */
+ void setModeStringstart()
+ { setMode( STRINGSTART ); }
+ /** Set the mode \ref STRINGEND. */
+ void setModeStringend()
+ { setMode( STRINGEND ); }
+ /** 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 MatchException
+ /// \brief Exceptions thrown from attribute matching.
+ ///////////////////////////////////////////////////////////////////
+ struct MatchException : public Exception
+ {
+ /** Supplied message. */
+ explicit MatchException( const std::string & msg_r ) : Exception( msg_r ) {}
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ /// \class MatchUnknownModeException
+ /// \brief 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() );
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ /// \class MatchInvalidRegexException
+ /// \brief 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 );
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ /// \class StrMatcher
+ /// \brief 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
+ /// StrMatcher matches( "foo", Match::SUBSTRING );
+ /// 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 StrMatcher : private base::SafeBool<StrMatcher>
+ {
+ friend std::ostream & operator<<( std::ostream & str, const StrMatcher & obj );
+
+ public:
+ typedef MatchException Exception;
+
+ public:
+ /** Implementation */
+ class Impl;
+
+ public:
+ /** Default ctor matches nothing. */
+ StrMatcher();
+
+ /** Ctor from string matches in \ref Match::STRING mode per default. */
+ StrMatcher( const std::string & search_r );
+
+ /** Ctor taking string and \ref Match flags. */
+ StrMatcher( const std::string & search_r, const Match & flags_r );
+
+ /** Ctor taking string and \ref Match::Mode.
+ * Needed because we want them to be treated as \ref Match,
+ * and not as \ref int as the compiler woud do.
+ */
+ StrMatcher( const std::string & search_r, const Match::Mode & flags_r );
+
+ /** Low level interface wraps \a flags into \ref Match. */
+ StrMatcher( 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<StrMatcher>::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 StrMatcher is already compiled. */
+ bool isCompiled() const;
+
+ /** Return whether string matches.
+ * Compiles the \ref StrMatcher if this was not yet done.
+ * \throws MatchException Any of the exceptions thrown by \ref StrMatcher::compile.
+ */
+ bool doMatch( const char * string_r ) const;
+
+ private:
+ friend base::SafeBool<StrMatcher>::operator bool_type() const;
+ bool boolTest() const
+ { return !searchstring().empty(); }
+
+ private:
+ /** Pointer to implementation */
+ RWCOW_pointer<Impl> _pimpl;
+ };
+
+ /** \relates StrMatcher Stream output */
+ std::ostream & operator<<( std::ostream & str, const StrMatcher & obj );
+
+ /** \relates StrMatcher */
+ bool operator==( const StrMatcher & lhs, const StrMatcher & rhs );
+
+ /** \relates StrMatcher */
+ inline bool operator!=( const StrMatcher & lhs, const StrMatcher & rhs )
+ { return !( lhs == rhs ); }
+
+ /** \relates StrMatcher Arbitrary order for std::container. */
+ bool operator<( const StrMatcher & lhs, const StrMatcher & rhs );
+
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_BASE_STRMATCHER_H
+++ /dev/null
-/*---------------------------------------------------------------------\
-| ____ _ __ __ ___ |
-| |__ / \ / / . \ . \ |
-| / / \ V /| _/ _/ |
-| / /__ | | | | | | |
-| /_____||_| |_| |_| |
-| |
-\---------------------------------------------------------------------*/
-/** \file zypp/sat/AttrMatcher.cc
- *
-*/
-extern "C"
-{
-#include <solv/repo.h>
-}
-
-#include <iostream>
-#include <sstream>
-#include <boost/mpl/int.hpp>
-
-#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_STRINGSTART: return STRINGSTART; break;
- case SEARCH_STRINGEND: return STRINGEND; 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 STRINGSTART: return SEARCH_STRINGSTART; break;
- case STRINGEND: return SEARCH_STRINGEND; 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( STRINGSTART );
- OUTS( STRINGEND );
- 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 = "|";
- Match::Mode mode( obj.mode() );
- switch ( mode )
- {
- case Match::NOTHING:
- sep = 0; // suppress 'NOTHING|'
- break;
- case Match::OTHER:
- str << mode<<"("<<obj.modeval()<<")"; // check whether libsolv has introduced new modes!
- break;
- default:
- str << mode;
- break;
- }
-
- int val = obj.flagval();
- if ( val )
- {
-#define OUTS(V) if ( val & Match::V.get() ) { val &= ~Match::V.get(); if ( sep ) str << sep; else sep = "|"; str << #V; }
- OUTS( NOCASE );
- OUTS( NO_STORAGE_SOLVABLE );
- OUTS( SUB );
- OUTS( ARRAYSENTINEL );
- OUTS( SKIP_KIND );
- OUTS( FILES );
-#undef OUTS
- if ( val )
- {
- if ( sep ) str << sep;
- str << zypp::str::hexstring( val ); // check whether libsolv has introduced new flags.
- }
- }
- return str;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : MatchException
- //
- ///////////////////////////////////////////////////////////////////
-
- MatchUnknownModeException::MatchUnknownModeException( const Match & mode_r, const std::string & msg_r )
- : MatchException( msg_r.empty() ? str::form(_("Unknown match mode '%s'"), mode_r.asString().c_str() )
- : str::form(_("Unknown match mode '%s' for pattern '%s'"), mode_r.asString().c_str(), msg_r.c_str() ) )
- {}
-
- MatchInvalidRegexException::MatchInvalidRegexException( const std::string & regex_r, int regcomp_r )
- : MatchException( regcomp_r ? str::form(_("Invalid regular expression '%s': regcomp returned %d"), regex_r.c_str(), regcomp_r )
- : str::form(_("Invalid regular expression '%s'"), regex_r.c_str() ) )
- {}
-
- ///////////////////////////////////////////////////////////////////
- namespace sat
- { /////////////////////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : AttrMatcher::Impl
- //
- /** AttrMatcher implementation.
- *
- * Take care to release any allocated regex by calling
- * \c ::datamatcher_free.
- */
- struct AttrMatcher::Impl
- {
- Impl()
- {}
-
- Impl( const std::string & search_r, const Match & flags_r )
- : _search( search_r )
- , _flags( flags_r )
- {}
-
- ~Impl()
- { invalidate(); }
-
- /** Compile the pattern. */
- void compile() const
- {
- if ( !_matcher )
- {
- if ( _flags.mode() == Match::OTHER )
- ZYPP_THROW( MatchUnknownModeException( _flags, _search ) );
-
- _matcher.reset( new ::_Datamatcher );
- int res = ::datamatcher_init( _matcher.get(), _search.c_str(), _flags.get() );
- if ( res )
- {
- _matcher.reset();
- ZYPP_THROW( MatchInvalidRegexException( _search, res ) );
- }
- }
- }
-
- /** Whether the pattern is already compiled. */
- bool isCompiled() const
- { return _matcher; }
-
- /** Return whether string matches. */
- bool doMatch( const char * string_r ) const
- {
- compile(); // nop if already compiled.
-
- if ( ! string_r )
- return false; // NULL never matches
- return ::datamatcher_match( _matcher.get(), string_r );
- }
-
- /** The current searchstring. */
- const std::string & searchstring() const
- { return _search; }
-
- /** Set a new searchstring. */
- void setSearchstring( const std::string & string_r )
- { invalidate(); _search = string_r; }
-
- /** The current search flags. */
- const Match & flags() const
- { return _flags; }
-
- /** Set new search flags. */
- void setFlags( const Match & flags_r )
- { invalidate(); _flags = flags_r; }
-
- private:
- /** Has to be called if _search or _flags change. */
- void invalidate()
- {
- if ( _matcher )
- ::datamatcher_free( _matcher.get() );
- _matcher.reset();
- }
-
- private:
- std::string _search;
- Match _flags;
- mutable scoped_ptr< ::_Datamatcher> _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, const Match::Mode & 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;
- }
-
- bool operator==( const AttrMatcher & lhs, const AttrMatcher & rhs )
- {
- return ( lhs.flags() == rhs.flags()
- && lhs.searchstring() == rhs.searchstring() );
- }
-
- bool operator<( const AttrMatcher & lhs, const AttrMatcher & rhs )
- {
- if ( lhs.flags().get() != rhs.flags().get() )
- return ( lhs.flags().get() < rhs.flags().get() );
-
- return ( lhs.searchstring() < rhs.searchstring() );
- }
-
- /////////////////////////////////////////////////////////////////
- } // namespace sat
- ///////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////
-} // namespace zypp
-///////////////////////////////////////////////////////////////////
*/
#ifndef ZYPP_SAT_ATTRMATCHER_H
#define ZYPP_SAT_ATTRMATCHER_H
+#warning sat::AttrMatcher was renamed to StrMatcher. Deprecated include of zypp/sat/AttrMatcher.h use zypp/base/StrMatcher.h
-extern "C"
-{
-struct _Datamatcher;
-}
-
-#include <iosfwd>
-#include <string>
-
-#include "zypp/base/PtrTypes.h"
-#include "zypp/base/SafeBool.h"
-#include "zypp/base/Exception.h"
+#include "zypp/base/StrMatcher.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
- STRINGSTART, //!< Match at string start
- STRINGEND, //!< Match at string end
- 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 STRINGSTART. */
- bool isModeStringstart() const
- { return isMode( STRINGSTART ); }
- /** Whether this has mode \ref STRINGEND. */
- bool isModeStringend() const
- { return isMode( STRINGEND ); }
- /** 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 STRINGSTART. */
- void setModeStringstart()
- { setMode( STRINGSTART ); }
- /** Set the mode \ref STRINGEND. */
- void setModeStringend()
- { setMode( STRINGEND ); }
- /** 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 );
-
- /** Ctor taking string and \ref Match::Mode.
- * Needed because we want them to be treated as \ref Match,
- * and not as \ref int as the compiler woud do.
- */
- AttrMatcher( const std::string & search_r, const Match::Mode & 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 );
-
- /** \relates AttrMatcher */
- bool operator==( const AttrMatcher & lhs, const AttrMatcher & rhs );
-
- /** \relates AttrMatcher */
- inline bool operator!=( const AttrMatcher & lhs, const AttrMatcher & rhs )
- { return !( lhs == rhs ); }
-
- /** \relates AttrMatcher Arbitrary order for std::container. */
- bool operator<( const AttrMatcher & lhs, const AttrMatcher & rhs );
+ {
+ typedef StrMatcher AttrMatcher;
- /////////////////////////////////////////////////////////////////
} // namespace sat
///////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
#endif // ZYPP_SAT_ATTRMATCHER_H
#include "zypp/sat/Pool.h"
#include "zypp/sat/LookupAttr.h"
-#include "zypp/sat/AttrMatcher.h"
+#include "zypp/base/StrMatcher.h"
#include "zypp/CheckSum.h"
_parent = p;
}
- const AttrMatcher & attrMatcher() const
- { return _attrMatcher; }
+ const StrMatcher & strMatcher() const
+ { return _strMatcher; }
- void setAttrMatcher( const AttrMatcher & matcher_r )
+ void setStrMatcher( const StrMatcher & matcher_r )
{
matcher_r.compile();
- _attrMatcher = matcher_r;
+ _strMatcher = matcher_r;
}
public:
else if ( _repo )
whichRepo = _repo.id();
- detail::DIWrap dip( whichRepo, _solv.id(), _attr.id(), _attrMatcher.searchstring(), _attrMatcher.flags().get() );
+ detail::DIWrap dip( whichRepo, _solv.id(), _attr.id(), _strMatcher.searchstring(), _strMatcher.flags().get() );
if ( _parent != SolvAttr::noAttr )
::dataiterator_prepend_keyname( dip.get(), _parent.id() );
SolvAttr _parent;
Repository _repo;
Solvable _solv;
- AttrMatcher _attrMatcher;
+ StrMatcher _strMatcher;
private:
friend Impl * rwcowClone<Impl>( const Impl * rhs );
void LookupAttr::setAttr( SolvAttr attr_r )
{ _pimpl->setAttr( attr_r ); }
- const AttrMatcher & LookupAttr::attrMatcher() const
- { return _pimpl->attrMatcher(); }
+ const StrMatcher & LookupAttr::strMatcher() const
+ { return _pimpl->strMatcher(); }
- void LookupAttr::setAttrMatcher( const AttrMatcher & matcher_r )
- { _pimpl->setAttrMatcher( matcher_r ); }
+ void LookupAttr::setStrMatcher( const StrMatcher & matcher_r )
+ { _pimpl->setStrMatcher( matcher_r ); }
///////////////////////////////////////////////////////////////////
class CheckSum;
class Match;
class MatchException;
+ class StrMatcher;
///////////////////////////////////////////////////////////////////
namespace sat
{ /////////////////////////////////////////////////////////////////
- class AttrMatcher;
-
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : LookupAttr
/** \name Restrict attributes to match a pattern. */
//@{
/** The pattern to match.
- * You can also evaluate \ref AttrMatcher in a boolean context,
- * in order to test whether an \ref AttrMatcher is set:
+ * You can also evaluate \ref StrMatcher in a boolean context,
+ * in order to test whether an \ref StrMatcher is set:
* \code
* LookupAttr q;
- * if ( q.attrMatcher() )
- * ...; // an AttrMatcher is set
+ * if ( q.strMatcher() )
+ * ...; // an StrMatcher is set
* \endcode
*/
- const AttrMatcher & attrMatcher() const;
+ const StrMatcher & strMatcher() const;
/** Set the pattern to match.
- * \throws MatchException Any of the exceptions thrown by \ref AttrMatcher::compile.
+ * \throws MatchException Any of the exceptions thrown by \ref StrMatcher::compile.
*/
- void setAttrMatcher( const AttrMatcher & matcher_r );
+ void setStrMatcher( const StrMatcher & matcher_r );
/** Reset the pattern to match. */
- void resetAttrMatcher();
+ void resetStrMatcher();
//@}
public: