cachefilter.cc 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. /** \file cachefilter.h
  4. Collection of functor classes */
  5. /*}}}*/
  6. // Include Files /*{{{*/
  7. #include <config.h>
  8. #include <apt-pkg/cachefile.h>
  9. #include <apt-pkg/cachefilter.h>
  10. #include <apt-pkg/error.h>
  11. #include <apt-pkg/pkgcache.h>
  12. #include <apt-pkg/cacheiterators.h>
  13. #include <apt-pkg/strutl.h>
  14. #include <apt-pkg/macros.h>
  15. #include <string>
  16. #include <string.h>
  17. #include <regex.h>
  18. #include <fnmatch.h>
  19. #include <apti18n.h>
  20. /*}}}*/
  21. namespace APT {
  22. namespace CacheFilter {
  23. APT_CONST Matcher::~Matcher() {}
  24. APT_CONST PackageMatcher::~PackageMatcher() {}
  25. // Name matches RegEx /*{{{*/
  26. PackageNameMatchesRegEx::PackageNameMatchesRegEx(std::string const &Pattern) {
  27. pattern = new regex_t;
  28. int const Res = regcomp(pattern, Pattern.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB);
  29. if (Res == 0)
  30. return;
  31. delete pattern;
  32. pattern = NULL;
  33. char Error[300];
  34. regerror(Res, pattern, Error, sizeof(Error));
  35. _error->Error(_("Regex compilation error - %s"), Error);
  36. }
  37. bool PackageNameMatchesRegEx::operator() (pkgCache::PkgIterator const &Pkg) {
  38. if (unlikely(pattern == NULL))
  39. return false;
  40. else
  41. return regexec(pattern, Pkg.Name(), 0, 0, 0) == 0;
  42. }
  43. bool PackageNameMatchesRegEx::operator() (pkgCache::GrpIterator const &Grp) {
  44. if (unlikely(pattern == NULL))
  45. return false;
  46. else
  47. return regexec(pattern, Grp.Name(), 0, 0, 0) == 0;
  48. }
  49. PackageNameMatchesRegEx::~PackageNameMatchesRegEx() {
  50. if (pattern == NULL)
  51. return;
  52. regfree(pattern);
  53. delete pattern;
  54. }
  55. /*}}}*/
  56. // Name matches Fnmatch /*{{{*/
  57. PackageNameMatchesFnmatch::PackageNameMatchesFnmatch(std::string const &Pattern) :
  58. Pattern(Pattern) {}
  59. bool PackageNameMatchesFnmatch::operator() (pkgCache::PkgIterator const &Pkg) {
  60. return fnmatch(Pattern.c_str(), Pkg.Name(), FNM_CASEFOLD) == 0;
  61. }
  62. bool PackageNameMatchesFnmatch::operator() (pkgCache::GrpIterator const &Grp) {
  63. return fnmatch(Pattern.c_str(), Grp.Name(), FNM_CASEFOLD) == 0;
  64. }
  65. /*}}}*/
  66. // Architecture matches <kernel>-<cpu> specification /*{{{*/
  67. //----------------------------------------------------------------------
  68. /* The complete architecture, consisting of <kernel>-<cpu>. */
  69. static std::string CompleteArch(std::string const &arch) {
  70. if (arch.find('-') != std::string::npos) {
  71. // ensure that only -any- is replaced and not something like company-
  72. std::string complete = std::string("-").append(arch).append("-");
  73. complete = SubstVar(complete, "-any-", "-*-");
  74. complete = complete.substr(1, complete.size()-2);
  75. return complete;
  76. }
  77. else if (arch == "any") return "*-*";
  78. else return "linux-" + arch;
  79. }
  80. PackageArchitectureMatchesSpecification::PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern) :
  81. literal(pattern), complete(CompleteArch(pattern)), isPattern(isPattern) {
  82. }
  83. bool PackageArchitectureMatchesSpecification::operator() (char const * const &arch) {
  84. if (strcmp(literal.c_str(), arch) == 0 ||
  85. strcmp(complete.c_str(), arch) == 0)
  86. return true;
  87. std::string const pkgarch = CompleteArch(arch);
  88. if (isPattern == true)
  89. return fnmatch(complete.c_str(), pkgarch.c_str(), 0) == 0;
  90. return fnmatch(pkgarch.c_str(), complete.c_str(), 0) == 0;
  91. }
  92. bool PackageArchitectureMatchesSpecification::operator() (pkgCache::PkgIterator const &Pkg) {
  93. return (*this)(Pkg.Arch());
  94. }
  95. PackageArchitectureMatchesSpecification::~PackageArchitectureMatchesSpecification() {
  96. }
  97. /*}}}*/
  98. // Package is new install /*{{{*/
  99. PackageIsNewInstall::PackageIsNewInstall(pkgCacheFile * const Cache) : Cache(Cache) {}
  100. APT_PURE bool PackageIsNewInstall::operator() (pkgCache::PkgIterator const &Pkg) {
  101. return (*Cache)[Pkg].NewInstall();
  102. }
  103. PackageIsNewInstall::~PackageIsNewInstall() {}
  104. /*}}}*/
  105. // Generica like True, False, NOT, AND, OR /*{{{*/
  106. APT_CONST bool TrueMatcher::operator() (pkgCache::PkgIterator const &) { return true; }
  107. APT_CONST bool TrueMatcher::operator() (pkgCache::GrpIterator const &) { return true; }
  108. APT_CONST bool TrueMatcher::operator() (pkgCache::VerIterator const &) { return true; }
  109. APT_CONST bool FalseMatcher::operator() (pkgCache::PkgIterator const &) { return false; }
  110. APT_CONST bool FalseMatcher::operator() (pkgCache::GrpIterator const &) { return false; }
  111. APT_CONST bool FalseMatcher::operator() (pkgCache::VerIterator const &) { return false; }
  112. NOTMatcher::NOTMatcher(Matcher * const matcher) : matcher(matcher) {}
  113. bool NOTMatcher::operator() (pkgCache::PkgIterator const &Pkg) { return ! (*matcher)(Pkg); }
  114. bool NOTMatcher::operator() (pkgCache::GrpIterator const &Grp) { return ! (*matcher)(Grp); }
  115. bool NOTMatcher::operator() (pkgCache::VerIterator const &Ver) { return ! (*matcher)(Ver); }
  116. NOTMatcher::~NOTMatcher() { delete matcher; }
  117. ANDMatcher::ANDMatcher() {}
  118. ANDMatcher::ANDMatcher(Matcher * const matcher1) {
  119. AND(matcher1);
  120. }
  121. ANDMatcher::ANDMatcher(Matcher * const matcher1, Matcher * const matcher2) {
  122. AND(matcher1).AND(matcher2);
  123. }
  124. ANDMatcher::ANDMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3) {
  125. AND(matcher1).AND(matcher2).AND(matcher3);
  126. }
  127. ANDMatcher::ANDMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3, Matcher * const matcher4) {
  128. AND(matcher1).AND(matcher2).AND(matcher3).AND(matcher4);
  129. }
  130. ANDMatcher::ANDMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3, Matcher * const matcher4, Matcher * const matcher5) {
  131. AND(matcher1).AND(matcher2).AND(matcher3).AND(matcher4).AND(matcher5);
  132. }
  133. ANDMatcher& ANDMatcher::AND(Matcher * const matcher) { matchers.push_back(matcher); return *this; }
  134. bool ANDMatcher::operator() (pkgCache::PkgIterator const &Pkg) {
  135. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  136. if ((**M)(Pkg) == false)
  137. return false;
  138. return true;
  139. }
  140. bool ANDMatcher::operator() (pkgCache::GrpIterator const &Grp) {
  141. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  142. if ((**M)(Grp) == false)
  143. return false;
  144. return true;
  145. }
  146. bool ANDMatcher::operator() (pkgCache::VerIterator const &Ver) {
  147. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  148. if ((**M)(Ver) == false)
  149. return false;
  150. return true;
  151. }
  152. ANDMatcher::~ANDMatcher() {
  153. for (std::vector<Matcher *>::iterator M = matchers.begin(); M != matchers.end(); ++M)
  154. delete *M;
  155. }
  156. ORMatcher::ORMatcher() {}
  157. ORMatcher::ORMatcher(Matcher * const matcher1) {
  158. OR(matcher1);
  159. }
  160. ORMatcher::ORMatcher(Matcher * const matcher1, Matcher * const matcher2) {
  161. OR(matcher1).OR(matcher2);
  162. }
  163. ORMatcher::ORMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3) {
  164. OR(matcher1).OR(matcher2).OR(matcher3);
  165. }
  166. ORMatcher::ORMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3, Matcher * const matcher4) {
  167. OR(matcher1).OR(matcher2).OR(matcher3).OR(matcher4);
  168. }
  169. ORMatcher::ORMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3, Matcher * const matcher4, Matcher * const matcher5) {
  170. OR(matcher1).OR(matcher2).OR(matcher3).OR(matcher4).OR(matcher5);
  171. }
  172. ORMatcher& ORMatcher::OR(Matcher * const matcher) { matchers.push_back(matcher); return *this; }
  173. bool ORMatcher::operator() (pkgCache::PkgIterator const &Pkg) {
  174. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  175. if ((**M)(Pkg) == true)
  176. return true;
  177. return false;
  178. }
  179. bool ORMatcher::operator() (pkgCache::GrpIterator const &Grp) {
  180. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  181. if ((**M)(Grp) == true)
  182. return true;
  183. return false;
  184. }
  185. bool ORMatcher::operator() (pkgCache::VerIterator const &Ver) {
  186. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  187. if ((**M)(Ver) == true)
  188. return true;
  189. return false;
  190. }
  191. ORMatcher::~ORMatcher() {
  192. for (std::vector<Matcher *>::iterator M = matchers.begin(); M != matchers.end(); ++M)
  193. delete *M;
  194. }
  195. /*}}}*/
  196. }
  197. }