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)
414 && _kinds == rhs.
_kinds );
425 void compile()
const;
435 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
438 {
return new Impl( *
this ); }
447 bool operator()(
const string & str)
459 bool operator()(
const string & str)
465 void PoolQuery::Impl::compile()
const
467 _attrMatchList.clear();
469 Match cflags( _flags );
470 if ( cflags.
mode() == Match::OTHER )
495 else if (_attrs.size() == 1)
500 rcstrings = createRegex(joined, cflags);
501 if (joined.size() > 1)
503 _attrMatchList.push_back( AttrMatchData( _attrs.begin()->first,
511 bool attrvals_empty =
true;
512 for (AttrRawStrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end(); ++ai)
513 if (!ai->second.empty())
514 for(StrContainer::const_iterator it = ai->second.begin();
515 it != ai->second.end(); it++)
518 attrvals_empty =
false;
519 goto attremptycheckend;
524 bool attrvals_thesame =
true;
525 AttrRawStrMap::const_iterator ai = _attrs.begin();
528 for (; ai != _attrs.end(); ++ai)
532 set1.begin(), set1.end(),
533 ai->second.begin(), ai->second.end(),
534 inserter(result, result.begin()));
537 attrvals_thesame =
false;
546 if (attrvals_empty || attrvals_thesame)
552 rcstrings = createRegex(joined, cflags);
558 rcstrings = createRegex(joined, cflags);
560 if (joined.size() > 1)
564 for_( ai, _attrs.begin(), _attrs.end() )
566 _attrMatchList.push_back( AttrMatchData( ai->first, matcher ) );
576 for_(ai, _attrs.begin(), _attrs.end())
581 string s = createRegex(joined, cflags);
582 if (joined.size() > 1)
584 _attrMatchList.push_back( AttrMatchData( ai->first,
591 if ( ! _uncompiledPredicated.empty() )
595 for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
597 if ( it->strMatcher.flags().mode() == Match::OTHER )
601 const std::string & mstr( it->strMatcher.searchstring() );
602 if ( ! mstr.empty() )
603 joined.insert( mstr );
606 rcstrings = createRegex( joined, cflags );
607 if ( joined.size() > 1 )
610 _attrMatchList.push_back( AttrMatchData( it->attr,
612 it->predicate, it->predicateStr ) );
617 _attrMatchList.push_back( *it );
623 if ( _attrMatchList.empty() )
626 rcstrings = createRegex( _strings, cflags );
627 if ( _strings.size() > 1 )
629 _attrMatchList.push_back( AttrMatchData( sat::SolvAttr::allAttr,
634 for_( it, _attrMatchList.begin(), _attrMatchList.end() )
636 it->strMatcher.compile();
647 string regexed = str;
654 for (pos = 0; (pos = regexed.find(
"*", pos)) != std::string::npos; pos+=2)
655 regexed = regexed.replace(pos, 1, r_all);
658 for (pos = 0; (pos = regexed.find(
'?', pos)) != std::string::npos; ++pos)
659 regexed = regexed.replace(pos, 1, r_one);
664 string PoolQuery::Impl::createRegex(
const StrContainer & container,
const Match & flags )
const
667 #define WB (_match_word ? string("\\b") : string())
670 if (container.empty())
673 if (container.size() == 1)
675 return WB + *container.begin() +
WB;
681 StrContainer::const_iterator it = container.begin();
692 tmp +=
".*" +
WB + tmp;
693 rstr =
"(?=" + tmp +
")";
699 rstr +=
WB +
"(" + tmp;
704 for (; it != container.end(); ++it)
714 tmp +=
".*" +
WB + tmp;
715 rstr +=
"(?=" + tmp +
")";
744 if ( _kinds.empty() )
748 for(Kinds::const_iterator it = _kinds.begin();
749 it != _kinds.end(); ++it)
755 if ( _repos.empty() )
759 for(StrContainer::const_iterator it = _repos.begin();
760 it != _repos.end(); ++it)
765 o <<
"version: "<< _op <<
" " << _edition.asString() << endl;
766 o <<
"status: " << ( _status_flags ? ( _status_flags == INSTALLED_ONLY ?
"INSTALLED_ONLY" :
"UNINSTALLED_ONLY" )
769 o <<
"string match flags: " <<
Match(_flags) << endl;
773 for(StrContainer::const_iterator it = _strings.begin();
774 it != _strings.end(); ++it)
778 o <<
"attributes: " << endl;
779 for(AttrRawStrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end(); ++ai)
781 o <<
"* " << ai->first <<
": ";
782 for(StrContainer::const_iterator vi = ai->second.begin();
783 vi != ai->second.end(); ++vi)
788 o <<
"predicated: " << endl;
789 for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
791 o <<
"* " << *it << endl;
795 o <<
"last attribute matcher compiled: " << endl;
796 if ( _attrMatchList.empty() )
798 o <<
"not yet compiled" << endl;
802 for_( it, _attrMatchList.begin(), _attrMatchList.end() )
804 o <<
"* " << *it << endl;
818 PoolQuery::PoolQuery()
827 if (repoalias.empty())
829 WAR <<
"ignoring an empty repository alias" << endl;
870 if ( isDependencyAttribute( attr ) )
871 attrMatchData.addPredicate( EditionRangePredicate( op, edition, arch ) );
873 attrMatchData.addPredicate( SolvableRangePredicate( op, edition, arch ) );
887 if ( isDependencyAttribute( attr ) )
888 attrMatchData.addPredicate( CapabilityMatchPredicate( cap_r ) );
890 attrMatchData.addPredicate( SolvableRangePredicate( cap.
op(), cap.
ed() ) );
941 AttrRawStrMap::const_iterator it =
_pimpl->
_attrs.find(attr);
942 return it !=
_pimpl->
_attrs.end() ? it->second : nocontainer;
1097 bool finded_something =
false;
1105 if ((!s.empty()) && s[0]==
'#')
1111 if (s.empty() || pos == s.npos)
1113 if (finded_something)
1123 finded_something =
true;
1125 string attrName(
str::trim(
string(s,0,pos)));
1126 string attrValue(
str::trim(
string(s,pos+1,s.npos)));
1130 MIL <<
"attribute name: " << attrName << endl;
1142 || attribute==
"global_string")
1147 || attribute==
"string_type" )
1172 WAR <<
"unknown string type " << attrValue << endl;
1176 WAR <<
"forget recover some attribute defined as String type attribute: " << attrValue << endl;
1191 WAR <<
"unknown boolean value " << attrValue << endl;
1206 WAR <<
"unknown boolean value " << attrValue << endl;
1211 if( attrValue ==
"all" )
1215 else if( attrValue ==
"installed" )
1219 else if( attrValue ==
"not-installed" )
1225 WAR <<
"Unknown value for install status " << attrValue << endl;
1232 if (attrValue.find_first_of(
"=<>!") == 0)
1234 pos = attrValue.find_last_of(
"=<>");
1235 rel =
Rel(attrValue.substr(0, pos+1));
1236 attrValue =
str::trim(attrValue.substr(pos+1, attrValue.npos));
1255 WAR <<
"empty attribute name" << endl;
1259 string s = attrName;
1262 if ( a == SolvAttr::name || isDependencyAttribute( a ) )
1277 return finded_something;
1289 str <<
"repo: " << *it << delim ;
1295 << it->idStr() << delim ;
1310 <<
": substring" << delim;
1325 str <<
"case_sensitive: ";
1328 str <<
"on" << delim;
1332 str <<
"off" << delim;
1338 str <<
"require_all: ";
1341 str <<
"on" << delim;
1345 str <<
"off" << delim;
1354 str <<
"install_status: all" << delim;
1357 str <<
"install_status: installed" << delim;
1360 str <<
"install_status: not-installed" << delim;
1372 string s = it->first.asString();
1374 for_( it2,it->second.begin(),it->second.end() )
1376 str << s <<
": "<< *it2 << delim;
1382 str <<
"complex: "<< it->serialize() << delim;
1439 if ( base_r ==
end() )
1447 while ( base_r !=
end() )
1462 if ( base_r ==
end() )
1474 return_r.push_back( base );
1477 for ( ++base; base.
inSolvable() == inSolvable; ++base )
1480 return_r.push_back( base );
1488 const AttrMatchData & matchData( *mi );
1490 if ( matchData.strMatcher )
1496 const AttrMatchData::Predicate &
predicate( matchData.predicate );
1500 return_r.push_back( it );
1518 for_( it, query_r->_repos.begin(), query_r->_repos.end() )
1532 _kinds = query_r->_kinds;
1555 if (
_repos.size() == 1 )
1564 if ( matchData.strMatcher )
1636 const AttrMatchData & matchData( *mi );
1638 if ( matchData.strMatcher )
1644 const AttrMatchData::Predicate &
predicate( matchData.predicate );
1686 if ( !
_matcher->advance( base_reference() ) )
1710 if ( ! obj.matchesEmpty() )
1712 for_( it, obj.matchesBegin(), obj.matchesEnd() )
1714 str << endl <<
" " << it->inSolvAttr() <<
"\t" << it->asString();