X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=zypp%2FPoolQuery.cc;h=94489ffe59fb7d7313d6664f9685bcfe4fc91d57;hb=48046fb4ac6b1d63d5031ddc51b9dab8c6b6fd8a;hp=4e286b21f45e64c569793a8ae372d7ed734d4d93;hpb=63cf187f9e87bed304d125f4ca504be0f273ac2b;p=platform%2Fupstream%2Flibzypp.git diff --git a/zypp/PoolQuery.cc b/zypp/PoolQuery.cc index 4e286b2..94489ff 100644 --- a/zypp/PoolQuery.cc +++ b/zypp/PoolQuery.cc @@ -357,7 +357,6 @@ namespace zypp Impl() : _flags( Match::SUBSTRING | Match::NOCASE | Match::SKIP_KIND ) , _match_word(false) - , _require_all(false) , _status_flags(ALL) {} @@ -380,7 +379,6 @@ namespace zypp /** Sat solver search flags */ Match _flags; bool _match_word; - bool _require_all; /** Sat solver status flags */ StatusFilter _status_flags; @@ -417,7 +415,6 @@ namespace zypp && _attrs == rhs._attrs && _uncompiledPredicated == rhs._uncompiledPredicated && _match_word == rhs._match_word - && _require_all == rhs._require_all && _status_flags == rhs._status_flags && _edition == rhs._edition && _op == rhs._op @@ -441,8 +438,10 @@ namespace zypp mutable AttrMatchList _attrMatchList; private: - /** Pass flags from \ref compile, as they may have been changed. */ - string createRegex( const StrContainer & container, const Match & flags ) const; + /** Join patterns in \a container_r according to \a flags_r into a single \ref StrMatcher. + * The \ref StrMatcher returned will be a REGEX if more than one pattern was passed. + */ + StrMatcher joinedStrMatcher( const StrContainer & container_r, const Match & flags_r ) const; private: friend Impl * rwcowClone( const Impl * rhs ); @@ -479,13 +478,8 @@ namespace zypp { _attrMatchList.clear(); - Match cflags( _flags ); - if ( cflags.mode() == Match::OTHER ) // this will never succeed... - ZYPP_THROW( MatchUnknownModeException( cflags ) ); - - /** Compiled search strings. */ - string rcstrings; - + if ( _flags.mode() == Match::OTHER ) // this will never succeed... + ZYPP_THROW( MatchUnknownModeException( _flags ) ); // 'different' - will have to iterate through all and match by ourselves (slow) // 'same' - will pass the compiled string to dataiterator_init @@ -510,11 +504,8 @@ namespace zypp StrContainer joined; invokeOnEach(_strings.begin(), _strings.end(), EmptyFilter(), MyInserter(joined)); invokeOnEach(_attrs.begin()->second.begin(), _attrs.begin()->second.end(), EmptyFilter(), MyInserter(joined)); - rcstrings = createRegex(joined, cflags); - if (joined.size() > 1) // switch to regex for multiple strings - cflags.setModeRegex(); - _attrMatchList.push_back( AttrMatchData( _attrs.begin()->first, - StrMatcher( rcstrings, cflags ) ) ); + + _attrMatchList.push_back( AttrMatchData( _attrs.begin()->first, joinedStrMatcher( joined, _flags ) ) ); } // // MULTIPLE ATTRIBUTES @@ -522,16 +513,21 @@ namespace zypp { // check whether there are any per-attribute strings bool attrvals_empty = true; - for (AttrRawStrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end(); ++ai) - if (!ai->second.empty()) - for(StrContainer::const_iterator it = ai->second.begin(); - it != ai->second.end(); it++) - if (!it->empty()) - { - attrvals_empty = false; - goto attremptycheckend; - } -attremptycheckend: + for_( ai, _attrs.begin(), _attrs.end() ) + { + if ( ai->second.empty() ) + continue; + for_( it, ai->second.begin(), ai->second.end() ) + { + if ( !it->empty() ) + { + attrvals_empty = false; + break; + } + } + if ( ! attrvals_empty ) + break; + } // chceck whether the per-attribute strings are all the same bool attrvals_thesame = true; @@ -562,18 +558,15 @@ attremptycheckend: if (attrvals_empty) { invokeOnEach(_strings.begin(), _strings.end(), EmptyFilter(), MyInserter(joined)); - rcstrings = createRegex(joined, cflags); } else { invokeOnEach(_strings.begin(), _strings.end(), EmptyFilter(), MyInserter(joined)); invokeOnEach(_attrs.begin()->second.begin(), _attrs.begin()->second.end(), EmptyFilter(), MyInserter(joined)); - rcstrings = createRegex(joined, cflags); } - if (joined.size() > 1) // switch to regex for multiple strings - cflags.setModeRegex(); + // May use the same StrMatcher for all - StrMatcher matcher( rcstrings, cflags ); + StrMatcher matcher( joinedStrMatcher( joined, _flags ) ); for_( ai, _attrs.begin(), _attrs.end() ) { _attrMatchList.push_back( AttrMatchData( ai->first, matcher ) ); @@ -591,11 +584,8 @@ attremptycheckend: StrContainer joined; invokeOnEach(_strings.begin(), _strings.end(), EmptyFilter(), MyInserter(joined)); invokeOnEach(ai->second.begin(), ai->second.end(), EmptyFilter(), MyInserter(joined)); - string s = createRegex(joined, cflags); - if (joined.size() > 1) // switch to regex for multiple strings - cflags.setModeRegex(); - _attrMatchList.push_back( AttrMatchData( ai->first, - StrMatcher( s, cflags ) ) ); + + _attrMatchList.push_back( AttrMatchData( ai->first, joinedStrMatcher( joined, _flags ) ) ); } } } @@ -615,14 +605,10 @@ attremptycheckend: if ( ! mstr.empty() ) joined.insert( mstr ); - cflags = _flags; - rcstrings = createRegex( joined, cflags ); - if ( joined.size() > 1 ) // switch to regex for multiple strings - cflags.setModeRegex(); - - _attrMatchList.push_back( AttrMatchData( it->attr, - StrMatcher( rcstrings, cflags ), - it->predicate, it->predicateStr ) ); + // copy and exchange the StrMatcher + AttrMatchData nattr( *it ); + nattr.strMatcher = joinedStrMatcher( joined, _flags ); + _attrMatchList.push_back( std::move(nattr) ); } else { @@ -635,12 +621,7 @@ attremptycheckend: // If no attributes defined at all, then add 'query all' if ( _attrMatchList.empty() ) { - cflags = _flags; - rcstrings = createRegex( _strings, cflags ); - if ( _strings.size() > 1 ) // switch to regex for multiple strings - cflags.setModeRegex(); - _attrMatchList.push_back( AttrMatchData( sat::SolvAttr::allAttr, - StrMatcher( rcstrings, cflags ) ) ); + _attrMatchList.push_back( AttrMatchData( sat::SolvAttr::allAttr, joinedStrMatcher( _strings, _flags ) ) ); } // Finally check here, whether all involved regex compile. @@ -651,102 +632,62 @@ attremptycheckend: //DBG << asString() << endl; } - - /** - * Converts '*' and '?' wildcards within str into their regex equivalents. - */ - static string wildcards2regex(const string & str) - { - string regexed = str; - - string r_all(".*"); // regex equivalent of '*' - string r_one("."); // regex equivalent of '?' - string::size_type pos; - - // replace all "*" in input with ".*" - for (pos = 0; (pos = regexed.find("*", pos)) != std::string::npos; pos+=2) - regexed = regexed.replace(pos, 1, r_all); - - // replace all "?" in input with "." - for (pos = 0; (pos = regexed.find('?', pos)) != std::string::npos; ++pos) - regexed = regexed.replace(pos, 1, r_one); - - return regexed; - } - - string PoolQuery::Impl::createRegex( const StrContainer & container, const Match & flags ) const + /////////////////////////////////////////////////////////////////// + namespace { -//! macro for word boundary tags for regexes -#define WB (_match_word ? string("\\b") : string()) - string rstr; - - if (container.empty()) - return rstr; - - if (container.size() == 1) + /** Escape \a str_r for use in a regex. + * \a flags_r determines whether the input string is interpreted + * as regex, glob or plain string. + */ + std::string rxEscape( std::string str_r, const Match & flags_r ) { - return WB + *container.begin() + WB; - } - - // multiple strings + if ( str_r.empty() || flags_r.isModeRegex() ) + return str_r; - bool use_wildcards = flags.isModeGlob(); - StrContainer::const_iterator it = container.begin(); - string tmp; + if ( flags_r.isModeGlob() ) + return str::rxEscapeGlob( std::move(str_r) ); - if (use_wildcards) - tmp = wildcards2regex(*it); - else - tmp = *it; - - if (_require_all) - { - if ( ! flags.isModeString() ) // not match exact - tmp += ".*" + WB + tmp; - rstr = "(?=" + tmp + ")"; + return str::rxEscapeStr( std::move(str_r) ); } - else - { - if ( flags.isModeString() || flags.isModeGlob() ) - rstr = "^"; - rstr += WB + "(" + tmp; - } - - ++it; + } // namespace + /////////////////////////////////////////////////////////////////// - for (; it != container.end(); ++it) + StrMatcher PoolQuery::Impl::joinedStrMatcher( const StrContainer & container_r, const Match & flags_r ) const + { + if ( container_r.empty() ) + return StrMatcher( std::string(), flags_r ); + + if ( container_r.size() == 1 && !_match_word ) // use RX to match words + return StrMatcher( *container_r.begin(), flags_r ); + + // Convert to a regex. + // Note: Modes STRING and GLOB match whole strings (anchored ^ $) + // SUBSTRING and REGEX match substrings (match_word anchores SUBSTRING \b) + Match retflags( flags_r ); + retflags.setModeRegex(); + str::Str ret; + + if ( flags_r.isModeString() || flags_r.isModeGlob() ) + ret << "^"; + else if ( _match_word ) + ret << "\\b"; + + // (..|..|..) + char sep = '('; + for ( const::std::string & s : container_r ) { - if (use_wildcards) - tmp = wildcards2regex(*it); - else - tmp = *it; - - if (_require_all) - { - if ( ! flags.isModeString() ) // not match exact - tmp += ".*" + WB + tmp; - rstr += "(?=" + tmp + ")"; - } - else - { - rstr += "|" + tmp; - } + ret << sep << rxEscape( s, flags_r ); + if ( sep == '(' ) + sep = '|'; } + ret << ')'; - if (_require_all) - { - if ( ! flags.isModeString() ) // not match exact - rstr += WB + ".*"; - } - else - { - rstr += ")" + WB; - if ( flags.isModeString() || flags.isModeGlob() ) - rstr += "$"; - } + if ( flags_r.isModeString() || flags_r.isModeGlob() ) + ret << "$"; + else if ( _match_word ) + ret << "\\b"; - return rstr; -#undef WB + return StrMatcher( ret, retflags ); } string PoolQuery::Impl::asString() const @@ -911,15 +852,11 @@ attremptycheckend: _pimpl->_op = op; } - void PoolQuery::setMatchSubstring() { _pimpl->_flags.setModeSubstring(); } - void PoolQuery::setMatchExact() { _pimpl->_flags.setModeString(); } - void PoolQuery::setMatchRegex() { _pimpl->_flags.setModeRegex(); } - void PoolQuery::setMatchGlob() { _pimpl->_flags.setModeGlob(); } - void PoolQuery::setMatchWord() - { - _pimpl->_match_word = true; - _pimpl->_flags.setModeRegex(); - } + void PoolQuery::setMatchSubstring() { _pimpl->_flags.setModeSubstring(); _pimpl->_match_word = false; } + void PoolQuery::setMatchExact() { _pimpl->_flags.setModeString(); _pimpl->_match_word = false; } + void PoolQuery::setMatchRegex() { _pimpl->_flags.setModeRegex(); _pimpl->_match_word = false; } + void PoolQuery::setMatchGlob() { _pimpl->_flags.setModeGlob(); _pimpl->_match_word = false; } + void PoolQuery::setMatchWord() { _pimpl->_flags.setModeSubstring(); _pimpl->_match_word = true; } Match PoolQuery::flags() const { return _pimpl->_flags; } @@ -935,10 +872,6 @@ attremptycheckend: { _pimpl->_status_flags = flags; } - void PoolQuery::setRequireAll(bool require_all) - { _pimpl->_require_all = require_all; } - - const PoolQuery::StrContainer & PoolQuery::strings() const { return _pimpl->_strings; } @@ -981,15 +914,10 @@ attremptycheckend: { _pimpl->_flags.turn( Match::FILES, value ); } bool PoolQuery::matchExact() const { return _pimpl->_flags.isModeString(); } - bool PoolQuery::matchSubstring() const { return _pimpl->_flags.isModeSubstring(); } + bool PoolQuery::matchSubstring() const { return _pimpl->_flags.isModeSubstring() && !_pimpl->_match_word; } bool PoolQuery::matchGlob() const { return _pimpl->_flags.isModeGlob(); } bool PoolQuery::matchRegex() const { return _pimpl->_flags.isModeRegex(); } - - bool PoolQuery::matchWord() const - { return _pimpl->_match_word; } - - bool PoolQuery::requireAll() const - { return _pimpl->_require_all; } + bool PoolQuery::matchWord() const { return _pimpl->_flags.isModeSubstring() && _pimpl->_match_word; } PoolQuery::StatusFilter PoolQuery::statusFilterFlags() const { return _pimpl->_status_flags; } @@ -1018,6 +946,9 @@ attremptycheckend: { invokeOnEach( begin(), end(), fnc); } + /*DEPRECATED LEGACY:*/void PoolQuery::setRequireAll( bool ) {} + /*DEPRECATED LEGACY:*/bool PoolQuery::requireAll() const { return false; } + /////////////////////////////////////////////////////////////////// // // CLASS NAME : PoolQuery::Attr @@ -1052,7 +983,7 @@ attremptycheckend: static const PoolQueryAttr kindAttr; static const PoolQueryAttr stringAttr; static const PoolQueryAttr stringTypeAttr; - static const PoolQueryAttr requireAllAttr; + static const PoolQueryAttr requireAllAttr; // LEAGACY: attribute was defined but never implemented. static const PoolQueryAttr caseSensitiveAttr; static const PoolQueryAttr installStatusAttr; static const PoolQueryAttr editionAttr; @@ -1065,7 +996,7 @@ attremptycheckend: const PoolQueryAttr PoolQueryAttr::kindAttr( "type" ); const PoolQueryAttr PoolQueryAttr::stringAttr( "query_string" ); const PoolQueryAttr PoolQueryAttr::stringTypeAttr("match_type"); - const PoolQueryAttr PoolQueryAttr::requireAllAttr("require_all"); + const PoolQueryAttr PoolQueryAttr::requireAllAttr("require_all"); // LEAGACY: attribute was defined but never implemented. const PoolQueryAttr PoolQueryAttr::caseSensitiveAttr("case_sensitive"); const PoolQueryAttr PoolQueryAttr::installStatusAttr("install_status"); const PoolQueryAttr PoolQueryAttr::editionAttr("version"); @@ -1189,18 +1120,8 @@ attremptycheckend: } else if ( attribute==PoolQueryAttr::requireAllAttr ) { - if ( str::strToTrue(attrValue) ) - { - setRequireAll(true); - } - else if ( !str::strToFalse(attrValue) ) - { - setRequireAll(false); - } - else - { - WAR << "unknown boolean value " << attrValue << endl; - } + // LEAGACY: attribute was defined but never implemented. + // Actually it should not occur outside our testcases. } else if ( attribute==PoolQueryAttr::caseSensitiveAttr ) { @@ -1344,19 +1265,6 @@ attremptycheckend: } } - if( requireAll() != q.requireAll() ) - { - str << "require_all: "; - if (requireAll()) - { - str << "on" << delim; - } - else - { - str << "off" << delim; - } - } - if( statusFilterFlags() != q.statusFilterFlags() ) { switch( statusFilterFlags() )