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