libzypp  17.36.1
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 
882  void PoolQuery::addString(const std::string & value)
883  { _pimpl->_strings.insert(value); }
884 
885  void PoolQuery::addAttribute(const sat::SolvAttr & attr, const std::string & value)
886  { _pimpl->_attrs[attr].insert(value); }
887 
888  void PoolQuery::addDependency( const sat::SolvAttr & attr, const std::string & name, const Rel & op, const Edition & edition )
889  {
890  // Default Match::OTHER indicates need to compile, i.e. to merge name into the global search string and mode.
891  return addDependency( attr, name, op, edition, Arch_empty, Match::OTHER );
892  }
893 
894  void PoolQuery::addDependency( const sat::SolvAttr & attr, const std::string & name, const Rel & op, const Edition & edition, const Arch & arch )
895  {
896  // Default Match::OTHER indicates need to compile, i.e. to merge name into the global search string and mode.
897  return addDependency( attr, name, op, edition, arch, Match::OTHER );
898  }
899 
900  void PoolQuery::addDependency( const sat::SolvAttr & attr, const std::string & name, const Rel & op, const Edition & edition, const Arch & arch, Match::Mode mode )
901  {
902  if ( op == Rel::NONE ) // will never match.
903  return;
904 
905  // SolvAttr::name with explicit 'kind:name' will overwrite the default _kinds
906  ResKind explicitKind;
907  if ( attr == sat::SolvAttr::name )
908  explicitKind = ResKind::explicitBuiltin( name );
909 
910  // Legacy: Match::OTHER and no additional constraints on edition/arch/kind
911  // require addAttribute, otherwise de-serialisation breaks (serialized
912  // and de-serialized query could be !=).
913  // From the results POV we could also use the predicated case below.
914  if ( op == Rel::ANY && arch.empty() && !explicitKind && mode == Match::OTHER )
915  {
916  addAttribute( attr, name );
917  return;
918  }
919 
920  // Match::OTHER indicates need to compile
921  // (merge global search strings into name).
922  AttrMatchData attrMatchData( attr );
923  if ( !explicitKind )
924  attrMatchData.strMatcher = StrMatcher( name, mode );
925  else
926  {
927  // ResKind::explicitBuiltin call above asserts the presence of the ':' in name
928  attrMatchData.strMatcher = StrMatcher( strchr( name.c_str(), ':')+1, mode );
929  attrMatchData.kindPredicate = explicitKind;
930  }
931 
932  if ( isDependencyAttribute( attr ) )
933  attrMatchData.addPredicate( EditionRangePredicate( op, edition, arch ) );
934  else
935  attrMatchData.addPredicate( SolvableRangePredicate( op, edition, arch ) );
936 
937  _pimpl->_uncompiledPredicated.insert( attrMatchData );
938  }
939 
941  {
942  CapDetail cap( cap_r );
943  if ( ! cap.isSimple() ) // will never match.
944  return;
945 
946  // Matches STRING per default. (won't get compiled!)
947  AttrMatchData attrMatchData( attr, StrMatcher( cap.name().asString() ) );
948 
949  if ( isDependencyAttribute( attr ) )
950  attrMatchData.addPredicate( CapabilityMatchPredicate( cap_r ) );
951  else
952  attrMatchData.addPredicate( SolvableRangePredicate( cap.op(), cap.ed() ) );
953 
954  _pimpl->_uncompiledPredicated.insert( attrMatchData );
955  }
956 
957  void PoolQuery::setEdition(const Edition & edition, const Rel & op)
958  {
960  _pimpl->_op = op;
961  }
962 
968 
970  { return _pimpl->_flags; }
971  void PoolQuery::setFlags( const Match & flags )
972  { _pimpl->_flags = flags; }
973 
974 
980  { _pimpl->_status_flags = flags; }
981 
982 
985  { return _pimpl->_strings; }
986 
989  { return _pimpl->_attrs; }
990 
993  {
994  static const PoolQuery::StrContainer nocontainer;
995  AttrRawStrMap::const_iterator it = _pimpl->_attrs.find(attr);
996  return it != _pimpl->_attrs.end() ? it->second : nocontainer;
997  }
998 
1000  { return _pimpl->_edition; }
1002  { return _pimpl->_op; }
1003 
1004 
1005  const PoolQuery::Kinds &
1007  { return _pimpl->_kinds; }
1008 
1009  const PoolQuery::StrContainer &
1011  { return _pimpl->_repos; }
1012 
1013  const std::string &
1015  { return _pimpl->_comment; }
1016 
1018  { return !_pimpl->_flags.test( Match::NOCASE ); }
1019  void PoolQuery::setCaseSensitive( bool value )
1020  { _pimpl->_flags.turn( Match::NOCASE, !value ); }
1021 
1023  { return _pimpl->_flags.test( Match::FILES ); }
1025  { _pimpl->_flags.turn( Match::FILES, value ); }
1026 
1027  bool PoolQuery::matchExact() const { return _pimpl->_flags.isModeString(); }
1029  bool PoolQuery::matchGlob() const { return _pimpl->_flags.isModeGlob(); }
1030  bool PoolQuery::matchRegex() const { return _pimpl->_flags.isModeRegex(); }
1032 
1034  { return _pimpl->_status_flags; }
1035 
1036  bool PoolQuery::empty() const
1037  {
1038  try { return begin() == end(); }
1039  catch (const Exception & ex) {}
1040  return true;
1041  }
1042 
1044  {
1045  try
1046  {
1047  size_type count = 0;
1048  for_( it, begin(), end() )
1049  ++count;
1050  return count;
1051  }
1052  catch (const Exception & ex) {}
1053  return 0;
1054  }
1055 
1057  { invokeOnEach( begin(), end(), std::move(fnc)); }
1058 
1059 
1060  /*DEPRECATED LEGACY:*/void PoolQuery::setRequireAll( bool ) {}
1061  /*DEPRECATED LEGACY:*/bool PoolQuery::requireAll() const { return false; }
1062 
1064  //
1065  // CLASS NAME : PoolQuery::Attr
1066  //
1071  struct PoolQueryAttr : public IdStringType<PoolQueryAttr>
1072  {
1073  private:
1076  public:
1077 
1078  //noAttr
1080 
1081  explicit PoolQueryAttr( const char* cstr_r )
1082  : _str( cstr_r )
1083  {}
1084 
1085  explicit PoolQueryAttr( const std::string & str_r )
1086  : _str( str_r )
1087  {}
1088 
1089  // unknown atributes
1090  static const PoolQueryAttr noAttr;
1091 
1092  // PoolQuery's own attributes
1093  static const PoolQueryAttr repoAttr;
1094  static const PoolQueryAttr kindAttr;
1098  static const PoolQueryAttr requireAllAttr; // LEAGACY: attribute was defined but never implemented.
1103  };
1104 
1106 
1107  const PoolQueryAttr PoolQueryAttr::repoAttr( "repo" );
1108  const PoolQueryAttr PoolQueryAttr::kindAttr( "type" );
1109  const PoolQueryAttr PoolQueryAttr::commentAttr( "comment" );
1110  const PoolQueryAttr PoolQueryAttr::stringAttr( "query_string" );
1111  const PoolQueryAttr PoolQueryAttr::stringTypeAttr("match_type");
1112  const PoolQueryAttr PoolQueryAttr::requireAllAttr("require_all"); // LEAGACY: attribute was defined but never implemented.
1113  const PoolQueryAttr PoolQueryAttr::caseSensitiveAttr("case_sensitive");
1114  const PoolQueryAttr PoolQueryAttr::installStatusAttr("install_status");
1115  const PoolQueryAttr PoolQueryAttr::editionAttr("version");
1116  const PoolQueryAttr PoolQueryAttr::complexAttr("complex");
1117 
1118  class StringTypeAttr : public IdStringType<PoolQueryAttr>
1119  {
1122 
1123  public:
1125  explicit StringTypeAttr( const char* cstr_r )
1126  : _str( cstr_r ){}
1127  explicit StringTypeAttr( const std::string & str_r )
1128  : _str( str_r ){}
1129 
1130  static const StringTypeAttr noAttr;
1131 
1135  static const StringTypeAttr globAttr;
1136  static const StringTypeAttr wordAttr;
1137  };
1138 
1140 
1142  const StringTypeAttr StringTypeAttr::substringAttr("substring");
1146 
1148 
1149 
1150  //\TODO maybe ctor with stream can be useful
1151  //\TODO let it throw, let it throw, let it throw.
1152  bool PoolQuery::recover( std::istream &str, char delim )
1153  {
1154  bool finded_something = false; //indicates some atributes is finded
1155  std::string s;
1156  do {
1157  if ( str.eof() )
1158  break;
1159 
1160  getline( str, s, delim );
1161 
1162  if ((!s.empty()) && s[0]=='#') //comment
1163  {
1164  continue;
1165  }
1166 
1167  std::string::size_type pos = s.find(':');
1168  if (s.empty() || pos == s.npos) // some garbage on line... act like blank line
1169  {
1170  if (finded_something) //is first blank line after record?
1171  {
1172  break;
1173  }
1174  else
1175  {
1176  continue;
1177  }
1178  }
1179 
1180  finded_something = true;
1181 
1182  std::string attrName(str::trim(std::string(s,0,pos))); // trimmed name of atribute
1183  std::string attrValue(str::trim(std::string(s,pos+1,s.npos))); //trimmed value
1184 
1185  PoolQueryAttr attribute( attrName );
1186 
1188  {
1189  addRepo( attrValue );
1190  }
1191  /* some backwards compatibility */
1192  else if ( attribute==PoolQueryAttr::kindAttr || attribute=="kind" )
1193  {
1194  addKind( ResKind(attrValue) );
1195  }
1197  {
1198  setComment( attrValue );
1199  }
1201  || attribute=="global_string")
1202  {
1203  addString( attrValue );
1204  }
1206  || attribute=="string_type" )
1207  {
1208  StringTypeAttr s(attrValue);
1209  if( s == StringTypeAttr::regexAttr )
1210  {
1211  setMatchRegex();
1212  }
1213  else if ( s == StringTypeAttr::globAttr )
1214  {
1215  setMatchGlob();
1216  }
1217  else if ( s == StringTypeAttr::exactAttr )
1218  {
1219  setMatchExact();
1220  }
1221  else if ( s == StringTypeAttr::substringAttr )
1222  {
1224  }
1225  else if ( s == StringTypeAttr::wordAttr )
1226  {
1227  setMatchWord();
1228  }
1229  else if ( s == StringTypeAttr::noAttr )
1230  {
1231  WAR << "unknown string type " << attrValue << endl;
1232  }
1233  else
1234  {
1235  WAR << "forget recover some attribute defined as String type attribute: " << attrValue << endl;
1236  }
1237  }
1239  {
1240  // LEAGACY: attribute was defined but never implemented.
1241  // Actually it should not occur outside our testcases.
1242  }
1244  {
1245  if ( str::strToTrue(attrValue) )
1246  {
1247  setCaseSensitive(true);
1248  }
1249  else if ( !str::strToFalse(attrValue) )
1250  {
1251  setCaseSensitive(false);
1252  }
1253  else
1254  {
1255  WAR << "unknown boolean value " << attrValue << endl;
1256  }
1257  }
1259  {
1260  if( attrValue == "all" )
1261  {
1263  }
1264  else if( attrValue == "installed" )
1265  {
1266  setInstalledOnly();
1267  }
1268  else if( attrValue == "not-installed" )
1269  {
1271  }
1272  else
1273  {
1274  WAR << "Unknown value for install status " << attrValue << endl;
1275  }
1276  }
1278  {
1279  std::string::size_type pos = 0;
1280  Rel rel("==");
1281  if (attrValue.find_first_of("=<>!") == 0)
1282  {
1283  pos = attrValue.find_last_of("=<>");
1284  rel = Rel(attrValue.substr(0, pos+1));
1285  attrValue = str::trim(attrValue.substr(pos+1, attrValue.npos));
1286  }
1287 
1288  setEdition(Edition(attrValue), rel);
1289  }
1290  else if ( attribute == PoolQueryAttr::complexAttr )
1291  {
1292  try
1293  {
1295  }
1296  catch ( const Exception & err )
1297  {
1298  WAR << "Unparsable value for complex: " << err.asUserHistory() << endl;
1299 
1300  }
1301  }
1302  else if ( attribute==PoolQueryAttr::noAttr )
1303  {
1304  WAR << "empty attribute name" << endl;
1305  }
1306  else
1307  {
1308  std::string s = attrName;
1309  str::replaceAll( s,"_",":" );
1310  SolvAttr a(s);
1311  if ( a == SolvAttr::name || isDependencyAttribute( a ) )
1312  {
1313  Capability c( attrValue );
1314  CapDetail d( c );
1315  if ( d.isVersioned() )
1316  addDependency( a, d.name().asString(), d.op(), d.ed() );
1317  else
1318  addDependency( a, attrValue );
1319  }
1320  else
1321  addAttribute( a, attrValue );
1322  }
1323 
1324  } while ( true );
1325 
1326  // OLD STYLE VERSIONED LOCKS:
1327  // solvable_name: kernel
1328  // version: > 1
1329  //
1330  // NEW STYLE VERSIONED LOCKS:
1331  // complex: AttrMatchData solvable:name kernel C SolvableRange\ >\ 1\ \"\"
1332  // or
1333  // solvable_name: kernel > 1
1334  //
1335  // Semantically equivalent as locks, but due to the different syntax
1336  // the complex lock is wrongly handled by zypper.
1337  //
1338  // bsc#1112911: Unfortunately all styles are found in real-life locks-files.
1339  // libzypp will try to make sure, when parsing the locks-file, that complex
1340  // locks are rewritten into to OLD STYLE queries zypper can handle.
1341  if ( !_pimpl->_attrs.count(SolvAttr::name) && _pimpl->_uncompiledPredicated.size() == 1 )
1342  {
1343  // No OLD STYLE lock for SolvAttr::name and exactly one complex lock...
1344  const AttrMatchData & attrmatch { *_pimpl->_uncompiledPredicated.begin() };
1345  if ( attrmatch.attr == SolvAttr::name && attrmatch.strMatcher.flags().mode() == Match::OTHER )
1346  {
1347  // ...for SolvAttr::name and following the global search flags.
1348  // A candidate for a rewrite?
1349 
1350  std::vector<std::string> words;
1351  str::splitEscaped( attrmatch.predicateStr, std::back_inserter(words) );
1352  if ( words.size() < 4 || words[3].empty() )
1353  {
1354  // We have _NO_ arch rule in the complex predicate, so we can simplify it.
1355  //
1356  // NOTE: AFAIK it's not possible to create (or have created) a complex lock
1357  // with arch rule with zypper means. Nevertheless, in case such a rule made it
1358  // into a locks file, it's better to have a strange looking 'zypper locks' list
1359  // than to lock the wrong packages.
1360  // (and remember that you can't use "addAttribute( SolvAttr::arch, ... )" because
1361  // attributes are `OR`ed)
1362 
1363  // kind
1364  if ( attrmatch.kindPredicate )
1365  {
1366  _pimpl->_kinds.clear(); // an explicit kind overwrites any global one
1367  addKind( attrmatch.kindPredicate );
1368  }
1369 
1370  // name
1371  addAttribute( SolvAttr::name, attrmatch.strMatcher.searchstring() );
1372 
1373  // edition
1374  std::vector<std::string> words;
1375  str::splitEscaped( attrmatch.predicateStr, std::back_inserter(words) );
1376  if ( ! words.empty() )
1377  {
1378  if ( words[0] == "EditionRange" || words[0] == "SolvableRange" )
1379  {
1380  setEdition( Edition(words[2]), Rel(words[1]) );
1381  }
1382  }
1383 
1384  // finally remove the complex lock
1385  _pimpl->_uncompiledPredicated.clear();
1386  }
1387  }
1388  }
1389 
1390  return finded_something;
1391  }
1392 
1393  void PoolQuery::serialize( std::ostream &str, char delim ) const
1394  {
1395  //separating delim
1396  str << delim;
1397  //iterate thrue all settings and write it
1398  static const zypp::PoolQuery q; //not save default options, so create default query example
1399 
1400  for_( it, repos().begin(), repos().end() )
1401  {
1402  str << "repo: " << *it << delim ;
1403  }
1404 
1405  for_( it, kinds().begin(), kinds().end() )
1406  {
1407  str << PoolQueryAttr::kindAttr.asString() << ": "
1408  << it->idStr() << delim ;
1409  }
1410 
1411  if (editionRel() != Rel::ANY && edition() != Edition::noedition)
1412  str << PoolQueryAttr::editionAttr.asString() << ": " << editionRel() << " " << edition() << delim;
1413 
1414  if (matchMode()!=q.matchMode())
1415  {
1416  switch( matchMode() )
1417  {
1418  case Match::STRING:
1419  str << PoolQueryAttr::stringTypeAttr.asString() << ": exact" << delim;
1420  break;
1421  case Match::SUBSTRING:
1423  << ": substring" << delim;
1424  break;
1425  case Match::GLOB:
1426  str << PoolQueryAttr::stringTypeAttr.asString() << ": glob" << delim;
1427  break;
1428  case Match::REGEX:
1429  str << PoolQueryAttr::stringTypeAttr.asString() << ": regex" << delim;
1430  break;
1431  default:
1432  WAR << "unknown match type " << matchMode() << endl;
1433  }
1434  }
1435 
1436  if( caseSensitive() != q.caseSensitive() )
1437  {
1438  str << "case_sensitive: ";
1439  if (caseSensitive())
1440  {
1441  str << "on" << delim;
1442  }
1443  else
1444  {
1445  str << "off" << delim;
1446  }
1447  }
1448 
1449  if( statusFilterFlags() != q.statusFilterFlags() )
1450  {
1451  switch( statusFilterFlags() )
1452  {
1453  case ALL:
1454  str << "install_status: all" << delim;
1455  break;
1456  case INSTALLED_ONLY:
1457  str << "install_status: installed" << delim;
1458  break;
1459  case UNINSTALLED_ONLY:
1460  str << "install_status: not-installed" << delim;
1461  break;
1462  }
1463  }
1464 
1465  for_( it, strings().begin(), strings().end() )
1466  {
1467  str << PoolQueryAttr::stringAttr.asString()<< ": " << *it << delim;
1468  }
1469 
1470  for_( it, attributes().begin(), attributes().end() )
1471  {
1472  std::string s = it->first.asString();
1473  str::replaceAll(s,":","_");
1474  for_( it2,it->second.begin(),it->second.end() )
1475  {
1476  str << s <<": "<< *it2 << delim;
1477  }
1478  }
1479 
1481  {
1482  str << "complex: "<< it->serialize() << delim;
1483  }
1484 
1485  if ( const std::string & c { comment() }; not c.empty() )
1486  str << PoolQueryAttr::commentAttr.asString() << ": " << c << delim ;
1487 
1488  //separating delim - protection
1489  str << delim;
1490  }
1491 
1492  std::string PoolQuery::asString() const
1493  { return _pimpl->asString(); }
1494 
1495  std::ostream & operator<<( std::ostream & str, const PoolQuery & obj )
1496  { return str << obj.asString(); }
1497 
1498  std::ostream & dumpOn( std::ostream & str, const PoolQuery & obj )
1499  { return dumpRange( str << obj, obj.begin(), obj.end() ); }
1500 
1501  bool PoolQuery::operator==( const PoolQuery & rhs ) const
1502  { return *_pimpl == *rhs._pimpl; }
1503 
1504  bool PoolQuery::operator<( const PoolQuery & rhs ) const
1505  { return *_pimpl < *rhs._pimpl; }
1506 
1508  namespace detail
1509  {
1510 
1512  //
1513  // CLASS NAME : PoolQueryMatcher
1514  //
1532  {
1533  public:
1535 
1536  public:
1537  const base_iterator & end() const
1538  {
1539  static base_iterator _end;
1540  return _end;
1541  }
1542 
1543  bool advance( base_iterator & base_r ) const
1544  {
1545  if ( base_r == end() )
1546  base_r = startNewQyery(); // first candidate
1547  else
1548  {
1549  base_r.nextSkipSolvable(); // assert we don't visit this Solvable again
1550  ++base_r; // advance to next candidate
1551  }
1552 
1553  while ( base_r != end() )
1554  {
1555  if ( isAMatch( base_r ) )
1556  return true;
1557  // No match: try next
1558  ++base_r;
1559  }
1560  return false;
1561  }
1562 
1566  void matchDetail( const base_iterator & base_r, std::vector<base_iterator> & return_r ) const
1567  {
1568  if ( base_r == end() )
1569  return;
1570 
1571  sat::Solvable inSolvable( base_r.inSolvable() );
1572 
1573  if ( _attrMatchList.size() == 1 )
1574  {
1575  // base_r is already on the 1st matching attribute!
1576  // String matching is done by the base iterator. We must check the predicate here.
1577  // Let's see if there are more matches for this solvable:
1578  base_iterator base( base_r );
1579  base.stayInThisSolvable(); // avoid discarding matches we found far away from here.
1580  return_r.push_back( base );
1581 
1582  const AttrMatchData::Predicate & predicate( _attrMatchList.front().predicate );
1583  for ( ++base; base.inSolvable() == inSolvable; ++base ) // safe even if base == end()
1584  {
1585  if ( ! predicate || predicate( base ) )
1586  return_r.push_back( base );
1587  }
1588  }
1589  else
1590  {
1591  // Here: search all attributes ;(
1592  for_( mi, _attrMatchList.begin(), _attrMatchList.end() )
1593  {
1594  const AttrMatchData & matchData( *mi );
1595  sat::LookupAttr q( matchData.attr, inSolvable );
1596  if ( matchData.strMatcher ) // an empty searchstring matches always
1597  q.setStrMatcher( matchData.strMatcher );
1598 
1599  if ( ! q.empty() ) // there are matches.
1600  {
1601  // now check any predicate:
1602  const AttrMatchData::Predicate & predicate( matchData.predicate );
1603  for_( it, q.begin(), q.end() )
1604  {
1605  if ( ! predicate || predicate( it ) )
1606  return_r.push_back( it );
1607  }
1608  }
1609  }
1610  }
1611  }
1612 
1613  public:
1614  PoolQueryMatcher(const PoolQueryMatcher &) = default;
1615  PoolQueryMatcher(PoolQueryMatcher &&) = default;
1616  PoolQueryMatcher &operator=(const PoolQueryMatcher &) = default;
1618 
1622  PoolQueryMatcher( const shared_ptr<const PoolQuery::Impl> & query_r )
1623  {
1624  query_r->compile();
1625 
1626  // Repo restriction:
1627  sat::Pool satpool( sat::Pool::instance() );
1628 
1629  for_( it, query_r->_repos.begin(), query_r->_repos.end() )
1630  {
1631  Repository r( satpool.reposFind( *it ) );
1632  if ( r )
1633  _repos.insert( r );
1634  else
1635  _neverMatchRepo = true;
1636  }
1637  // _neverMatchRepo: we just need to catch the case that no repo
1638  // matched, so we'd interpret the empty list as 'take from all'
1639  if ( _neverMatchRepo && ! _repos.empty() )
1640  _neverMatchRepo = false;
1641 
1642  // Kind restriction:
1643  _kinds = query_r->_kinds;
1644  // Edition restriction:
1645  _op = query_r->_op;
1646  _edition = query_r->_edition;
1647  // Status restriction:
1648  _status_flags = query_r->_status_flags;
1649  // StrMatcher
1650  _attrMatchList = query_r->_attrMatchList;
1651  }
1652 
1654  {}
1655 
1656  private:
1659  {
1660  sat::LookupAttr q;
1661 
1662  if ( _neverMatchRepo )
1663  return q.end();
1664 
1665  // Repo restriction:
1666  if ( _repos.size() == 1 )
1667  q.setRepo( *_repos.begin() );
1668  // else: handled in isAMatch.
1669 
1670  // Attribute restriction:
1671  if ( _attrMatchList.size() == 1 ) // all (SolvAttr::allAttr) or 1 attr
1672  {
1673  const AttrMatchData & matchData( _attrMatchList.front() );
1674  q.setAttr( matchData.attr );
1675  if ( matchData.strMatcher ) // empty searchstring matches always
1676  q.setStrMatcher( matchData.strMatcher );
1677  }
1678  else // more than 1 attr (but not all)
1679  {
1680  // no restriction, it's all handled in isAMatch.
1682  }
1683 
1684  return q.begin();
1685  }
1686 
1687 
1698  bool isAMatch( base_iterator & base_r ) const
1699  {
1701  Repository inRepo( base_r.inRepo() );
1702  // Status restriction:
1703  if ( _status_flags
1704  && ( (_status_flags == PoolQuery::INSTALLED_ONLY) != inRepo.isSystemRepo() ) )
1705  {
1706  base_r.nextSkipRepo();
1707  return false;
1708  }
1709  // Repo restriction:
1710  if ( _repos.size() > 1 && _repos.find( inRepo ) == _repos.end() )
1711  {
1712  base_r.nextSkipRepo();
1713  return false;
1714  }
1716  sat::Solvable inSolvable( base_r.inSolvable() );
1717  // Edition restriction:
1718  if ( _op != Rel::ANY && !compareByRel( _op, inSolvable.edition(), _edition, Edition::Match() ) )
1719  {
1720  base_r.nextSkipSolvable();
1721  return false;
1722  }
1723 
1724  // Kind restriction:
1725  // Delay the decision to nextSkipSolvable and return false, as there may be
1726  // some explicit kind:name predicate which overrules the global kinds.
1727  bool globalKindOk =( _kinds.empty() || inSolvable.isKind( _kinds.begin(), _kinds.end() ) );
1728 
1730  // string and predicate matching:
1731 
1732  if ( _attrMatchList.size() == 1 )
1733  {
1734  // String matching was done by the base iterator.
1735  // Now check any predicate:
1736  const AttrMatchData & matchData( _attrMatchList.front() );
1737 
1738  if ( matchData.kindPredicate )
1739  {
1740  if ( matchData.kindPredicate != inSolvable.kind() )
1741  {
1742  base_r.nextSkipSolvable(); // this matchData will never match in this solvable
1743  return false;
1744  }
1745  }
1746  else if ( !globalKindOk )
1747  return false; // only matching kindPredicate could overwrite this
1748 
1749  if ( !matchData.predicate || matchData.predicate( base_r ) )
1750  return true;
1751 
1752  return false; // no skip as there may be more occurrences in this solvable of this attr.
1753  }
1754 
1755  // Here: search all attributes ;(
1756  for_( mi, _attrMatchList.begin(), _attrMatchList.end() )
1757  {
1758  const AttrMatchData & matchData( *mi );
1759 
1760  if ( matchData.kindPredicate )
1761  {
1762  if ( matchData.kindPredicate != inSolvable.kind() )
1763  continue; // this matchData does not apply
1764  }
1765  else if ( !globalKindOk )
1766  continue; // only matching kindPredicate could overwrite this
1767 
1768  sat::LookupAttr q( matchData.attr, inSolvable );
1769  if ( matchData.strMatcher ) // an empty searchstring matches always
1770  q.setStrMatcher( matchData.strMatcher );
1771 
1772  if ( ! q.empty() ) // there are matches.
1773  {
1774  // now check any predicate:
1775  const AttrMatchData::Predicate & predicate( matchData.predicate );
1776  if ( predicate )
1777  {
1778  for_( it, q.begin(), q.end() )
1779  {
1780  if ( predicate( it ) )
1781  return true;
1782  }
1783  }
1784  else
1785  return true;
1786  }
1787  }
1788  base_r.nextSkipSolvable();
1789  return false;
1790  }
1791 
1792  private:
1794  std::set<Repository> _repos;
1797  std::set<ResKind> _kinds;
1804  AttrMatchList _attrMatchList;
1805  };
1807 
1809  {
1810  // matcher restarts if at end! It is called from the ctor
1811  // to get the 1st match. But if the end is reached, it should
1812  // be deleted, otherwise we'd start over again.
1813  if ( !_matcher )
1814  return; // at end
1815  if ( _matches )
1816  _matches.reset(); // invalidate old matches
1817  if ( ! _matcher->advance( base_reference() ) )
1818  _matcher.reset();
1819  }
1820 
1822  {
1823  if ( _matches )
1824  return *_matches;
1825 
1826  if ( !_matcher )
1827  {
1828  // at end of query:
1829  static const Matches _none;
1830  return _none;
1831  }
1832 
1833  _matches.reset( new Matches );
1834  _matcher->matchDetail( base_reference(), *_matches );
1835  return *_matches;
1836  }
1837 
1838  std::ostream & dumpOn( std::ostream & str, const PoolQueryIterator & obj )
1839  {
1840  str << *obj;
1841  if ( ! obj.matchesEmpty() )
1842  {
1843  for_( it, obj.matchesBegin(), obj.matchesEnd() )
1844  {
1845  str << endl << " " << it->inSolvAttr() << "\t" << it->asString();
1846  }
1847  }
1848  return str;
1849  }
1850 
1852  } //namespace detail
1854 
1856  {
1857  return shared_ptr<detail::PoolQueryMatcher>( new detail::PoolQueryMatcher( _pimpl.getPtr() ) );
1858  }
1859 
1861 } // namespace zypp
1863 
std::string asString(const Patch::Category &obj)
Definition: Patch.cc:122
int _status_flags
Installed status filter flags.
Definition: PoolQuery.cc:1802
Interface to gettext.
std::set< std::string > StrContainer
Definition: PoolQuery.h:94
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off, never.
Definition: String.cc:82
static const PoolQueryAttr installStatusAttr
Definition: PoolQuery.cc:1100
bool matchExact() const
Definition: PoolQuery.cc:1027
Rel _op
Operator for edition condition.
Definition: PoolQuery.cc:455
A Solvable object within the sat Pool.
Definition: Solvable.h:53
static const SolvAttr dep_provides
Definition: SolvAttr.h:79
void setUninstalledOnly()
Return only packages from repos other than .
Definition: PoolQuery.cc:977
bool isVersioned() const
Definition: Capability.h:355
StatusFilter
Installed status filter setters.
Definition: PoolQuery.h:174
Arch _arch
Definition: PoolQuery.cc:103
static const StringTypeAttr substringAttr
Definition: PoolQuery.cc:1133
const AttrRawStrMap & attributes() const
Map (map<SolvAttr, StrContainer>) of attribute values added via addAttribute(), addDep in string form...
Definition: PoolQuery.cc:988
bool compareByRel(Rel op, const Tp &lhs, const Tp &rhs, TCompare compare)
Comparison of two elements using relational operator op.
Definition: RelCompare.h:108
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:885
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
static const SolvAttr dep_obsoletes
Definition: SolvAttr.h:80
void compile() const
Compile the regex.
Definition: PoolQuery.cc:564
std::vector< sat::LookupAttr::iterator > Matches
Definition: PoolQuery.h:524
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:424
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:1797
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:1838
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
static const StringTypeAttr noAttr
Definition: PoolQuery.cc:1130
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:516
void setFlags(const Match &flags)
Free function to set libsolv repo search flags.
Definition: PoolQuery.cc:971
String matching (STRING|SUBSTRING|GLOB|REGEX).
Definition: StrMatcher.h:297
Relational operators.
Definition: Rel.h:45
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:1099
bool requireAll() const ZYPP_DEPRECATED
Definition: PoolQuery.cc:1061
void execute(ProcessResolvable fnc)
Executes the query with the current settings.
Definition: PoolQuery.cc:1056
void addString(const std::string &value)
Add a global query string.
Definition: PoolQuery.cc:882
bool operator==(const Map &lhs, const Map &rhs)
Definition: Map.cc:125
Lightweight attribute value lookup.
Definition: LookupAttr.h:109
Rel _op
Edition filter.
Definition: PoolQuery.cc:1799
static const Rel EQ
Definition: Rel.h:52
const StrContainer & strings() const
Search strings added via addString()
Definition: PoolQuery.cc:984
constPtrType getPtr() const
Definition: PtrTypes.h:359
Regular Expression.
Definition: StrMatcher.h:48
static const PoolQueryAttr commentAttr
Definition: PoolQuery.cc:1095
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:425
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:120
const Matches & matches() const
Definition: PoolQuery.cc:1821
void setMatchGlob()
Set to match globs.
Definition: PoolQuery.cc:966
void setMatchRegex()
Set to use the query strings as regexes.
Definition: PoolQuery.cc:965
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
const Arch Arch_empty(IdString::Empty)
String related utilities and Regular expression matching.
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
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
static const SolvAttr dep_recommends
Definition: SolvAttr.h:83
bool operator<(const PoolQuery &b) const
Definition: PoolQuery.cc:1504
std::string getline(std::istream &str)
Read one line from stream.
Definition: IOStream.cc:33
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:1622
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:888
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:43
void setCaseSensitive(bool value=true)
Turn case sentitivity on or off (unsets or sets SEARCH_NOCASE flag).
Definition: PoolQuery.cc:1019
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:1531
static const Rel ANY
Definition: Rel.h:58
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:1006
Base class for creating IdString based types.
Definition: IdStringType.h:86
PoolQueryAttr(const std::string &str_r)
Definition: PoolQuery.cc:1085
unsigned int size_type
Definition: PoolQuery.h:98
std::string asString() const
String representation.
Definition: PoolQuery.cc:780
size_type size() const
Number of solvables in the query result.
Definition: PoolQuery.cc:1043
Unknown match mode.
Definition: StrMatcher.h:257
static const PoolQueryAttr noAttr
Definition: PoolQuery.cc:1090
static const PoolQueryAttr repoAttr
Definition: PoolQuery.cc:1093
bool operator==(const PoolQuery &b) const
Definition: PoolQuery.cc:1501
void serialize(std::ostream &str, char delim='\n') const
Writes a machine-readable string representation of the query to stream.
Definition: PoolQuery.cc:1393
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:992
AttrMatchList _attrMatchList
StrMatcher per attribtue.
Definition: PoolQuery.cc:1804
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:1017
StringTypeAttr(const char *cstr_r)
Definition: PoolQuery.cc:1125
static Pool instance()
Singleton ctor.
Definition: Pool.h:55
void setRequireAll(bool require_all=true) ZYPP_DEPRECATED
Definition: PoolQuery.cc:1060
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:1022
std::string asString() const
Definition: IdStringType.h:108
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:979
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:1010
static const SolvAttr dep_supplements
Definition: SolvAttr.h:85
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:127
#define OUTS(M, S)
void setMatchWord()
Set substring to match words.
Definition: PoolQuery.cc:967
const_iterator begin() const
Query result accessers.
Definition: PoolQuery.cc:1855
#define WAR
Definition: Logger.h:101
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:1014
static const SolvAttr dep_enhances
Definition: SolvAttr.h:86
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:1658
bool operator!=(const SolvableType< Derived > &lhs, const Solvable &rhs)
Definition: SolvableType.h:200
bool operator<(const SolvableType< Derived > &lhs, const Solvable &rhs)
Definition: SolvableType.h:213
void nextSkipSolvable()
On the next call to operator++ advance to the next Solvable.
Definition: LookupAttr.cc:364
const Rel editionRel() const
Definition: PoolQuery.cc:1001
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:1127
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:143
void setInstalledOnly()
Return only repo packages.
Definition: PoolQuery.cc:975
static const StringTypeAttr exactAttr
Definition: PoolQuery.cc:1132
bool recover(std::istream &str, char delim='\n')
Reads from stream query.
Definition: PoolQuery.cc:1152
Mode
Mode flags (mutual exclusive).
Definition: StrMatcher.h:40
std::string asString() const
Return a human-readable description of the query.
Definition: PoolQuery.cc:1492
const base_iterator & end() const
Definition: PoolQuery.cc:1537
void matchDetail(const base_iterator &base_r, std::vector< base_iterator > &return_r) const
Provide all matching attributes within this solvable.
Definition: PoolQuery.cc:1566
bool advance(base_iterator &base_r) const
Definition: PoolQuery.cc:1543
Editions with v-r setparator highlighted.
const_iterator end() const
An iterator pointing to the end of the query result.
Definition: PoolQuery.h:621
static const PoolQueryAttr stringTypeAttr
Definition: PoolQuery.cc:1097
static const StringTypeAttr wordAttr
Definition: PoolQuery.cc:1136
#define arrayEnd(A)
Definition: Easy.h:38
const Edition edition() const
Definition: PoolQuery.cc:999
bool operator<(const PoolQuery::Impl &rhs) const
Definition: PoolQuery.cc:469
void setMatchSubstring()
Set to substring (the default).
Definition: PoolQuery.cc:963
represents all atributes in PoolQuery except SolvAtributes, which are used as is (not needed extend a...
Definition: PoolQuery.cc:1071
for_use_in_switch _op
The operator.
Definition: Rel.h:156
static const SolvAttr dep_suggests
Definition: SolvAttr.h:84
std::set< Repository > _repos
Repositories include in the search.
Definition: PoolQuery.cc:1794
std::string predicateStr
Definition: PoolQuery.cc:315
static const PoolQueryAttr stringAttr
Definition: PoolQuery.cc:1096
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:1031
Base class for Exception.
Definition: Exception.h:146
std::string rxEscapeGlob(std::string str_r)
Escape GLOB str_r for use in a regex (not anchored by "^" or "$").
Definition: String.cc:421
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:1102
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:957
void setMatchExact()
Set to match exact string instead of substring.
Definition: PoolQuery.cc:964
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:605
StatusFilter statusFilterFlags() const
Definition: PoolQuery.cc:1033
static const SolvAttr dep_requires
Definition: SolvAttr.h:82
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:1028
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:1036
shared_ptr< Matches > _matches
Definition: PoolQuery.h:606
static const SolvAttr dep_conflicts
Definition: SolvAttr.h:81
DefaultIntegral< bool, false > _neverMatchRepo
Definition: PoolQuery.cc:1795
static const PoolQueryAttr requireAllAttr
Definition: PoolQuery.cc:1098
Match flags() const
Free function to get libsolv repo search flags.
Definition: PoolQuery.cc:969
static const PoolQueryAttr editionAttr
Definition: PoolQuery.cc:1101
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:1024
std::string asString() const
Conversion to std::string
Definition: IdString.h:99
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:486
AttrMatchList _attrMatchList
StrMatcher per attribtue.
Definition: PoolQuery.cc:525
StatusFilter _status_flags
Sat solver status flags.
Definition: PoolQuery.cc:450
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 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:1081
bool isAMatch(base_iterator &base_r) const
Check whether we are on a match.
Definition: PoolQuery.cc:1698
static const CapMatch yes
Definition: CapMatch.h:52
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:1094
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:1029
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:1030
static const StringTypeAttr globAttr
Definition: PoolQuery.cc:1135
iterator begin() const
Iterator to the begin of query results.
Definition: LookupAttr.cc:237
#define arrayBegin(A)
Simple C-array iterator.
Definition: Easy.h:36
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:1134
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition: String.cc:64
bool isModeSubstring() const
Whether this has mode SUBSTRING.
Definition: StrMatcher.h:173
static const Rel NONE
Definition: Rel.h:59