cachefilter.cc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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 <libc>-<kernel>-<cpu> specification /*{{{*/
  67. //----------------------------------------------------------------------
  68. /* The complete architecture, consisting of <libc>-<kernel>-<cpu>. */
  69. static std::string CompleteArch(std::string const &arch, bool const isPattern) {
  70. auto const found = arch.find('-');
  71. if (found != std::string::npos)
  72. {
  73. // ensure that only -any- is replaced and not something like company-
  74. std::string complete = std::string("-").append(arch).append("-");
  75. size_t pos = 0;
  76. char const * const search = "-any-";
  77. auto const search_len = strlen(search) - 2;
  78. while((pos = complete.find(search, pos)) != std::string::npos) {
  79. complete.replace(pos + 1, search_len, "*");
  80. pos += 2;
  81. }
  82. complete = complete.substr(1, complete.size()-2);
  83. if (arch.find('-', found+1) != std::string::npos)
  84. // <libc>-<kernel>-<cpu> format
  85. return complete;
  86. // <kernel>-<cpu> format
  87. else if (isPattern)
  88. return "*-" + complete;
  89. else
  90. return "gnu-" + complete;
  91. }
  92. else if (arch == "any")
  93. return "*-*-*";
  94. else if (isPattern)
  95. return "*-linux-" + arch;
  96. else
  97. return "gnu-linux-" + arch;
  98. }
  99. PackageArchitectureMatchesSpecification::PackageArchitectureMatchesSpecification(std::string const &pattern, bool const pisPattern) :
  100. literal(pattern), complete(CompleteArch(pattern, pisPattern)), isPattern(pisPattern) {
  101. }
  102. bool PackageArchitectureMatchesSpecification::operator() (char const * const &arch) {
  103. if (strcmp(literal.c_str(), arch) == 0 ||
  104. strcmp(complete.c_str(), arch) == 0)
  105. return true;
  106. std::string const pkgarch = CompleteArch(arch, !isPattern);
  107. if (isPattern == true)
  108. return fnmatch(complete.c_str(), pkgarch.c_str(), 0) == 0;
  109. return fnmatch(pkgarch.c_str(), complete.c_str(), 0) == 0;
  110. }
  111. bool PackageArchitectureMatchesSpecification::operator() (pkgCache::PkgIterator const &Pkg) {
  112. return (*this)(Pkg.Arch());
  113. }
  114. PackageArchitectureMatchesSpecification::~PackageArchitectureMatchesSpecification() {
  115. }
  116. /*}}}*/
  117. // Package is new install /*{{{*/
  118. PackageIsNewInstall::PackageIsNewInstall(pkgCacheFile * const Cache) : Cache(Cache) {}
  119. APT_PURE bool PackageIsNewInstall::operator() (pkgCache::PkgIterator const &Pkg) {
  120. return (*Cache)[Pkg].NewInstall();
  121. }
  122. PackageIsNewInstall::~PackageIsNewInstall() {}
  123. /*}}}*/
  124. // Generica like True, False, NOT, AND, OR /*{{{*/
  125. APT_CONST bool TrueMatcher::operator() (pkgCache::PkgIterator const &) { return true; }
  126. APT_CONST bool TrueMatcher::operator() (pkgCache::GrpIterator const &) { return true; }
  127. APT_CONST bool TrueMatcher::operator() (pkgCache::VerIterator const &) { return true; }
  128. APT_CONST bool FalseMatcher::operator() (pkgCache::PkgIterator const &) { return false; }
  129. APT_CONST bool FalseMatcher::operator() (pkgCache::GrpIterator const &) { return false; }
  130. APT_CONST bool FalseMatcher::operator() (pkgCache::VerIterator const &) { return false; }
  131. NOTMatcher::NOTMatcher(Matcher * const matcher) : matcher(matcher) {}
  132. bool NOTMatcher::operator() (pkgCache::PkgIterator const &Pkg) { return ! (*matcher)(Pkg); }
  133. bool NOTMatcher::operator() (pkgCache::GrpIterator const &Grp) { return ! (*matcher)(Grp); }
  134. bool NOTMatcher::operator() (pkgCache::VerIterator const &Ver) { return ! (*matcher)(Ver); }
  135. NOTMatcher::~NOTMatcher() { delete matcher; }
  136. ANDMatcher::ANDMatcher() {}
  137. ANDMatcher::ANDMatcher(Matcher * const matcher1) {
  138. AND(matcher1);
  139. }
  140. ANDMatcher::ANDMatcher(Matcher * const matcher1, Matcher * const matcher2) {
  141. AND(matcher1).AND(matcher2);
  142. }
  143. ANDMatcher::ANDMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3) {
  144. AND(matcher1).AND(matcher2).AND(matcher3);
  145. }
  146. ANDMatcher::ANDMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3, Matcher * const matcher4) {
  147. AND(matcher1).AND(matcher2).AND(matcher3).AND(matcher4);
  148. }
  149. ANDMatcher::ANDMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3, Matcher * const matcher4, Matcher * const matcher5) {
  150. AND(matcher1).AND(matcher2).AND(matcher3).AND(matcher4).AND(matcher5);
  151. }
  152. ANDMatcher& ANDMatcher::AND(Matcher * const matcher) { matchers.push_back(matcher); return *this; }
  153. bool ANDMatcher::operator() (pkgCache::PkgIterator const &Pkg) {
  154. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  155. if ((**M)(Pkg) == false)
  156. return false;
  157. return true;
  158. }
  159. bool ANDMatcher::operator() (pkgCache::GrpIterator const &Grp) {
  160. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  161. if ((**M)(Grp) == false)
  162. return false;
  163. return true;
  164. }
  165. bool ANDMatcher::operator() (pkgCache::VerIterator const &Ver) {
  166. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  167. if ((**M)(Ver) == false)
  168. return false;
  169. return true;
  170. }
  171. ANDMatcher::~ANDMatcher() {
  172. for (std::vector<Matcher *>::iterator M = matchers.begin(); M != matchers.end(); ++M)
  173. delete *M;
  174. }
  175. ORMatcher::ORMatcher() {}
  176. ORMatcher::ORMatcher(Matcher * const matcher1) {
  177. OR(matcher1);
  178. }
  179. ORMatcher::ORMatcher(Matcher * const matcher1, Matcher * const matcher2) {
  180. OR(matcher1).OR(matcher2);
  181. }
  182. ORMatcher::ORMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3) {
  183. OR(matcher1).OR(matcher2).OR(matcher3);
  184. }
  185. ORMatcher::ORMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3, Matcher * const matcher4) {
  186. OR(matcher1).OR(matcher2).OR(matcher3).OR(matcher4);
  187. }
  188. ORMatcher::ORMatcher(Matcher * const matcher1, Matcher * const matcher2, Matcher * const matcher3, Matcher * const matcher4, Matcher * const matcher5) {
  189. OR(matcher1).OR(matcher2).OR(matcher3).OR(matcher4).OR(matcher5);
  190. }
  191. ORMatcher& ORMatcher::OR(Matcher * const matcher) { matchers.push_back(matcher); return *this; }
  192. bool ORMatcher::operator() (pkgCache::PkgIterator const &Pkg) {
  193. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  194. if ((**M)(Pkg) == true)
  195. return true;
  196. return false;
  197. }
  198. bool ORMatcher::operator() (pkgCache::GrpIterator const &Grp) {
  199. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  200. if ((**M)(Grp) == true)
  201. return true;
  202. return false;
  203. }
  204. bool ORMatcher::operator() (pkgCache::VerIterator const &Ver) {
  205. for (std::vector<Matcher *>::const_iterator M = matchers.begin(); M != matchers.end(); ++M)
  206. if ((**M)(Ver) == true)
  207. return true;
  208. return false;
  209. }
  210. ORMatcher::~ORMatcher() {
  211. for (std::vector<Matcher *>::iterator M = matchers.begin(); M != matchers.end(); ++M)
  212. delete *M;
  213. }
  214. /*}}}*/
  215. }
  216. }