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