28 #undef ZYPP_BASE_LOGGER_LOGGROUP
29 #define ZYPP_BASE_LOGGER_LOGGROUP "PoolQuery"
32 using namespace zypp::sat;
46 bool isDependencyAttribute( sat::SolvAttr attr_r )
48 static sat::SolvAttr deps[] = {
55 SolvAttr::supplements,
68 struct EditionRangePredicate
70 EditionRangePredicate(
const Rel & op,
const Edition & edition )
74 EditionRangePredicate(
const Rel & op,
const Edition & edition,
const Arch & arch )
79 bool operator()( sat::LookupAttr::iterator iter_r )
81 if ( !
_arch.empty() && iter_r.inSolvable().arch() !=
_arch )
84 CapDetail cap( iter_r.id() );
85 if ( ! cap.isSimple() )
89 return overlaps( Edition::MatchRange( cap.op(), cap.ed() ),
_range );
92 std::string serialize()
const
94 std::string ret(
"EditionRange" );
106 struct SolvableRangePredicate
108 SolvableRangePredicate(
const Rel & op,
const Edition & edition )
113 SolvableRangePredicate(
const Rel & op,
const Edition & edition,
const Arch & arch )
118 bool operator()( sat::LookupAttr::iterator iter_r )
120 if ( !
_arch.empty() && iter_r.inSolvable().arch() !=
_arch )
122 return overlaps( Edition::MatchRange( Rel::EQ, iter_r.inSolvable().edition() ),
_range );
125 std::string serialize()
const
127 std::string ret(
"SolvableRange" );
134 Edition::MatchRange
_range;
142 struct CapabilityMatchPredicate
144 CapabilityMatchPredicate( Capability cap_r )
148 bool operator()( sat::LookupAttr::iterator iter_r )
const
150 return _cap.matches( iter_r.asType<Capability>() ) == CapMatch::yes;
153 std::string serialize()
const
155 std::string ret(
"CapabilityMatch" );
186 typedef function<bool(sat::LookupAttr::iterator)> Predicate;
188 static bool always( sat::LookupAttr::iterator ) {
return true; }
189 static bool never( sat::LookupAttr::iterator ) {
return false; }
194 AttrMatchData( sat::SolvAttr attr_r,
const StrMatcher & strMatcher_r )
199 AttrMatchData( sat::SolvAttr attr_r,
const StrMatcher & strMatcher_r,
200 const Predicate & predicate_r,
const std::string & predicateStr_r )
212 template<
class _Predicate>
213 void addPredicate(
const _Predicate & predicate_r )
224 std::string serialize()
const
226 std::string ret(
"AttrMatchData" );
240 static AttrMatchData
deserialize(
const std::string & str_r )
242 std::vector<std::string> words;
244 if ( words.empty() || words[0] !=
"AttrMatchData" )
245 ZYPP_THROW( Exception( str::Str() <<
"Expecting AttrMatchData: " << str_r ) );
246 if ( words.size() != 5 )
247 ZYPP_THROW( Exception( str::Str() <<
"Wrong number of words: " << str_r ) );
250 ret.attr = sat::SolvAttr( words[1] );
251 ret.strMatcher = StrMatcher( words[2] );
252 if ( words[3] ==
"C" )
253 ret.strMatcher.setFlags( Match::OTHER );
254 ret.predicateStr = words[4];
259 if ( ! words.empty() )
261 if ( words[0] ==
"EditionRange" )
263 switch( words.size() )
266 ret.predicate = EditionRangePredicate( Rel(words[1]), Edition(words[2]) );
269 ret.predicate = EditionRangePredicate( Rel(words[1]), Edition(words[2]), Arch(words[3]) );
272 ZYPP_THROW( Exception( str::Str() <<
"Wrong number of words: " << str_r ) );
276 else if ( words[0] ==
"SolvableRange" )
278 switch( words.size() )
281 ret.predicate = SolvableRangePredicate( Rel(words[1]), Edition(words[2]) );
284 ret.predicate = SolvableRangePredicate( Rel(words[1]), Edition(words[2]), Arch(words[3]) );
287 ZYPP_THROW( Exception( str::Str() <<
"Wrong number of words: " << str_r ) );
291 else if ( words[0] ==
"CapabilityMatch" )
293 if ( words.size() != 2 )
294 ZYPP_THROW( Exception( str::Str() <<
"Wrong number of words: " << str_r ) );
295 ret.predicate = CapabilityMatchPredicate( Capability(words[1]) );
298 ZYPP_THROW( Exception( str::Str() <<
"Unknown predicate: " << str_r ) );
310 inline std::ostream &
operator<<( std::ostream & str,
const AttrMatchData & obj )
312 str << obj.attr <<
": " << obj.strMatcher;
314 str <<
" +(" << obj.predicateStr <<
")";
319 inline bool operator==(
const AttrMatchData & lhs,
const AttrMatchData & rhs )
321 return ( lhs.attr == rhs.attr
322 && lhs.strMatcher == rhs.strMatcher
323 && lhs.predicateStr == rhs.predicateStr );
327 inline bool operator!=(
const AttrMatchData & lhs,
const AttrMatchData & rhs )
328 {
return !( lhs == rhs ); }
331 inline bool operator<(
const AttrMatchData & lhs,
const AttrMatchData & rhs )
333 if ( lhs.attr != rhs.attr )
334 return ( lhs.attr < rhs.attr );
335 if ( lhs.strMatcher != rhs.strMatcher )
336 return ( lhs.strMatcher < rhs.strMatcher );
337 if ( lhs.predicateStr != rhs.predicateStr )
338 return ( lhs.predicateStr < rhs.predicateStr );
342 typedef std::list<AttrMatchData> AttrMatchList;
360 , _require_all(false)
413 && _attrs.size() == 1
414 && _attrs.begin()->first == sat::SolvAttr::name )
425 && _kinds == rhs.
_kinds );
438 void compile()
const;
448 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
451 {
return new Impl( *
this ); }
460 bool operator()(
const string & str)
472 bool operator()(
const string & str)
478 void PoolQuery::Impl::compile()
const
480 _attrMatchList.clear();
482 Match cflags( _flags );
483 if ( cflags.
mode() == Match::OTHER )
508 else if (_attrs.size() == 1)
513 rcstrings = createRegex(joined, cflags);
514 if (joined.size() > 1)
516 _attrMatchList.push_back( AttrMatchData( _attrs.begin()->first,
524 bool attrvals_empty =
true;
525 for (AttrRawStrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end(); ++ai)
526 if (!ai->second.empty())
527 for(StrContainer::const_iterator it = ai->second.begin();
528 it != ai->second.end(); it++)
531 attrvals_empty =
false;
532 goto attremptycheckend;
537 bool attrvals_thesame =
true;
538 AttrRawStrMap::const_iterator ai = _attrs.begin();
541 for (; ai != _attrs.end(); ++ai)
545 set1.begin(), set1.end(),
546 ai->second.begin(), ai->second.end(),
547 inserter(result, result.begin()));
550 attrvals_thesame =
false;
559 if (attrvals_empty || attrvals_thesame)
565 rcstrings = createRegex(joined, cflags);
571 rcstrings = createRegex(joined, cflags);
573 if (joined.size() > 1)
577 for_( ai, _attrs.begin(), _attrs.end() )
579 _attrMatchList.push_back( AttrMatchData( ai->first, matcher ) );
589 for_(ai, _attrs.begin(), _attrs.end())
594 string s = createRegex(joined, cflags);
595 if (joined.size() > 1)
597 _attrMatchList.push_back( AttrMatchData( ai->first,
604 if ( ! _uncompiledPredicated.empty() )
608 for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
610 if ( it->strMatcher.flags().mode() == Match::OTHER )
614 const std::string & mstr( it->strMatcher.searchstring() );
615 if ( ! mstr.empty() )
616 joined.insert( mstr );
619 rcstrings = createRegex( joined, cflags );
620 if ( joined.size() > 1 )
623 _attrMatchList.push_back( AttrMatchData( it->attr,
625 it->predicate, it->predicateStr ) );
630 _attrMatchList.push_back( *it );
636 if ( _attrMatchList.empty() )
639 rcstrings = createRegex( _strings, cflags );
640 if ( _strings.size() > 1 )
642 _attrMatchList.push_back( AttrMatchData( sat::SolvAttr::allAttr,
647 for_( it, _attrMatchList.begin(), _attrMatchList.end() )
649 it->strMatcher.compile();
660 string regexed = str;
667 for (pos = 0; (pos = regexed.find(
"*", pos)) != std::string::npos; pos+=2)
668 regexed = regexed.replace(pos, 1, r_all);
671 for (pos = 0; (pos = regexed.find(
'?', pos)) != std::string::npos; ++pos)
672 regexed = regexed.replace(pos, 1, r_one);
677 string PoolQuery::Impl::createRegex(
const StrContainer & container,
const Match & flags )
const
680 #define WB (_match_word ? string("\\b") : string())
683 if (container.empty())
686 if (container.size() == 1)
688 return WB + *container.begin() +
WB;
694 StrContainer::const_iterator it = container.begin();
705 tmp +=
".*" +
WB + tmp;
706 rstr =
"(?=" + tmp +
")";
712 rstr +=
WB +
"(" + tmp;
717 for (; it != container.end(); ++it)
727 tmp +=
".*" +
WB + tmp;
728 rstr +=
"(?=" + tmp +
")";
757 if ( _kinds.empty() )
761 for(Kinds::const_iterator it = _kinds.begin();
762 it != _kinds.end(); ++it)
768 if ( _repos.empty() )
772 for(StrContainer::const_iterator it = _repos.begin();
773 it != _repos.end(); ++it)
778 o <<
"version: "<< _op <<
" " << _edition.asString() << endl;
779 o <<
"status: " << ( _status_flags ? ( _status_flags == INSTALLED_ONLY ?
"INSTALLED_ONLY" :
"UNINSTALLED_ONLY" )
782 o <<
"string match flags: " <<
Match(_flags) << endl;
786 for(StrContainer::const_iterator it = _strings.begin();
787 it != _strings.end(); ++it)
791 o <<
"attributes: " << endl;
792 for(AttrRawStrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end(); ++ai)
794 o <<
"* " << ai->first <<
": ";
795 for(StrContainer::const_iterator vi = ai->second.begin();
796 vi != ai->second.end(); ++vi)
801 o <<
"predicated: " << endl;
802 for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
804 o <<
"* " << *it << endl;
808 o <<
"last attribute matcher compiled: " << endl;
809 if ( _attrMatchList.empty() )
811 o <<
"not yet compiled" << endl;
815 for_( it, _attrMatchList.begin(), _attrMatchList.end() )
817 o <<
"* " << *it << endl;
831 PoolQuery::PoolQuery()
840 if (repoalias.empty())
842 WAR <<
"ignoring an empty repository alias" << endl;
883 if ( isDependencyAttribute( attr ) )
884 attrMatchData.addPredicate( EditionRangePredicate( op, edition, arch ) );
886 attrMatchData.addPredicate( SolvableRangePredicate( op, edition, arch ) );
900 if ( isDependencyAttribute( attr ) )
901 attrMatchData.addPredicate( CapabilityMatchPredicate( cap_r ) );
903 attrMatchData.addPredicate( SolvableRangePredicate( cap.
op(), cap.
ed() ) );
954 AttrRawStrMap::const_iterator it =
_pimpl->
_attrs.find(attr);
955 return it !=
_pimpl->
_attrs.end() ? it->second : nocontainer;
1110 bool finded_something =
false;
1118 if ((!s.empty()) && s[0]==
'#')
1124 if (s.empty() || pos == s.npos)
1126 if (finded_something)
1136 finded_something =
true;
1138 string attrName(
str::trim(
string(s,0,pos)));
1139 string attrValue(
str::trim(
string(s,pos+1,s.npos)));
1153 || attribute==
"global_string")
1158 || attribute==
"string_type" )
1183 WAR <<
"unknown string type " << attrValue << endl;
1187 WAR <<
"forget recover some attribute defined as String type attribute: " << attrValue << endl;
1202 WAR <<
"unknown boolean value " << attrValue << endl;
1217 WAR <<
"unknown boolean value " << attrValue << endl;
1222 if( attrValue ==
"all" )
1226 else if( attrValue ==
"installed" )
1230 else if( attrValue ==
"not-installed" )
1236 WAR <<
"Unknown value for install status " << attrValue << endl;
1243 if (attrValue.find_first_of(
"=<>!") == 0)
1245 pos = attrValue.find_last_of(
"=<>");
1246 rel =
Rel(attrValue.substr(0, pos+1));
1247 attrValue =
str::trim(attrValue.substr(pos+1, attrValue.npos));
1266 WAR <<
"empty attribute name" << endl;
1270 string s = attrName;
1273 if ( a == SolvAttr::name || isDependencyAttribute( a ) )
1288 return finded_something;
1300 str <<
"repo: " << *it << delim ;
1306 << it->idStr() << delim ;
1321 <<
": substring" << delim;
1336 str <<
"case_sensitive: ";
1339 str <<
"on" << delim;
1343 str <<
"off" << delim;
1349 str <<
"require_all: ";
1352 str <<
"on" << delim;
1356 str <<
"off" << delim;
1365 str <<
"install_status: all" << delim;
1368 str <<
"install_status: installed" << delim;
1371 str <<
"install_status: not-installed" << delim;
1383 string s = it->first.asString();
1385 for_( it2,it->second.begin(),it->second.end() )
1387 str << s <<
": "<< *it2 << delim;
1393 str <<
"complex: "<< it->serialize() << delim;
1450 if ( base_r ==
end() )
1458 while ( base_r !=
end() )
1473 if ( base_r ==
end() )
1485 return_r.push_back( base );
1488 for ( ++base; base.
inSolvable() == inSolvable; ++base )
1491 return_r.push_back( base );
1499 const AttrMatchData & matchData( *mi );
1501 if ( matchData.strMatcher )
1507 const AttrMatchData::Predicate &
predicate( matchData.predicate );
1511 return_r.push_back( it );
1529 for_( it, query_r->_repos.begin(), query_r->_repos.end() )
1543 _kinds = query_r->_kinds;
1566 if (
_repos.size() == 1 )
1575 if ( matchData.strMatcher )
1647 const AttrMatchData & matchData( *mi );
1649 if ( matchData.strMatcher )
1655 const AttrMatchData::Predicate &
predicate( matchData.predicate );
1697 if ( !
_matcher->advance( base_reference() ) )
1721 if ( ! obj.matchesEmpty() )
1723 for_( it, obj.matchesBegin(), obj.matchesEnd() )
1725 str << endl <<
" " << it->inSolvAttr() <<
"\t" << it->asString();