libzypp  17.30.0
PoolQuery.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <sstream>
14 
15 #include <zypp/base/Gettext.h>
16 #include <zypp/base/LogTools.h>
17 #include <zypp/base/Algorithm.h>
18 #include <zypp/base/String.h>
20 #include <zypp/RelCompare.h>
21 
22 #include <zypp/sat/Pool.h>
23 #include <zypp/sat/Solvable.h>
24 #include <zypp/base/StrMatcher.h>
25 
26 #include <zypp/PoolQuery.h>
27 
28 #undef ZYPP_BASE_LOGGER_LOGGROUP
29 #define ZYPP_BASE_LOGGER_LOGGROUP "PoolQuery"
30 
31 using std::endl;
32 using namespace zypp::sat;
33 
35 namespace zypp
36 {
37 
39  namespace
40  {
41 
43  // some Helpers and Predicates
45 
46  bool isDependencyAttribute( sat::SolvAttr attr_r )
47  {
48  static sat::SolvAttr deps[] = {
57  };
58  for_( it, arrayBegin(deps), arrayEnd(deps) )
59  if ( *it == attr_r )
60  return true;
61  return false;
62  }
63 
68  struct EditionRangePredicate
69  {
70  EditionRangePredicate( const Rel & op, const Edition & edition )
71  : _range( op, edition )
72  , _arch( Arch_empty )
73  {}
74  EditionRangePredicate( const Rel & op, const Edition & edition, const Arch & arch )
75  : _range( op, edition )
76  , _arch( arch )
77  {}
78 
79  bool operator()( sat::LookupAttr::iterator iter_r )
80  {
81  if ( !_arch.empty() && iter_r.inSolvable().arch() != _arch )
82  return false;
83 
84  CapDetail cap( iter_r.id() );
85  if ( ! cap.isSimple() )
86  return false;
87  if ( cap.isNamed() ) // no range to match
88  return true;
89  return overlaps( Edition::MatchRange( cap.op(), cap.ed() ), _range );
90  }
91 
92  std::string serialize() const
93  {
94  std::string ret( "EditionRange" );
95  str::appendEscaped( ret, _range.op.asString() );
96  str::appendEscaped( ret, _range.value.asString() );
97  str::appendEscaped( ret, _arch.asString() );
98  return ret;
99  }
100 
102  Arch _arch;
103  };
104 
106  struct SolvableRangePredicate
107  {
108  SolvableRangePredicate( const Rel & op, const Edition & edition )
109  : _range( op, edition )
110  , _arch( Arch_empty )
111  {}
112 
113  SolvableRangePredicate( const Rel & op, const Edition & edition, const Arch & arch )
114  : _range( op, edition )
115  , _arch( arch )
116  {}
117 
118  bool operator()( sat::LookupAttr::iterator iter_r )
119  {
120  if ( !_arch.empty() && iter_r.inSolvable().arch() != _arch )
121  return false;
122  return overlaps( Edition::MatchRange( Rel::EQ, iter_r.inSolvable().edition() ), _range );
123  }
124 
125  std::string serialize() const
126  {
127  std::string ret( "SolvableRange" );
128  str::appendEscaped( ret, _range.op.asString() );
129  str::appendEscaped( ret, _range.value.asString() );
130  str::appendEscaped( ret, _arch.asString() );
131  return ret;
132  }
133 
135  Arch _arch;
136  };
137 
142  struct CapabilityMatchPredicate
143  {
144  CapabilityMatchPredicate( Capability cap_r )
145  : _cap( cap_r )
146  {}
147 
148  bool operator()( sat::LookupAttr::iterator iter_r ) const
149  {
150  return _cap.matches( iter_r.asType<Capability>() ) == CapMatch::yes;
151  }
152 
153  std::string serialize() const
154  {
155  std::string ret( "CapabilityMatch" );
156  str::appendEscaped( ret, _cap.asString() );
157  return ret;
158  }
159 
160  Capability _cap;
161  };
162 
164  //
166 
191  struct AttrMatchData
192  {
193  typedef function<bool(sat::LookupAttr::iterator)> Predicate;
194 
195  static bool always( sat::LookupAttr::iterator ) { return true; }
196  static bool never( sat::LookupAttr::iterator ) { return false; }
197 
198  AttrMatchData()
199  {}
200 
201  AttrMatchData( sat::SolvAttr attr_r )
202  : attr( attr_r )
203  {}
204 
205  AttrMatchData( sat::SolvAttr attr_r, const StrMatcher & strMatcher_r )
206  : attr( attr_r )
207  , strMatcher( strMatcher_r )
208  {}
209 
210  AttrMatchData( sat::SolvAttr attr_r, const StrMatcher & strMatcher_r,
211  const Predicate & predicate_r, const std::string & predicateStr_r )
212  : attr( attr_r )
213  , strMatcher( strMatcher_r )
214  , predicate( predicate_r )
215  , predicateStr( predicateStr_r )
216  {}
217 
223  template<class TPredicate>
224  void addPredicate( const TPredicate & predicate_r )
225  {
226  predicate = predicate_r;
227  predicateStr = predicate_r.serialize();
228  }
229 
235  std::string serialize() const
236  {
237  std::string ret( "AttrMatchData" );
238  str::appendEscaped( ret, attr.asString() );
239  str::appendEscaped( ret, strMatcher.searchstring() );
240  str::appendEscaped( ret, serializeMode( strMatcher.flags().mode() ) );
242  return ret;
243  }
244 
248  static AttrMatchData deserialize( const std::string & str_r )
249  {
250  std::vector<std::string> words;
251  str::splitEscaped( str_r, std::back_inserter(words) );
252  if ( words.empty() || words[0] != "AttrMatchData" )
253  ZYPP_THROW( Exception( str::Str() << "Expecting AttrMatchData: " << str_r ) );
254  if ( words.size() != 5 )
255  ZYPP_THROW( Exception( str::Str() << "Wrong number of words: " << str_r ) );
256 
257  AttrMatchData ret;
258  ret.attr = sat::SolvAttr( words[1] );
259  ret.strMatcher = StrMatcher( words[2] );
260  if ( Match::Mode mode = deserializeMode( words[3] ) )
261  ret.strMatcher.setFlags( mode );
262  ret.predicateStr = words[4];
263 
264  // now the predicate
265  words.clear();
266  str::splitEscaped( ret.predicateStr, std::back_inserter(words) );
267  if ( ! words.empty() )
268  {
269  if ( words[0] == "EditionRange" )
270  {
271  switch( words.size() )
272  {
273  case 3:
274  ret.predicate = EditionRangePredicate( Rel(words[1]), Edition(words[2]) );
275  break;
276  case 4:
277  ret.predicate = EditionRangePredicate( Rel(words[1]), Edition(words[2]), Arch(words[3]) );
278  break;
279  default:
280  ZYPP_THROW( Exception( str::Str() << "Wrong number of words: " << str_r ) );
281  break;
282  }
283  }
284  else if ( words[0] == "SolvableRange" )
285  {
286  switch( words.size() )
287  {
288  case 3:
289  ret.predicate = SolvableRangePredicate( Rel(words[1]), Edition(words[2]) );
290  break;
291  case 4:
292  ret.predicate = SolvableRangePredicate( Rel(words[1]), Edition(words[2]), Arch(words[3]) );
293  break;
294  default:
295  ZYPP_THROW( Exception( str::Str() << "Wrong number of words: " << str_r ) );
296  break;
297  }
298  }
299  else if ( words[0] == "CapabilityMatch" )
300  {
301  if ( words.size() != 2 )
302  ZYPP_THROW( Exception( str::Str() << "Wrong number of words: " << str_r ) );
303  ret.predicate = CapabilityMatchPredicate( Capability(words[1]) );
304  }
305  else
306  ZYPP_THROW( Exception( str::Str() << "Unknown predicate: " << str_r ) );
307  }
308  return ret;
309  }
310 
311  sat::SolvAttr attr;
312  StrMatcher strMatcher;
313  Predicate predicate;
314  std::string predicateStr;
315  ResKind kindPredicate = ResKind::nokind; // holds the 'kind' part if SolvAttr:name looks for an explicit 'kind:name'
316 
317  private:
319  static std::string serializeMode( Match::Mode mode_r )
320  {
321  // Legacy code used "[C|X]" to differ just between OTHER (need to (C)ompile) and
322  // using the default search mode. As we now allow to specify a SEARCHMODE we
323  // need to serialize it:
324  switch ( mode_r )
325  {
326 #define OUTS(M,S) case Match::M: return #S; break
327  // (C)ompile
328  OUTS( OTHER, C );
329  // well known modes:
330  OUTS( STRING, T );
331  OUTS( STRINGSTART, S );
332  OUTS( STRINGEND, E );
333  OUTS( SUBSTRING, B );
334  OUTS( GLOB, G );
335  OUTS( REGEX, R );
336 #undef OUTS
337  // everything else use default
338  case Match::NOTHING:
339  break;
340  }
341  return "X";
342  }
343 
345  static Match::Mode deserializeMode( const std::string & str_r )
346  {
347  switch ( str_r[0] )
348  {
349 #define OUTS(M,C) case *#C: return Match::M; break
350  // (C)ompile
351  OUTS( OTHER, C );
352  // well known modes:
353  OUTS( STRING, T );
354  OUTS( STRINGSTART, S );
355  OUTS( STRINGEND, E );
356  OUTS( SUBSTRING, B );
357  OUTS( GLOB, G );
358  OUTS( REGEX, R );
359 #undef OUTS
360  // everything else use default
361  default:
362  break;
363  }
364  return Match::NOTHING;
365  }
366  };
367 
369  inline std::ostream & operator<<( std::ostream & str, const AttrMatchData & obj )
370  {
371  str << obj.attr << ": " << obj.strMatcher;
372  if ( obj.kindPredicate )
373  str << " +(" << obj.kindPredicate << ")";
374  if ( obj.predicate )
375  str << " +(" << obj.predicateStr << ")";
376  return str;
377  }
378 
380  inline bool operator==( const AttrMatchData & lhs, const AttrMatchData & rhs )
381  {
382  return ( lhs.attr == rhs.attr
383  && lhs.strMatcher == rhs.strMatcher
384  && lhs.predicateStr == rhs.predicateStr );
385  }
386 
388  inline bool operator!=( const AttrMatchData & lhs, const AttrMatchData & rhs )
389  { return !( lhs == rhs ); }
390 
392  inline bool operator<( const AttrMatchData & lhs, const AttrMatchData & rhs )
393  {
394  if ( lhs.attr != rhs.attr )
395  return ( lhs.attr < rhs.attr );
396  if ( lhs.strMatcher != rhs.strMatcher )
397  return ( lhs.strMatcher < rhs.strMatcher );
398  if ( lhs.predicateStr != rhs.predicateStr )
399  return ( lhs.predicateStr < rhs.predicateStr );
400  return false;
401  }
402 
403  typedef std::list<AttrMatchData> AttrMatchList;
404 
405 
406  }
407  // namespace
409 
411  //
412  // CLASS NAME : PoolQuery::Impl
413  //
416  {
417  public:
419  : _flags( Match::SUBSTRING | Match::NOCASE | Match::SKIP_KIND )
420  , _match_word(false)
421  , _status_flags(ALL)
422  {}
423 
425  {}
426 
427  public:
429  std::string asString() const;
430 
438  std::set<AttrMatchData> _uncompiledPredicated;
439 
443 
446 
451 
454 
457 
459  mutable std::string _comment;
461 
462  public:
463 
464  bool operator<( const PoolQuery::Impl & rhs ) const
465  {
466 #define OUTS(A) if ( A != rhs.A ) return A < rhs.A;
467  OUTS( _strings );
468  OUTS( _attrs );
469  OUTS( _uncompiledPredicated );
470  OUTS( _flags.get() );
471  OUTS( _match_word );
472  OUTS( _status_flags );
473  OUTS( _edition );
474  OUTS( _op.inSwitch() );
475  OUTS( _repos );
476  OUTS( _kinds );
477 #undef OUTS
478  return false;
479  }
480 
481  bool operator==( const PoolQuery::Impl & rhs ) const
482  {
483  if ( _flags == rhs._flags
484  // bnc#792901: while libzypp uses exact match mode for a single
485  // package name lock, zypper always uses glob. :(
486  // We unify those two forms to enable zypper to remove zypp locks
487  // without need to actually evaluate the query (which would require
488  // repos to be loaded).
489  || ( ( ( _flags.isModeString() && rhs._flags.isModeGlob() )
490  || ( _flags.isModeGlob() && rhs._flags.isModeString() ) )
491  && _strings.empty()
492  && _attrs.size() == 1
493  && _attrs.begin()->first == sat::SolvAttr::name ) )
494  {
495  // ma: Intentionally a different _comment is not considered.
496  return ( _strings == rhs._strings
497  && _attrs == rhs._attrs
498  && _uncompiledPredicated == rhs._uncompiledPredicated
499  && _match_word == rhs._match_word
500  && _status_flags == rhs._status_flags
501  && _edition == rhs._edition
502  && _op == rhs._op
503  && _repos == rhs._repos
504  && _kinds == rhs._kinds );
505  }
506  return false;
507  }
508 
509  bool operator!=( const PoolQuery::Impl & rhs ) const
510  { return ! operator==( rhs ); }
511 
512  public:
517  void compile() const;
518 
520  mutable AttrMatchList _attrMatchList;
521 
522  private:
526  StrMatcher joinedStrMatcher( const StrContainer & container_r, const Match & flags_r ) const;
527 
528  private:
529  friend Impl * rwcowClone<Impl>( const Impl * rhs );
531  Impl * clone() const
532  { return new Impl( *this ); }
533  };
534 
536 
537  struct MyInserter
538  {
539  MyInserter(PoolQuery::StrContainer & cont) : _cont(cont) {}
540 
541  bool operator()(const std::string & str)
542  {
543  _cont.insert(str);
544  return true;
545  }
546 
548  };
549 
550 
551  struct EmptyFilter
552  {
553  bool operator()(const std::string & str)
554  {
555  return !str.empty();
556  }
557  };
558 
560  {
561  _attrMatchList.clear();
562 
563  if ( _flags.mode() == Match::OTHER ) // this will never succeed...
565 
566  // 'different' - will have to iterate through all and match by ourselves (slow)
567  // 'same' - will pass the compiled string to dataiterator_init
568  // 'one-attr' - will pass it to dataiterator_init
569  // 'one-non-regex-str' - will pass to dataiterator_init, set flag to SEARCH_STRING or SEARCH_SUBSTRING
570 
571  // // NO ATTRIBUTE
572  // else
573  // for all _strings
574  // create regex; store in rcstrings; if more strings flag regex;
575  if (_attrs.empty())
576  {
577  ; // A default 'query-all' will be added after all sources are processed.
578  }
579 
580  // // ONE ATTRIBUTE
581  // else if _attrs is not empty but it contains just one attr
582  // for all _strings and _attr[key] strings
583  // create regex; flag 'one-attr'; if more strings flag regex;
584  else if (_attrs.size() == 1)
585  {
586  StrContainer joined;
587  invokeOnEach(_strings.begin(), _strings.end(), EmptyFilter(), MyInserter(joined));
588  invokeOnEach(_attrs.begin()->second.begin(), _attrs.begin()->second.end(), EmptyFilter(), MyInserter(joined));
589 
590  _attrMatchList.push_back( AttrMatchData( _attrs.begin()->first, joinedStrMatcher( joined, _flags ) ) );
591  }
592 
593  // // MULTIPLE ATTRIBUTES
594  else
595  {
596  // check whether there are any per-attribute strings
597  bool attrvals_empty = true;
598  for_( ai, _attrs.begin(), _attrs.end() )
599  {
600  if ( ai->second.empty() )
601  continue;
602  for_( it, ai->second.begin(), ai->second.end() )
603  {
604  if ( !it->empty() )
605  {
606  attrvals_empty = false;
607  break;
608  }
609  }
610  if ( ! attrvals_empty )
611  break;
612  }
613 
614  // chceck whether the per-attribute strings are all the same
615  bool attrvals_thesame = true;
616  AttrRawStrMap::const_iterator ai = _attrs.begin();
617  const StrContainer & set1 = ai->second;
618  ++ai;
619  for (; ai != _attrs.end(); ++ai)
620  {
621  StrContainer result;
622  set_difference(
623  set1.begin(), set1.end(),
624  ai->second.begin(), ai->second.end(),
625  inserter(result, result.begin())/*, ltstr()*/);
626  if (!result.empty())
627  {
628  attrvals_thesame = false;
629  break;
630  }
631  }
632 
633  // // THE SAME STRINGS FOR DIFFERENT ATTRS
634  // else if _attrs is not empty but it does not contain strings
635  // for each key in _attrs take all _strings
636  // create regex; store in rcstrings; flag 'same'; if more strings flag regex;
637  if (attrvals_empty || attrvals_thesame)
638  {
639  StrContainer joined;
640  if (attrvals_empty)
641  {
642  invokeOnEach(_strings.begin(), _strings.end(), EmptyFilter(), MyInserter(joined));
643  }
644  else
645  {
646  invokeOnEach(_strings.begin(), _strings.end(), EmptyFilter(), MyInserter(joined));
647  invokeOnEach(_attrs.begin()->second.begin(), _attrs.begin()->second.end(), EmptyFilter(), MyInserter(joined));
648  }
649 
650  // May use the same StrMatcher for all
651  StrMatcher matcher( joinedStrMatcher( joined, _flags ) );
652  for_( ai, _attrs.begin(), _attrs.end() )
653  {
654  _attrMatchList.push_back( AttrMatchData( ai->first, matcher ) );
655  }
656  }
657 
658  // // DIFFERENT STRINGS FOR DIFFERENT ATTRS
659  // if _attrs is not empty and it contains non-empty vectors with non-empty strings
660  // for each key in _attrs take all _strings + all _attrs[key] strings
661  // create regex; flag 'different'; if more strings flag regex;
662  else
663  {
664  for_(ai, _attrs.begin(), _attrs.end())
665  {
666  StrContainer joined;
667  invokeOnEach(_strings.begin(), _strings.end(), EmptyFilter(), MyInserter(joined));
668  invokeOnEach(ai->second.begin(), ai->second.end(), EmptyFilter(), MyInserter(joined));
669 
670  _attrMatchList.push_back( AttrMatchData( ai->first, joinedStrMatcher( joined, _flags ) ) );
671  }
672  }
673  }
674 
675  // Now handle any predicated queries
676  if ( ! _uncompiledPredicated.empty() )
677  {
678  StrContainer global;
679  invokeOnEach( _strings.begin(), _strings.end(), EmptyFilter(), MyInserter(global) );
680  for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
681  {
682  if ( it->strMatcher.flags().mode() == Match::OTHER )
683  {
684  // need to compile:
685  StrContainer joined( global );
686  const std::string & mstr( it->strMatcher.searchstring() );
687  if ( ! mstr.empty() )
688  joined.insert( mstr );
689 
690  // copy and exchange the StrMatcher
691  AttrMatchData nattr( *it );
692  nattr.strMatcher = joinedStrMatcher( joined, _flags );
693  _attrMatchList.push_back( std::move(nattr) );
694  }
695  else
696  {
697  // copy matcher
698  _attrMatchList.push_back( *it );
699  }
700  }
701  }
702 
703  // If no attributes defined at all, then add 'query all'
704  if ( _attrMatchList.empty() )
705  {
706  _attrMatchList.push_back( AttrMatchData( sat::SolvAttr::allAttr, joinedStrMatcher( _strings, _flags ) ) );
707  }
708 
709  // Finally check here, whether all involved regex compile.
710  for_( it, _attrMatchList.begin(), _attrMatchList.end() )
711  {
712  it->strMatcher.compile(); // throws on error
713  }
714  //DBG << asString() << endl;
715  }
716 
718  namespace
719  {
724  std::string rxEscape( std::string str_r, const Match & flags_r )
725  {
726  if ( str_r.empty() || flags_r.isModeRegex() )
727  return str_r;
728 
729  if ( flags_r.isModeGlob() )
730  return str::rxEscapeGlob( std::move(str_r) );
731 
732  return str::rxEscapeStr( std::move(str_r) );
733  }
734  } // namespace
736 
737  StrMatcher PoolQuery::Impl::joinedStrMatcher( const StrContainer & container_r, const Match & flags_r ) const
738  {
739  if ( container_r.empty() )
740  return StrMatcher( std::string(), flags_r );
741 
742  if ( container_r.size() == 1 && !_match_word ) // use RX to match words
743  return StrMatcher( *container_r.begin(), flags_r );
744 
745  // Convert to a regex.
746  // Note: Modes STRING and GLOB match whole strings (anchored ^ $)
747  // SUBSTRING and REGEX match substrings (match_word anchores SUBSTRING \b)
748  Match retflags( flags_r );
749  retflags.setModeRegex();
750  str::Str ret;
751 
752  if ( flags_r.isModeString() || flags_r.isModeGlob() )
753  ret << "^";
754  else if ( _match_word )
755  ret << "\\b";
756 
757  // (..|..|..)
758  char sep = '(';
759  for ( const::std::string & s : container_r )
760  {
761  ret << sep << rxEscape( s, flags_r );
762  if ( sep == '(' )
763  sep = '|';
764  }
765  ret << ')';
766 
767  if ( flags_r.isModeString() || flags_r.isModeGlob() )
768  ret << "$";
769  else if ( _match_word )
770  ret << "\\b";
771 
772  return StrMatcher( ret, retflags );
773  }
774 
775  std::string PoolQuery::Impl::asString() const
776  {
777  std::ostringstream o;
778 
779  o << "kinds: ";
780  if ( _kinds.empty() )
781  o << "ALL";
782  else
783  {
784  for(Kinds::const_iterator it = _kinds.begin();
785  it != _kinds.end(); ++it)
786  o << *it << " ";
787  }
788  o << endl;
789 
790  o << "repos: ";
791  if ( _repos.empty() )
792  o << "ALL";
793  else
794  {
795  for(StrContainer::const_iterator it = _repos.begin();
796  it != _repos.end(); ++it)
797  o << *it << " ";
798  }
799  o << endl;
800 
801  o << "version: "<< _op << " " << _edition.asString() << endl;
802  o << "status: " << ( _status_flags ? ( _status_flags == INSTALLED_ONLY ? "INSTALLED_ONLY" : "UNINSTALLED_ONLY" )
803  : "ALL" ) << endl;
804 
805  o << "string match flags: " << Match(_flags) << endl;
806 
807  // raw
808  o << "strings: ";
809  for(StrContainer::const_iterator it = _strings.begin();
810  it != _strings.end(); ++it)
811  o << *it << " ";
812  o << endl;
813 
814  o << "attributes: " << endl;
815  for(AttrRawStrMap::const_iterator ai = _attrs.begin(); ai != _attrs.end(); ++ai)
816  {
817  o << "* " << ai->first << ": ";
818  for(StrContainer::const_iterator vi = ai->second.begin();
819  vi != ai->second.end(); ++vi)
820  o << *vi << " ";
821  o << endl;
822  }
823 
824  o << "predicated: " << endl;
825  for_( it, _uncompiledPredicated.begin(), _uncompiledPredicated.end() )
826  {
827  o << "* " << *it << endl;
828  }
829 
830  // compiled
831  o << "last attribute matcher compiled: " << endl;
832  if ( _attrMatchList.empty() )
833  {
834  o << "not yet compiled" << endl;
835  }
836  else
837  {
838  for_( it, _attrMatchList.begin(), _attrMatchList.end() )
839  {
840  o << "* " << *it << endl;
841  }
842  }
843  return o.str();
844  }
845 
847 
849  //
850  // CLASS NAME : PoolQuery
851  //
853 
855  : _pimpl(new Impl())
856  {}
857 
859  {}
860 
861  void PoolQuery::addRepo(const std::string &repoalias)
862  {
863  if (repoalias.empty())
864  {
865  WAR << "ignoring an empty repository alias" << endl;
866  return;
867  }
868  _pimpl->_repos.insert(repoalias);
869  }
870 
871  void PoolQuery::addKind(const ResKind & kind)
872  { _pimpl->_kinds.insert(kind); }
873 
874  void PoolQuery::setComment(const std::string & comment) const
875  { _pimpl->_comment = comment; }
876 #if LEGACY(1722)
877  void PoolQuery::setComment(const std::string & comment)
878  { _pimpl->_comment = comment; }
879 #endif
880 
881  void PoolQuery::addString(const std::string & value)
882  { _pimpl->_strings.insert(value); }
883 
884  void PoolQuery::addAttribute(const sat::SolvAttr & attr, const std::string & value)
885  { _pimpl->_attrs[attr].insert(value); }
886 
887  void PoolQuery::addDependency( const sat::SolvAttr & attr, const std::string & name, const Rel & op, const Edition & edition )
888  {
889  // Default Match::OTHER indicates need to compile, i.e. to merge name into the global search string and mode.
890  return addDependency( attr, name, op, edition, Arch_empty, Match::OTHER );
891  }
892 
893  void PoolQuery::addDependency( const sat::SolvAttr & attr, const std::string & name, const Rel & op, const Edition & edition, const Arch & arch )
894  {
895  // Default Match::OTHER indicates need to compile, i.e. to merge name into the global search string and mode.
896  return addDependency( attr, name, op, edition, arch, Match::OTHER );
897  }
898 
899  void PoolQuery::addDependency( const sat::SolvAttr & attr, const std::string & name, const Rel & op, const Edition & edition, const Arch & arch, Match::Mode mode )
900  {
901  if ( op == Rel::NONE ) // will never match.
902  return;
903 
904  // SolvAttr::name with explicit 'kind:name' will overwrite the default _kinds
905  ResKind explicitKind;
906  if ( attr == sat::SolvAttr::name )
907  explicitKind = ResKind::explicitBuiltin( name );
908 
909  // Legacy: Match::OTHER and no additional constraints on edition/arch/kind
910  // require addAttribute, otherwise de-serialisation breaks (serialized
911  // and de-serialized query could be !=).
912  // From the results POV we could also use the predicated case below.
913  if ( op == Rel::ANY && arch.empty() && !explicitKind && mode == Match::OTHER )
914  {
915  addAttribute( attr, name );
916  return;
917  }
918 
919  // Match::OTHER indicates need to compile
920  // (merge global search strings into name).
921  AttrMatchData attrMatchData( attr );
922  if ( !explicitKind )
923  attrMatchData.strMatcher = StrMatcher( name, mode );
924  else
925  {
926  // ResKind::explicitBuiltin call above asserts the presence of the ':' in name
927  attrMatchData.strMatcher = StrMatcher( strchr( name.c_str(), ':')+1, mode );
928  attrMatchData.kindPredicate = explicitKind;
929  }
930 
931  if ( isDependencyAttribute( attr ) )
932  attrMatchData.addPredicate( EditionRangePredicate( op, edition, arch ) );
933  else
934  attrMatchData.addPredicate( SolvableRangePredicate( op, edition, arch ) );
935 
936  _pimpl->_uncompiledPredicated.insert( attrMatchData );
937  }
938 
940  {
941  CapDetail cap( cap_r );
942  if ( ! cap.isSimple() ) // will never match.
943  return;
944 
945  // Matches STRING per default. (won't get compiled!)
946  AttrMatchData attrMatchData( attr, StrMatcher( cap.name().asString() ) );
947 
948  if ( isDependencyAttribute( attr ) )
949  attrMatchData.addPredicate( CapabilityMatchPredicate( cap_r ) );
950  else
951  attrMatchData.addPredicate( SolvableRangePredicate( cap.op(), cap.ed() ) );
952 
953  _pimpl->_uncompiledPredicated.insert( attrMatchData );
954  }
955 
956  void PoolQuery::setEdition(const Edition & edition, const Rel & op)
957  {
959  _pimpl->_op = op;
960  }
961 
967 
969  { return _pimpl->_flags; }
970  void PoolQuery::setFlags( const Match & flags )
971  { _pimpl->_flags = flags; }
972 
973 
979  { _pimpl->_status_flags = flags; }
980 
981 
984  { return _pimpl->_strings; }
985 
988  { return _pimpl->_attrs; }
989 
992  {
993  static const PoolQuery::StrContainer nocontainer;
994  AttrRawStrMap::const_iterator it = _pimpl->_attrs.find(attr);
995  return it != _pimpl->_attrs.end() ? it->second : nocontainer;
996  }
997 
999  { return _pimpl->_edition; }
1001  { return _pimpl->_op; }
1002 
1003 
1004  const PoolQuery::Kinds &
1006  { return _pimpl->_kinds; }
1007 
1008  const PoolQuery::StrContainer &
1010  { return _pimpl->_repos; }
1011 
1012  const std::string &
1014  { return _pimpl->_comment; }
1015 
1017  { return !_pimpl->_flags.test( Match::NOCASE ); }
1018  void PoolQuery::setCaseSensitive( bool value )
1019  { _pimpl->_flags.turn( Match::NOCASE, !value ); }
1020 
1022  { return _pimpl->_flags.test( Match::FILES ); }
1024  { _pimpl->_flags.turn( Match::FILES, value ); }
1025 
1026  bool PoolQuery::matchExact() const { return _pimpl->_flags.isModeString(); }
1028  bool PoolQuery::matchGlob() const { return _pimpl->_flags.isModeGlob(); }
1029  bool PoolQuery::matchRegex() const { return _pimpl->_flags.isModeRegex(); }
1031 
1033  { return _pimpl->_status_flags; }
1034 
1035  bool PoolQuery::empty() const
1036  {
1037  try { return begin() == end(); }
1038  catch (const Exception & ex) {}
1039  return true;
1040  }
1041 
1043  {
1044  try
1045  {
1046  size_type count = 0;
1047  for_( it, begin(), end() )
1048  ++count;
1049  return count;
1050  }
1051  catch (const Exception & ex) {}
1052  return 0;
1053  }
1054 
1056  { invokeOnEach( begin(), end(), fnc); }
1057 
1058 
1059  /*DEPRECATED LEGACY:*/void PoolQuery::setRequireAll( bool ) {}
1060  /*DEPRECATED LEGACY:*/bool PoolQuery::requireAll() const { return false; }
1061 
1063  //
1064  // CLASS NAME : PoolQuery::Attr
1065  //
1070  struct PoolQueryAttr : public IdStringType<PoolQueryAttr>
1071  {
1072  private:
1073  friend class IdStringType<PoolQueryAttr>;
1075  public:
1076 
1077  //noAttr
1079 
1080  explicit PoolQueryAttr( const char* cstr_r )
1081  : _str( cstr_r )
1082  {}
1083 
1084  explicit PoolQueryAttr( const std::string & str_r )
1085  : _str( str_r )
1086  {}
1087 
1088  // unknown atributes
1089  static const PoolQueryAttr noAttr;
1090 
1091  // PoolQuery's own attributes
1092  static const PoolQueryAttr repoAttr;
1093  static const PoolQueryAttr kindAttr;
1097  static const PoolQueryAttr requireAllAttr; // LEAGACY: attribute was defined but never implemented.
1102  };
1103 
1105 
1106  const PoolQueryAttr PoolQueryAttr::repoAttr( "repo" );
1107  const PoolQueryAttr PoolQueryAttr::kindAttr( "type" );
1108  const PoolQueryAttr PoolQueryAttr::commentAttr( "comment" );
1109  const PoolQueryAttr PoolQueryAttr::stringAttr( "query_string" );
1110  const PoolQueryAttr PoolQueryAttr::stringTypeAttr("match_type");
1111  const PoolQueryAttr PoolQueryAttr::requireAllAttr("require_all"); // LEAGACY: attribute was defined but never implemented.
1112  const PoolQueryAttr PoolQueryAttr::caseSensitiveAttr("case_sensitive");
1113  const PoolQueryAttr PoolQueryAttr::installStatusAttr("install_status");
1114  const PoolQueryAttr PoolQueryAttr::editionAttr("version");
1115  const PoolQueryAttr PoolQueryAttr::complexAttr("complex");
1116 
1117  class StringTypeAttr : public IdStringType<PoolQueryAttr>
1118  {
1119  friend class IdStringType<StringTypeAttr>;
1121 
1122  public:
1124  explicit StringTypeAttr( const char* cstr_r )
1125  : _str( cstr_r ){}
1126  explicit StringTypeAttr( const std::string & str_r )
1127  : _str( str_r ){}
1128 
1129  static const StringTypeAttr noAttr;
1130 
1134  static const StringTypeAttr globAttr;
1135  static const StringTypeAttr wordAttr;
1136  };
1137 
1139 
1141  const StringTypeAttr StringTypeAttr::substringAttr("substring");
1145 
1147 
1148 
1149  //\TODO maybe ctor with stream can be useful
1150  //\TODO let it throw, let it throw, let it throw.
1151  bool PoolQuery::recover( std::istream &str, char delim )
1152  {
1153  bool finded_something = false; //indicates some atributes is finded
1154  std::string s;
1155  do {
1156  if ( str.eof() )
1157  break;
1158 
1159  getline( str, s, delim );
1160 
1161  if ((!s.empty()) && s[0]=='#') //comment
1162  {
1163  continue;
1164  }
1165 
1166  std::string::size_type pos = s.find(':');
1167  if (s.empty() || pos == s.npos) // some garbage on line... act like blank line
1168  {
1169  if (finded_something) //is first blank line after record?
1170  {
1171  break;
1172  }
1173  else
1174  {
1175  continue;
1176  }
1177  }
1178 
1179  finded_something = true;
1180 
1181  std::string attrName(str::trim(std::string(s,0,pos))); // trimmed name of atribute
1182  std::string attrValue(str::trim(std::string(s,pos+1,s.npos))); //trimmed value
1183 
1184  PoolQueryAttr attribute( attrName );
1185 
1187  {
1188  addRepo( attrValue );
1189  }
1190  /* some backwards compatibility */
1191  else if ( attribute==PoolQueryAttr::kindAttr || attribute=="kind" )
1192  {
1193  addKind( ResKind(attrValue) );
1194  }
1196  {
1197  setComment( attrValue );
1198  }
1200  || attribute=="global_string")
1201  {
1202  addString( attrValue );
1203  }
1205  || attribute=="string_type" )
1206  {
1207  StringTypeAttr s(attrValue);
1208  if( s == StringTypeAttr::regexAttr )
1209  {
1210  setMatchRegex();
1211  }
1212  else if ( s == StringTypeAttr::globAttr )
1213  {
1214  setMatchGlob();
1215  }
1216  else if ( s == StringTypeAttr::exactAttr )
1217  {
1218  setMatchExact();
1219  }
1220  else if ( s == StringTypeAttr::substringAttr )
1221  {
1223  }
1224  else if ( s == StringTypeAttr::wordAttr )
1225  {
1226  setMatchWord();
1227  }
1228  else if ( s == StringTypeAttr::noAttr )
1229  {
1230  WAR << "unknown string type " << attrValue << endl;
1231  }
1232  else
1233  {
1234  WAR << "forget recover some attribute defined as String type attribute: " << attrValue << endl;
1235  }
1236  }
1238  {
1239  // LEAGACY: attribute was defined but never implemented.
1240  // Actually it should not occur outside our testcases.
1241  }
1243  {
1244  if ( str::strToTrue(attrValue) )
1245  {
1246  setCaseSensitive(true);
1247  }
1248  else if ( !str::strToFalse(attrValue) )
1249  {
1250  setCaseSensitive(false);
1251  }
1252  else
1253  {
1254  WAR << "unknown boolean value " << attrValue << endl;
1255  }
1256  }
1258  {
1259  if( attrValue == "all" )
1260  {
1262  }
1263  else if( attrValue == "installed" )
1264  {
1265  setInstalledOnly();
1266  }
1267  else if( attrValue == "not-installed" )
1268  {
1270  }
1271  else
1272  {
1273  WAR << "Unknown value for install status " << attrValue << endl;
1274  }
1275  }
1277  {
1279  Rel rel("==");
1280  if (attrValue.find_first_of("=<>!") == 0)
1281  {
1282  pos = attrValue.find_last_of("=<>");
1283  rel = Rel(attrValue.substr(0, pos+1));
1284  attrValue = str::trim(attrValue.substr(pos+1, attrValue.npos));
1285  }
1286 
1287  setEdition(Edition(attrValue), rel);
1288  }
1289  else if ( attribute == PoolQueryAttr::complexAttr )
1290  {
1291  try
1292  {
1294  }
1295  catch ( const Exception & err )
1296  {
1297  WAR << "Unparsable value for complex: " << err.asUserHistory() << endl;
1298 
1299  }
1300  }
1301  else if ( attribute==PoolQueryAttr::noAttr )
1302  {
1303  WAR << "empty attribute name" << endl;
1304  }
1305  else
1306  {
1307  std::string s = attrName;
1308  str::replaceAll( s,"_",":" );
1309  SolvAttr a(s);
1310  if ( a == SolvAttr::name || isDependencyAttribute( a ) )
1311  {
1312  Capability c( attrValue );
1313  CapDetail d( c );
1314  if ( d.isVersioned() )
1315  addDependency( a, d.name().asString(), d.op(), d.ed() );
1316  else
1317  addDependency( a, attrValue );
1318  }
1319  else
1320  addAttribute( a, attrValue );
1321  }
1322 
1323  } while ( true );
1324 
1325  // OLD STYLE VERSIONED LOCKS:
1326  // solvable_name: kernel
1327  // version: > 1
1328  //
1329  // NEW STYLE VERSIONED LOCKS:
1330  // complex: AttrMatchData solvable:name kernel C SolvableRange\ >\ 1\ \"\"
1331  // or
1332  // solvable_name: kernel > 1
1333  //
1334  // Semantically equivalent as locks, but due to the different syntax
1335  // the complex lock is wrongly handled by zypper.
1336  //
1337  // bsc#1112911: Unfortunately all styles are found in real-life locks-files.
1338  // libzypp will try to make sure, when parsing the locks-file, that complex
1339  // locks are rewritten into to OLD STYLE queries zypper can handle.
1340  if ( !_pimpl->_attrs.count(SolvAttr::name) && _pimpl->_uncompiledPredicated.size() == 1 )
1341  {
1342  // No OLD STYLE lock for SolvAttr::name and exactly one complex lock...
1343  const AttrMatchData & attrmatch { *_pimpl->_uncompiledPredicated.begin() };
1344  if ( attrmatch.attr == SolvAttr::name && attrmatch.strMatcher.flags().mode() == Match::OTHER )
1345  {
1346  // ...for SolvAttr::name and following the global search flags.
1347  // A candidate for a rewrite?
1348 
1349  std::vector<std::string> words;
1350  str::splitEscaped( attrmatch.predicateStr, std::back_inserter(words) );
1351  if ( words.size() < 4 || words[3].empty() )
1352  {
1353  // We have _NO_ arch rule in the complex predicate, so we can simplify it.
1354  //
1355  // NOTE: AFAIK it's not possible to create (or have created) a complex lock
1356  // with arch rule with zypper means. Nevertheless, in case such a rule made it
1357  // into a locks file, it's better to have a strange looking 'zypper locks' list
1358  // than to lock the wrong packages.
1359  // (and remember that you can't use "addAttribute( SolvAttr::arch, ... )" because
1360  // attributes are `OR`ed)
1361 
1362  // kind
1363  if ( attrmatch.kindPredicate )
1364  {
1365  _pimpl->_kinds.clear(); // an explicit kind overwrites any global one
1366  addKind( attrmatch.kindPredicate );
1367  }
1368 
1369  // name
1370  addAttribute( SolvAttr::name, attrmatch.strMatcher.searchstring() );
1371 
1372  // edition
1373  std::vector<std::string> words;
1374  str::splitEscaped( attrmatch.predicateStr, std::back_inserter(words) );
1375  if ( ! words.empty() )
1376  {
1377  if ( words[0] == "EditionRange" || words[0] == "SolvableRange" )
1378  {
1379  setEdition( Edition(words[2]), Rel(words[1]) );
1380  }
1381  }
1382 
1383  // finally remove the complex lock
1384  _pimpl->_uncompiledPredicated.clear();
1385  }
1386  }
1387  }
1388 
1389  return finded_something;
1390  }
1391 
1392  void PoolQuery::serialize( std::ostream &str, char delim ) const
1393  {
1394  //separating delim
1395  str << delim;
1396  //iterate thrue all settings and write it
1397  static const zypp::PoolQuery q; //not save default options, so create default query example
1398 
1399  for_( it, repos().begin(), repos().end() )
1400  {
1401  str << "repo: " << *it << delim ;
1402  }
1403 
1404  for_( it, kinds().begin(), kinds().end() )
1405  {
1406  str << PoolQueryAttr::kindAttr.asString() << ": "
1407  << it->idStr() << delim ;
1408  }
1409 
1410  if (editionRel() != Rel::ANY && edition() != Edition::noedition)
1411  str << PoolQueryAttr::editionAttr.asString() << ": " << editionRel() << " " << edition() << delim;
1412 
1413  if (matchMode()!=q.matchMode())
1414  {
1415  switch( matchMode() )
1416  {
1417  case Match::STRING:
1418  str << PoolQueryAttr::stringTypeAttr.asString() << ": exact" << delim;
1419  break;
1420  case Match::SUBSTRING:
1422  << ": substring" << delim;
1423  break;
1424  case Match::GLOB:
1425  str << PoolQueryAttr::stringTypeAttr.asString() << ": glob" << delim;
1426  break;
1427  case Match::REGEX:
1428  str << PoolQueryAttr::stringTypeAttr.asString() << ": regex" << delim;
1429  break;
1430  default:
1431  WAR << "unknown match type " << matchMode() << endl;
1432  }
1433  }
1434 
1435  if( caseSensitive() != q.caseSensitive() )
1436  {
1437  str << "case_sensitive: ";
1438  if (caseSensitive())
1439  {
1440  str << "on" << delim;
1441  }
1442  else
1443  {
1444  str << "off" << delim;
1445  }
1446  }
1447 
1448  if( statusFilterFlags() != q.statusFilterFlags() )
1449  {
1450  switch( statusFilterFlags() )
1451  {
1452  case ALL:
1453  str << "install_status: all" << delim;
1454  break;
1455  case INSTALLED_ONLY:
1456  str << "install_status: installed" << delim;
1457  break;
1458  case UNINSTALLED_ONLY:
1459  str << "install_status: not-installed" << delim;
1460  break;
1461  }
1462  }
1463 
1464  for_( it, strings().begin(), strings().end() )
1465  {
1466  str << PoolQueryAttr::stringAttr.asString()<< ": " << *it << delim;
1467  }
1468 
1469  for_( it, attributes().begin(), attributes().end() )
1470  {
1471  std::string s = it->first.asString();
1472  str::replaceAll(s,":","_");
1473  for_( it2,it->second.begin(),it->second.end() )
1474  {
1475  str << s <<": "<< *it2 << delim;
1476  }
1477  }
1478 
1480  {
1481  str << "complex: "<< it->serialize() << delim;
1482  }
1483 
1484  if ( const std::string & c { comment() }; not c.empty() )
1485  str << PoolQueryAttr::commentAttr.asString() << ": " << c << delim ;
1486 
1487  //separating delim - protection
1488  str << delim;
1489  }
1490 
1491  std::string PoolQuery::asString() const
1492  { return _pimpl->asString(); }
1493 
1494  std::ostream & operator<<( std::ostream & str, const PoolQuery & obj )
1495  { return str << obj.asString(); }
1496 
1497  std::ostream & dumpOn( std::ostream & str, const PoolQuery & obj )
1498  { return dumpRange( str << obj, obj.begin(), obj.end() ); }
1499 
1500  bool PoolQuery::operator==( const PoolQuery & rhs ) const
1501  { return *_pimpl == *rhs._pimpl; }
1502 
1503  bool PoolQuery::operator<( const PoolQuery & rhs ) const
1504  { return *_pimpl < *rhs._pimpl; }
1505 
1507  namespace detail
1508  {
1509 
1511  //
1512  // CLASS NAME : PoolQueryMatcher
1513  //
1531  {
1532  public:
1534 
1535  public:
1536  const base_iterator & end() const
1537  {
1538  static base_iterator _end;
1539  return _end;
1540  }
1541 
1542  bool advance( base_iterator & base_r ) const
1543  {
1544  if ( base_r == end() )
1545  base_r = startNewQyery(); // first candidate
1546  else
1547  {
1548  base_r.nextSkipSolvable(); // assert we don't visit this Solvable again
1549  ++base_r; // advance to next candidate
1550  }
1551 
1552  while ( base_r != end() )
1553  {
1554  if ( isAMatch( base_r ) )
1555  return true;
1556  // No match: try next
1557  ++base_r;
1558  }
1559  return false;
1560  }
1561 
1565  void matchDetail( const base_iterator & base_r, std::vector<base_iterator> & return_r ) const
1566  {
1567  if ( base_r == end() )
1568  return;
1569 
1570  sat::Solvable inSolvable( base_r.inSolvable() );
1571 
1572  if ( _attrMatchList.size() == 1 )
1573  {
1574  // base_r is already on the 1st matching attribute!
1575  // String matching is done by the base iterator. We must check the predicate here.
1576  // Let's see if there are more matches for this solvable:
1577  base_iterator base( base_r );
1578  base.stayInThisSolvable(); // avoid discarding matches we found far away from here.
1579  return_r.push_back( base );
1580 
1581  const AttrMatchData::Predicate & predicate( _attrMatchList.front().predicate );
1582  for ( ++base; base.inSolvable() == inSolvable; ++base ) // safe even if base == end()
1583  {
1584  if ( ! predicate || predicate( base ) )
1585  return_r.push_back( base );
1586  }
1587  }
1588  else
1589  {
1590  // Here: search all attributes ;(
1591  for_( mi, _attrMatchList.begin(), _attrMatchList.end() )
1592  {
1593  const AttrMatchData & matchData( *mi );
1594  sat::LookupAttr q( matchData.attr, inSolvable );
1595  if ( matchData.strMatcher ) // an empty searchstring matches always
1596  q.setStrMatcher( matchData.strMatcher );
1597 
1598  if ( ! q.empty() ) // there are matches.
1599  {
1600  // now check any predicate:
1601  const AttrMatchData::Predicate & predicate( matchData.predicate );
1602  for_( it, q.begin(), q.end() )
1603  {
1604  if ( ! predicate || predicate( it ) )
1605  return_r.push_back( it );
1606  }
1607  }
1608  }
1609  }
1610  }
1611 
1612  public:
1616  PoolQueryMatcher( const shared_ptr<const PoolQuery::Impl> & query_r )
1617  {
1618  query_r->compile();
1619 
1620  // Repo restriction:
1621  sat::Pool satpool( sat::Pool::instance() );
1622 
1623  for_( it, query_r->_repos.begin(), query_r->_repos.end() )
1624  {
1625  Repository r( satpool.reposFind( *it ) );
1626  if ( r )
1627  _repos.insert( r );
1628  else
1629  _neverMatchRepo = true;
1630  }
1631  // _neverMatchRepo: we just need to catch the case that no repo
1632  // matched, so we'd interpret the empty list as 'take from all'
1633  if ( _neverMatchRepo && ! _repos.empty() )
1634  _neverMatchRepo = false;
1635 
1636  // Kind restriction:
1637  _kinds = query_r->_kinds;
1638  // Edition restriction:
1639  _op = query_r->_op;
1640  _edition = query_r->_edition;
1641  // Status restriction:
1642  _status_flags = query_r->_status_flags;
1643  // StrMatcher
1644  _attrMatchList = query_r->_attrMatchList;
1645  }
1646 
1648  {}
1649 
1650  private:
1653  {
1654  sat::LookupAttr q;
1655 
1656  if ( _neverMatchRepo )
1657  return q.end();
1658 
1659  // Repo restriction:
1660  if ( _repos.size() == 1 )
1661  q.setRepo( *_repos.begin() );
1662  // else: handled in isAMatch.
1663 
1664  // Attribute restriction:
1665  if ( _attrMatchList.size() == 1 ) // all (SolvAttr::allAttr) or 1 attr
1666  {
1667  const AttrMatchData & matchData( _attrMatchList.front() );
1668  q.setAttr( matchData.attr );
1669  if ( matchData.strMatcher ) // empty searchstring matches always
1670  q.setStrMatcher( matchData.strMatcher );
1671  }
1672  else // more than 1 attr (but not all)
1673  {
1674  // no restriction, it's all handled in isAMatch.
1676  }
1677 
1678  return q.begin();
1679  }
1680 
1681 
1692  bool isAMatch( base_iterator & base_r ) const
1693  {
1695  Repository inRepo( base_r.inRepo() );
1696  // Status restriction:
1697  if ( _status_flags
1698  && ( (_status_flags == PoolQuery::INSTALLED_ONLY) != inRepo.isSystemRepo() ) )
1699  {
1700  base_r.nextSkipRepo();
1701  return false;
1702  }
1703  // Repo restriction:
1704  if ( _repos.size() > 1 && _repos.find( inRepo ) == _repos.end() )
1705  {
1706  base_r.nextSkipRepo();
1707  return false;
1708  }
1710  sat::Solvable inSolvable( base_r.inSolvable() );
1711  // Edition restriction:
1712  if ( _op != Rel::ANY && !compareByRel( _op, inSolvable.edition(), _edition, Edition::Match() ) )
1713  {
1714  base_r.nextSkipSolvable();
1715  return false;
1716  }
1717 
1718  // Kind restriction:
1719  // Delay the decision to nextSkipSolvable and return false, as there may be
1720  // some explicit kind:name predicate which overrules the global kinds.
1721  bool globalKindOk =( _kinds.empty() || inSolvable.isKind( _kinds.begin(), _kinds.end() ) );
1722 
1724  // string and predicate matching:
1725 
1726  if ( _attrMatchList.size() == 1 )
1727  {
1728  // String matching was done by the base iterator.
1729  // Now check any predicate:
1730  const AttrMatchData & matchData( _attrMatchList.front() );
1731 
1732  if ( matchData.kindPredicate )
1733  {
1734  if ( matchData.kindPredicate != inSolvable.kind() )
1735  {
1736  base_r.nextSkipSolvable(); // this matchData will never match in this solvable
1737  return false;
1738  }
1739  }
1740  else if ( !globalKindOk )
1741  return false; // only matching kindPredicate could overwrite this
1742 
1743  if ( !matchData.predicate || matchData.predicate( base_r ) )
1744  return true;
1745 
1746  return false; // no skip as there may be more occurrences in this solvable of this attr.
1747  }
1748 
1749  // Here: search all attributes ;(
1750  for_( mi, _attrMatchList.begin(), _attrMatchList.end() )
1751  {
1752  const AttrMatchData & matchData( *mi );
1753 
1754  if ( matchData.kindPredicate )
1755  {
1756  if ( matchData.kindPredicate != inSolvable.kind() )
1757  continue; // this matchData does not apply
1758  }
1759  else if ( !globalKindOk )
1760  continue; // only matching kindPredicate could overwrite this
1761 
1762  sat::LookupAttr q( matchData.attr, inSolvable );
1763  if ( matchData.strMatcher ) // an empty searchstring matches always
1764  q.setStrMatcher( matchData.strMatcher );
1765 
1766  if ( ! q.empty() ) // there are matches.
1767  {
1768  // now check any predicate:
1769  const AttrMatchData::Predicate & predicate( matchData.predicate );
1770  if ( predicate )
1771  {
1772  for_( it, q.begin(), q.end() )
1773  {
1774  if ( predicate( it ) )
1775  return true;
1776  }
1777  }
1778  else
1779  return true;
1780  }
1781  }
1782  base_r.nextSkipSolvable();
1783  return false;
1784  }
1785 
1786  private:
1788  std::set<Repository> _repos;
1791  std::set<ResKind> _kinds;
1798  AttrMatchList _attrMatchList;
1799  };
1801 
1803  {
1804  // matcher restarts if at end! It is called from the ctor
1805  // to get the 1st match. But if the end is reached, it should
1806  // be deleted, otherwise we'd start over again.
1807  if ( !_matcher )
1808  return; // at end
1809  if ( _matches )
1810  _matches.reset(); // invalidate old matches
1811  if ( ! _matcher->advance( base_reference() ) )
1812  _matcher.reset();
1813  }
1814 
1816  {
1817  if ( _matches )
1818  return *_matches;
1819 
1820  if ( !_matcher )
1821  {
1822  // at end of query:
1823  static const Matches _none;
1824  return _none;
1825  }
1826 
1827  _matches.reset( new Matches );
1828  _matcher->matchDetail( base_reference(), *_matches );
1829  return *_matches;
1830  }
1831 
1832  std::ostream & dumpOn( std::ostream & str, const PoolQueryIterator & obj )
1833  {
1834  str << *obj;
1835  if ( ! obj.matchesEmpty() )
1836  {
1837  for_( it, obj.matchesBegin(), obj.matchesEnd() )
1838  {
1839  str << endl << " " << it->inSolvAttr() << "\t" << it->asString();
1840  }
1841  }
1842  return str;
1843  }
1844 
1846  } //namespace detail
1848 
1850  {
1851  return shared_ptr<detail::PoolQueryMatcher>( new detail::PoolQueryMatcher( _pimpl.getPtr() ) );
1852  }
1853 
1855 } // namespace zypp
1857 
ResKind kindPredicate
Definition: PoolQuery.cc:315
Predicate predicate
Definition: PoolQuery.cc:313
sat::SolvAttr attr
Definition: PoolQuery.cc:311
Edition::MatchRange _range
Definition: PoolQuery.cc:101
std::string predicateStr
Definition: PoolQuery.cc:314
Arch _arch
Definition: PoolQuery.cc:102
StrMatcher strMatcher
Definition: PoolQuery.cc:312
Capability _cap
Definition: PoolQuery.cc:160
#define OUTS(M, S)
Architecture.
Definition: Arch.h:37
bool empty() const
Test for an empty Arch (this is Arch_epmty, not Arch_noarch ).
Definition: Arch.h:63
Helper providing more detailed information about a Capability.
Definition: Capability.h:299
bool isSimple() const
Definition: Capability.h:345
IdString name() const
Definition: Capability.h:352
Edition ed() const
Definition: Capability.h:354
Rel op() const
Definition: Capability.h:353
bool isVersioned() const
Definition: Capability.h:344
static const CapMatch yes
Definition: CapMatch.h:51
A sat capability.
Definition: Capability.h:60
Edition represents [epoch:]version[-release]
Definition: Edition.h:61
Range< Edition, Match > MatchRange
Edition Range based on Match.
Definition: Edition.h:169
static const Edition noedition
Value representing noedition ("") This is in fact a valid Edition.
Definition: Edition.h:73
Base class for Exception.
Definition: Exception.h:146
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Definition: Exception.cc:91
Base class for creating IdString based types.
Definition: IdStringType.h:87
std::string asString() const
Definition: IdStringType.h:106
Access to the sat-pools string space.
Definition: IdString.h:43
std::string asString() const
Conversion to std::string
Definition: IdString.h:98
String matching option flags as used e.g.
Definition: StrMatcher.h:33
void setModeGlob()
Set the mode GLOB.
Definition: StrMatcher.h:198
int get() const
Return the integer representation.
Definition: StrMatcher.h:150
bool isModeSubstring() const
Whether this has mode SUBSTRING.
Definition: StrMatcher.h:173
Mode
Mode flags (mutual exclusive).
Definition: StrMatcher.h:41
@ NOTHING
Match nothing.
Definition: StrMatcher.h:42
@ OTHER
Something else.
Definition: StrMatcher.h:49
@ REGEX
Regular Expression.
Definition: StrMatcher.h:48
@ GLOB
Glob.
Definition: StrMatcher.h:47
@ SUBSTRING
Match substring.
Definition: StrMatcher.h:46
@ STRING
Excat matching.
Definition: StrMatcher.h:43
bool isModeString() const
Whether this has mode STRING.
Definition: StrMatcher.h:164
static const Match FILES
LookupAttr: match full path when matching in filelists, otherwise just the basenames.
Definition: StrMatcher.h:75
void setModeRegex()
Set the mode REGEX.
Definition: StrMatcher.h:201
static const Match NOCASE
If set, match case insensitive.
Definition: StrMatcher.h:59
bool isModeGlob() const
Whether this has mode GLOB.
Definition: StrMatcher.h:176
void setModeString()
Set the mode STRING.
Definition: StrMatcher.h:186
void turn(const Match &rhs, bool onoff)
Depending on the value of onoff, set or unset flags.
Definition: StrMatcher.h:127
bool isModeRegex() const
Whether this has mode REGEX.
Definition: StrMatcher.h:179
bool test(const Match &rhs) const
Test whether all of the rhs bits are set (same mode if rhs has one).
Definition: StrMatcher.h:101
void setModeSubstring()
Set the mode SUBSTRING.
Definition: StrMatcher.h:195
Edition _edition
Edition condition operand.
Definition: PoolQuery.cc:448
Kinds _kinds
Kinds to search.
Definition: PoolQuery.cc:456
StrContainer _repos
Repos to search.
Definition: PoolQuery.cc:453
StatusFilter _status_flags
Sat solver status flags.
Definition: PoolQuery.cc:445
Rel _op
Operator for edition condition.
Definition: PoolQuery.cc:450
Match _flags
Sat solver search flags.
Definition: PoolQuery.cc:441
std::string _comment
Optional comment string for serialization.
Definition: PoolQuery.cc:459
void compile() const
Compile the regex.
Definition: PoolQuery.cc:559
bool operator<(const PoolQuery::Impl &rhs) const
Definition: PoolQuery.cc:464
bool operator!=(const PoolQuery::Impl &rhs) const
Definition: PoolQuery.cc:509
StrContainer _strings
Raw search strings.
Definition: PoolQuery.cc:434
std::set< AttrMatchData > _uncompiledPredicated
Uncompiled attributes with predicate.
Definition: PoolQuery.cc:438
StrMatcher joinedStrMatcher(const StrContainer &container_r, const Match &flags_r) const
Join patterns in container_r according to flags_r into a single StrMatcher.
Definition: PoolQuery.cc:737
AttrRawStrMap _attrs
Raw attributes.
Definition: PoolQuery.cc:436
Impl * clone() const
clone for RWCOW_pointer
Definition: PoolQuery.cc:531
AttrMatchList _attrMatchList
StrMatcher per attribtue.
Definition: PoolQuery.cc:520
bool operator==(const PoolQuery::Impl &rhs) const
Definition: PoolQuery.cc:481
std::string asString() const
String representation.
Definition: PoolQuery.cc:775
Meta-data query API.
Definition: PoolQuery.h:91
Match flags() const
Free function to get libsolv repo search flags.
Definition: PoolQuery.cc:968
void addString(const std::string &value)
Add a global query string.
Definition: PoolQuery.cc:881
const Rel editionRel() const
Definition: PoolQuery.cc:1000
std::set< std::string > StrContainer
Definition: PoolQuery.h:94
bool matchSubstring() const
Definition: PoolQuery.cc:1027
const StrContainer & repos() const
Definition: PoolQuery.cc:1009
void setMatchExact()
Set to match exact string instead of substring.
Definition: PoolQuery.cc:963
void setMatchWord()
Set substring to match words.
Definition: PoolQuery.cc:966
void setMatchRegex()
Set to use the query strings as regexes.
Definition: PoolQuery.cc:964
const Edition edition() const
Definition: PoolQuery.cc:998
void setFlags(const Match &flags)
Free function to set libsolv repo search flags.
Definition: PoolQuery.cc:970
RW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: PoolQuery.h:489
void setCaseSensitive(bool value=true)
Turn case sentitivity on or off (unsets or sets SEARCH_NOCASE flag).
Definition: PoolQuery.cc:1018
bool matchRegex() const
Definition: PoolQuery.cc:1029
void setComment(const std::string &comment) const
Set an optional comment string describing the purpose of the query.
Definition: PoolQuery.cc:874
void execute(ProcessResolvable fnc)
Executes the query with the current settings.
Definition: PoolQuery.cc:1055
std::string asString() const
Return a human-readable description of the query.
Definition: PoolQuery.cc:1491
unsigned int size_type
Definition: PoolQuery.h:98
void setStatusFilterFlags(StatusFilter flags)
Set status filter directly.
Definition: PoolQuery.cc:978
bool empty() const
Whether the result is empty.
Definition: PoolQuery.cc:1035
void addKind(const ResKind &kind)
Filter by selectable kind.
Definition: PoolQuery.cc:871
bool operator==(const PoolQuery &b) const
Definition: PoolQuery.cc:1500
bool matchExact() const
Definition: PoolQuery.cc:1026
void setRequireAll(bool require_all=true) ZYPP_DEPRECATED
Definition: PoolQuery.cc:1059
bool matchWord() const
Definition: PoolQuery.cc:1030
void addAttribute(const sat::SolvAttr &attr, const std::string &value="")
Filter by the value of the specified attr attribute.
Definition: PoolQuery.cc:884
bool requireAll() const ZYPP_DEPRECATED
Definition: PoolQuery.cc:1060
const std::string & comment() const
Definition: PoolQuery.cc:1013
bool filesMatchFullPath() const
Whether searching in filelists looks at the full path or just at the basenames.
Definition: PoolQuery.cc:1021
void addRepo(const std::string &repoalias)
Filter by repo.
Definition: PoolQuery.cc:861
const Kinds & kinds() const
Definition: PoolQuery.cc:1005
Match::Mode matchMode() const
Returns string matching mode as enum.
Definition: PoolQuery.h:428
void setInstalledOnly()
Return only @System repo packages.
Definition: PoolQuery.cc:974
const_iterator end() const
An iterator pointing to the end of the query result.
Definition: PoolQuery.h:624
StatusFilter statusFilterFlags() const
Definition: PoolQuery.cc:1032
const StrContainer & strings() const
Search strings added via addString()
Definition: PoolQuery.cc:983
std::set< ResKind > Kinds
Definition: PoolQuery.h:93
bool matchGlob() const
Definition: PoolQuery.cc:1028
size_type size() const
Number of solvables in the query result.
Definition: PoolQuery.cc:1042
const_iterator begin() const
Query result accessers.
Definition: PoolQuery.cc:1849
bool recover(std::istream &str, char delim='\n')
Reads from stream query.
Definition: PoolQuery.cc:1151
void serialize(std::ostream &str, char delim='\n') const
Writes a machine-readable string representation of the query to stream.
Definition: PoolQuery.cc:1392
std::map< sat::SolvAttr, StrContainer > AttrRawStrMap
Definition: PoolQuery.h:95
const AttrRawStrMap & attributes() const
Map (map<SolvAttr, StrContainer>) of attribute values added via addAttribute(), addDep in string form...
Definition: PoolQuery.cc:987
void addDependency(const sat::SolvAttr &attr, const std::string &name, const Rel &op, const Edition &edition)
Query "name|global op edition".
Definition: PoolQuery.cc:887
StatusFilter
Installed status filter setters.
Definition: PoolQuery.h:177
void setEdition(const Edition &edition, const Rel &op=Rel::EQ)
Set version condition.
Definition: PoolQuery.cc:956
const StrContainer & attribute(const sat::SolvAttr &attr) const
Definition: PoolQuery.cc:991
void setMatchSubstring()
Set to substring (the default).
Definition: PoolQuery.cc:962
void setFilesMatchFullPath(bool value=true)
If set (default), look at the full path when searching in filelists.
Definition: PoolQuery.cc:1023
void setUninstalledOnly()
Return only packages from repos other than @System.
Definition: PoolQuery.cc:976
function< bool(const sat::Solvable &)> ProcessResolvable
Definition: PoolQuery.h:101
void setMatchGlob()
Set to match globs.
Definition: PoolQuery.cc:965
bool operator<(const PoolQuery &b) const
Definition: PoolQuery.cc:1503
bool caseSensitive() const
returns true if search is case sensitive
Definition: PoolQuery.cc:1016
bool isSystemRepo() const
Return whether this is the system repository.
Definition: Repository.cc:53
Resolvable kinds.
Definition: ResKind.h:33
static ResKind explicitBuiltin(const char *str_r)
Return the builtin kind if str_r explicitly prefixed.
Definition: ResKind.cc:46
static const ResKind nokind
Value representing nokind ("")
Definition: ResKind.h:38
String matching (STRING|SUBSTRING|GLOB|REGEX).
Definition: StrMatcher.h:298
static const StringTypeAttr substringAttr
Definition: PoolQuery.cc:1132
static const StringTypeAttr wordAttr
Definition: PoolQuery.cc:1135
StringTypeAttr(const char *cstr_r)
Definition: PoolQuery.cc:1124
StringTypeAttr(const std::string &str_r)
Definition: PoolQuery.cc:1126
static const StringTypeAttr noAttr
Definition: PoolQuery.cc:1129
static const StringTypeAttr globAttr
Definition: PoolQuery.cc:1134
static const StringTypeAttr exactAttr
Definition: PoolQuery.cc:1131
static const StringTypeAttr regexAttr
Definition: PoolQuery.cc:1133
PoolQuery iterator as returned by PoolQuery::begin.
Definition: PoolQuery.h:526
const Matches & matches() const
Definition: PoolQuery.cc:1815
matches_iterator matchesEnd() const
End of matches.
Definition: PoolQuery.h:593
bool matchesEmpty() const
False unless this is the end iterator.
Definition: PoolQuery.h:587
shared_ptr< Matches > _matches
Definition: PoolQuery.h:609
matches_iterator matchesBegin() const
Begin of matches.
Definition: PoolQuery.h:591
shared_ptr< PoolQueryMatcher > _matcher
Definition: PoolQuery.h:608
std::vector< sat::LookupAttr::iterator > Matches
Definition: PoolQuery.h:527
Store PoolQuery settings and assist PoolQueryIterator.
Definition: PoolQuery.cc:1531
sat::LookupAttr::iterator base_iterator
Definition: PoolQuery.cc:1533
std::set< Repository > _repos
Repositories include in the search.
Definition: PoolQuery.cc:1788
bool isAMatch(base_iterator &base_r) const
Check whether we are on a match.
Definition: PoolQuery.cc:1692
bool advance(base_iterator &base_r) const
Definition: PoolQuery.cc:1542
PoolQueryMatcher(const shared_ptr< const PoolQuery::Impl > &query_r)
Ctor stores the PoolQuery settings.
Definition: PoolQuery.cc:1616
std::set< ResKind > _kinds
Resolvable kinds to include.
Definition: PoolQuery.cc:1791
AttrMatchList _attrMatchList
StrMatcher per attribtue.
Definition: PoolQuery.cc:1798
DefaultIntegral< bool, false > _neverMatchRepo
Definition: PoolQuery.cc:1789
const base_iterator & end() const
Definition: PoolQuery.cc:1536
void matchDetail(const base_iterator &base_r, std::vector< base_iterator > &return_r) const
Provide all matching attributes within this solvable.
Definition: PoolQuery.cc:1565
base_iterator startNewQyery() const
Initialize a new base query.
Definition: PoolQuery.cc:1652
int _status_flags
Installed status filter flags.
Definition: PoolQuery.cc:1796
void stayInThisSolvable()
Stop after all matches in the current Solvable are processed.
Definition: LookupAttr.cc:369
void nextSkipSolvable()
On the next call to operator++ advance to the next Solvable.
Definition: LookupAttr.cc:363
Solvable inSolvable() const
The current Solvable.
Definition: LookupAttr.cc:354
void nextSkipRepo()
On the next call to operator++ advance to the next Repository.
Definition: LookupAttr.cc:366
Repository inRepo() const
The current Repository.
Definition: LookupAttr.cc:351
Lightweight attribute value lookup.
Definition: LookupAttr.h:108
iterator end() const
Iterator behind the end of query results.
Definition: LookupAttr.cc:239
bool empty() const
Whether the query is empty.
Definition: LookupAttr.cc:242
void setStrMatcher(const StrMatcher &matcher_r)
Set the pattern to match.
Definition: LookupAttr.cc:205
void setAttr(SolvAttr attr_r)
Set the SolvAttr to search.
Definition: LookupAttr.cc:199
void setRepo(Repository repo_r, Location=SOLV_ATTR)
Set search in one Repository.
Definition: LookupAttr.cc:219
iterator begin() const
Iterator to the begin of query results.
Definition: LookupAttr.cc:236
Global sat-pool.
Definition: Pool.h:47
Repository reposFind(const std::string &alias_r) const
Find a Repository named alias_r.
Definition: Pool.cc:163
static Pool instance()
Singleton ctor.
Definition: Pool.h:55
Solvable attribute keys.
Definition: SolvAttr.h:41
static const SolvAttr supplements
Definition: SolvAttr.h:66
static const SolvAttr obsoletes
Definition: SolvAttr.h:61
static const SolvAttr name
Definition: SolvAttr.h:52
static const SolvAttr suggests
Definition: SolvAttr.h:65
static const SolvAttr conflicts
Definition: SolvAttr.h:62
static const SolvAttr recommends
Definition: SolvAttr.h:64
static const SolvAttr requires
Definition: SolvAttr.h:63
static const SolvAttr allAttr
Value to request searching all Attributes (0).
Definition: SolvAttr.h:46
static const SolvAttr enhances
Definition: SolvAttr.h:67
static const SolvAttr provides
Definition: SolvAttr.h:60
A Solvable object within the sat Pool.
Definition: Solvable.h:54
ResKind kind() const
The Solvables ResKind.
Definition: Solvable.cc:275
Edition edition() const
The edition (version-release).
Definition: Solvable.cc:337
bool isKind(const ResKind &kind_r) const
Test whether a Solvable is of a certain ResKind.
Definition: Solvable.cc:302
bool compareByRel(Rel op, const Tp &lhs, const Tp &rhs, TCompare compare)
Comparison of two elements using relational operator op.
Definition: RelCompare.h:108
String related utilities and Regular expression matching.
std::ostream & dumpOn(std::ostream &str, const PoolQueryIterator &obj)
Definition: PoolQuery.cc:1832
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:33
SolvableIdType size_type
Definition: PoolMember.h:126
Libsolv interface
bool operator!=(const SolvableType< Derived > &lhs, const Solvable &rhs)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SolvableType.h:188
bool operator<(const SolvableType< Derived > &lhs, const Solvable &rhs)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SolvableType.h:201
std::ostream & operator<<(std::ostream &str, const FileConflicts &obj)
bool operator==(const Map &lhs, const Map &rhs)
Definition: Map.cc:125
std::string & replaceAll(std::string &str_r, const std::string &from_r, const std::string &to_r)
Replace all occurrences of from_r with to_r in str_r (inplace).
Definition: String.cc:330
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off, never.
Definition: String.cc:81
void appendEscaped(std::string &str_r, const C_Str &next_r, const char sep_r=' ')
Escape next_r and append it to str_r using separator sep_r.
Definition: String.h:922
std::string rxEscapeStr(std::string str_r)
Escape plain STRING str_r for use in a regex (not anchored by "^" or "$").
Definition: String.cc:415
std::string rxEscapeGlob(std::string str_r)
Escape GLOB str_r for use in a regex (not anchored by "^" or "$").
Definition: String.cc:420
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition: String.cc:63
unsigned splitEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", bool withEmpty=false)
Split line_r into words with respect to escape delimeters.
Definition: String.h:595
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:223
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
bool overlaps(const Range< Tp, TCompare > &lhs, const Range< Tp, TCompare > &rhs)
Definition: Range.h:65
const Arch Arch_empty(IdString::Empty)
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
Definition: SerialNumber.cc:52
std::ostream & dumpRange(std::ostream &str, TIterator begin, TIterator end, const std::string &intro="{", const std::string &pfx="\n ", const std::string &sep="\n ", const std::string &sfx="\n", const std::string &extro="}")
Print range defined by iterators (multiline style).
Definition: LogTools.h:91
std::ostream & dumpOn(std::ostream &str, const Capability &obj)
Definition: Capability.cc:567
bool deserialize(const std::string &str_r, DownloadMode &result_r)
Definition: DownloadMode.cc:23
std::string asString(const Patch::Category &obj)
Definition: Patch.cc:122
int invokeOnEach(TIterator begin_r, TIterator end_r, TFilter filter_r, TFunction fnc_r)
Iterate through [begin_r,end_r) and invoke fnc_r on each item that passes filter_r.
Definition: Algorithm.h:30
match functor.
Definition: Edition.h:161
bool operator()(const std::string &str)
Definition: PoolQuery.cc:553
PoolQuery::StrContainer & _cont
Definition: PoolQuery.cc:547
bool operator()(const std::string &str)
Definition: PoolQuery.cc:541
MyInserter(PoolQuery::StrContainer &cont)
Definition: PoolQuery.cc:539
represents all atributes in PoolQuery except SolvAtributes, which are used as is (not needed extend a...
Definition: PoolQuery.cc:1071
PoolQueryAttr(const std::string &str_r)
Definition: PoolQuery.cc:1084
static const PoolQueryAttr stringAttr
Definition: PoolQuery.cc:1095
static const PoolQueryAttr kindAttr
Definition: PoolQuery.cc:1093
static const PoolQueryAttr editionAttr
Definition: PoolQuery.cc:1100
static const PoolQueryAttr installStatusAttr
Definition: PoolQuery.cc:1099
static const PoolQueryAttr commentAttr
Definition: PoolQuery.cc:1094
static const PoolQueryAttr repoAttr
Definition: PoolQuery.cc:1092
static const PoolQueryAttr requireAllAttr
Definition: PoolQuery.cc:1097
PoolQueryAttr(const char *cstr_r)
Definition: PoolQuery.cc:1080
static const PoolQueryAttr caseSensitiveAttr
Definition: PoolQuery.cc:1098
static const PoolQueryAttr noAttr
Definition: PoolQuery.cc:1089
static const PoolQueryAttr complexAttr
Definition: PoolQuery.cc:1101
static const PoolQueryAttr stringTypeAttr
Definition: PoolQuery.cc:1096
constPtrType getPtr() const
Definition: PtrTypes.h:349
Relational operators.
Definition: Rel.h:44
for_use_in_switch inSwitch() const
Enumarator provided for use in switch statement.
Definition: Rel.h:141
static const Rel NONE
Definition: Rel.h:57
static const Rel ANY
Definition: Rel.h:56
static const Rel EQ
Definition: Rel.h:50
for_use_in_switch _op
The operator.
Definition: Rel.h:154
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
#define arrayBegin(A)
Simple C-array iterator.
Definition: Easy.h:41
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
#define arrayEnd(A)
Definition: Easy.h:43
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:418
#define WAR
Definition: Logger.h:97