apt: apt-pkg/cachefilter-patterns.h Source File

apt 2.9.8 commandline package manager

cachefilter-patterns.h
1/*
2 * cachefilter-patterns.h - Pattern parser and additional patterns as matchers
3 *
4 * Copyright (c) 2019 Canonical Ltd
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9#ifndef APT_CACHEFILTER_PATTERNS_H
10#define APT_CACHEFILTER_PATTERNS_H
11#include <apt-pkg/cachefile.h>
12#include <apt-pkg/cachefilter.h>
13#include <apt-pkg/error.h>
14#include <apt-pkg/header-is-private.h>
15#include <apt-pkg/string_view.h>
16#include <apt-pkg/strutl.h>
17#include <cassert>
18#include <iostream>
19#include <memory>
20#include <sstream>
21#include <string>
22#include <vector>
23
24namespace APT
25{
26
27namespace Internal
28{
36 struct APT_PUBLIC PatternTreeParser
37{
38
39 struct Node
40 {
41 size_t start = 0;
42 size_t end = 0;
43
44 explicit Node(size_t start = 0, size_t end = 0) : start(start), end(end) {}
45
46 virtual std::ostream &render(std::ostream &os) { return os; };
47 std::nullptr_t error(std::string message);
48 virtual ~Node() = default;
49 };
50
51 struct Error : public std::exception
52 {
53 Node location;
54 std::string message;
55
56 Error(Node location, std::string message) : location(location), message(message) {}
57 const char *what() const throw() override { return message.c_str(); }
58 };
59
60 struct PatternNode : public Node
61 {
62 APT::StringView term;
63 std::vector<std::unique_ptr<Node>> arguments;
64 bool haveArgumentList = false;
65
66 APT_HIDDEN std::ostream &render(std::ostream &stream) override;
67 APT_HIDDEN bool matches(APT::StringView name, int min, int max);
68 };
69
70 struct WordNode : public Node
71 {
72 APT::StringView word;
73 bool quoted = false;
74 APT_HIDDEN std::ostream &render(std::ostream &stream) override;
75 };
76
77 struct State
78 {
79 size_t offset = 0;
80 };
81
82 APT::StringView sentence;
83 State state;
84
85 PatternTreeParser(APT::StringView sentence) : sentence(sentence){};
86 off_t skipSpace()
87 {
88 while (sentence[state.offset] == ' ' || sentence[state.offset] == '\t' || sentence[state.offset] == '\r' || sentence[state.offset] == '\n')
89 state.offset++;
90 return state.offset;
91 };
92
97 std::unique_ptr<Node> parseTop();
98 std::unique_ptr<Node> parse(); // public for test cases only
99
100 private:
101 APT_HIDDEN std::unique_ptr<Node> parseOr();
102 APT_HIDDEN std::unique_ptr<Node> parseAnd();
103 APT_HIDDEN std::unique_ptr<Node> parseUnary();
104 APT_HIDDEN std::unique_ptr<Node> parsePrimary();
105 APT_HIDDEN std::unique_ptr<Node> parseGroup();
106 APT_HIDDEN std::unique_ptr<Node> parsePattern();
107 APT_HIDDEN std::unique_ptr<Node> parseShortPattern();
108 APT_HIDDEN std::unique_ptr<Node> parseArgument(bool shrt);
109 APT_HIDDEN std::unique_ptr<Node> parseWord(bool shrt);
110 APT_HIDDEN std::unique_ptr<Node> parseQuotedWord();
111};
112
120 struct APT_HIDDEN PatternParser
121{
122 pkgCacheFile *file;
123
124 std::unique_ptr<APT::CacheFilter::Matcher> aPattern(std::unique_ptr<PatternTreeParser::Node> &nodeP);
125 std::string aWord(std::unique_ptr<PatternTreeParser::Node> &nodeP);
126};
127
128namespace Patterns
129{
130using namespace APT::CacheFilter;
131
133 class BaseRegexMatcher
134{
135 regex_t *pattern;
136
137 public:
138 BaseRegexMatcher(std::string const &string);
139 ~BaseRegexMatcher();
140 bool operator()(const char *cstring);
141 bool operator()(std::string const &string)
142 {
143 return (*this)(string.c_str());
144 }
145};
146
147 struct APT_HIDDEN PackageIsAutomatic : public PackageMatcher
148{
149 pkgCacheFile *Cache;
150 explicit PackageIsAutomatic(pkgCacheFile *Cache) : Cache(Cache) {}
151 bool operator()(pkgCache::PkgIterator const &Pkg) override
152 {
153 assert(Cache != nullptr);
154 return ((*Cache)[Pkg].Flags & pkgCache::Flag::Auto) != 0;
155 }
156};
157
158 struct APT_HIDDEN PackageIsBroken : public PackageMatcher
159{
160 pkgCacheFile *Cache;
161 explicit PackageIsBroken(pkgCacheFile *Cache) : Cache(Cache) {}
162 bool operator()(pkgCache::PkgIterator const &Pkg) override
163 {
164 assert(Cache != nullptr);
165 auto state = (*Cache)[Pkg];
166 return state.InstBroken() || state.NowBroken();
167 }
168};
169
170 struct APT_HIDDEN PackageIsConfigFiles : public PackageMatcher
171{
172 bool operator()(pkgCache::PkgIterator const &Pkg) override
173 {
174 return Pkg->CurrentState == pkgCache::State::ConfigFiles;
175 }
176};
177
178 struct APT_HIDDEN PackageIsGarbage : public PackageMatcher
179{
180 pkgCacheFile *Cache;
181 explicit PackageIsGarbage(pkgCacheFile *Cache) : Cache(Cache) {}
182 bool operator()(pkgCache::PkgIterator const &Pkg) override
183 {
184 assert(Cache != nullptr);
185 return (*Cache)[Pkg].Garbage;
186 }
187};
188 struct APT_HIDDEN PackageIsEssential : public PackageMatcher
189{
190 bool operator()(pkgCache::PkgIterator const &Pkg) override
191 {
192 return (Pkg->Flags & pkgCache::Flag::Essential) != 0;
193 }
194};
195
196 struct APT_HIDDEN PackageHasExactName : public PackageMatcher
197{
198 std::string name;
199 explicit PackageHasExactName(std::string name) : name(name) {}
200 bool operator()(pkgCache::PkgIterator const &Pkg) override
201 {
202 return Pkg.Name() == name;
203 }
204};
205
206 struct APT_HIDDEN PackageIsInstalled : public PackageMatcher
207{
208 pkgCacheFile *Cache;
209 explicit PackageIsInstalled(pkgCacheFile *Cache) : Cache(Cache) {}
210 bool operator()(pkgCache::PkgIterator const &Pkg) override
211 {
212 assert(Cache != nullptr);
213 return Pkg->CurrentVer != 0;
214 }
215 bool operator()(pkgCache::VerIterator const &Ver) override
216 {
217 assert(Cache != nullptr);
218 return Ver == Ver.ParentPkg().CurrentVer();
219 }
220};
221
222 struct APT_HIDDEN PackageIsObsolete : public PackageMatcher
223{
224 bool operator()(pkgCache::PkgIterator const &pkg) override
225 {
226 // This code can be written without loops, as aptitude does, but it
227 // is far less readable.
228 if (pkg.CurrentVer().end())
229 return false;
230
231 // See if there is any version that exists in a repository,
232 // if so return false
233 for (auto ver = pkg.VersionList(); !ver.end(); ver++)
234 {
235 for (auto file = ver.FileList(); !file.end(); file++)
236 {
237 if ((file.File()->Flags & pkgCache::Flag::NotSource) == 0)
238 return false;
239 }
240 }
241
242 return true;
243 }
244};
245
246 struct APT_HIDDEN PackageIsPhasing : public PackageMatcher
247{
248 pkgCacheFile *Cache;
249 explicit PackageIsPhasing(pkgCacheFile *Cache) : Cache(Cache) {}
250 bool operator()(pkgCache::PkgIterator const &pkg) override
251 {
252 return (*Cache)->PhasingApplied(pkg);
253 }
254};
255
256 struct APT_HIDDEN PackageIsUpgradable : public PackageMatcher
257{
258 pkgCacheFile *Cache;
259 explicit PackageIsUpgradable(pkgCacheFile *Cache) : Cache(Cache) {}
260 bool operator()(pkgCache::PkgIterator const &Pkg) override
261 {
262 assert(Cache != nullptr);
263 return Pkg->CurrentVer != 0 && (*Cache)[Pkg].Upgradable();
264 }
265};
266
267 struct APT_HIDDEN PackageIsVirtual : public PackageMatcher
268{
269 bool operator()(pkgCache::PkgIterator const &Pkg) override
270 {
271 return Pkg->VersionList == 0;
272 }
273};
274
275 struct APT_HIDDEN VersionAnyMatcher : public Matcher
276{
277 bool operator()(pkgCache::GrpIterator const &) override { return false; }
278 bool operator()(pkgCache::VerIterator const &Ver) override = 0;
279 bool operator()(pkgCache::PkgIterator const &Pkg) override
280 {
281 for (auto Ver = Pkg.VersionList(); not Ver.end(); Ver++)
282 {
283 if ((*this)(Ver))
284 return true;
285 }
286 return false;
287 }
288};
289
290 struct APT_HIDDEN VersionIsAllVersions : public Matcher
291{
292 std::unique_ptr<APT::CacheFilter::Matcher> base;
293 VersionIsAllVersions(std::unique_ptr<APT::CacheFilter::Matcher> base) : base(std::move(base)) {}
294 bool operator()(pkgCache::GrpIterator const &) override { return false; }
295 bool operator()(pkgCache::VerIterator const &Ver) override
296 {
297 return (*base)(Ver);
298 }
299 bool operator()(pkgCache::PkgIterator const &Pkg) override
300 {
301 for (auto Ver = Pkg.VersionList(); not Ver.end(); Ver++)
302 {
303 if (not(*this)(Ver))
304 return false;
305 }
306 return true;
307 }
308};
309
310 struct APT_HIDDEN VersionDepends : public VersionAnyMatcher
311{
312 std::unique_ptr<APT::CacheFilter::Matcher> base;
313 pkgCache::Dep::DepType type;
314 VersionDepends(std::unique_ptr<APT::CacheFilter::Matcher> base, pkgCache::Dep::DepType type = pkgCache::Dep::Depends) : base(std::move(base)), type(type) {}
315 bool operator()(pkgCache::GrpIterator const &) override { return false; }
316 bool operator()(pkgCache::VerIterator const &Ver) override
317 {
318 for (auto D = Ver.DependsList(); not D.end(); D++)
319 {
320 if (D.IsImplicit())
321 continue;
322 if (D->Type != type)
323 continue;
324 if ((*base)(D.TargetPkg()))
325 return true;
326 }
327
328 return false;
329 }
330};
331
332 struct APT_HIDDEN PackageReverseDepends : public PackageMatcher
333{
334 std::unique_ptr<APT::CacheFilter::Matcher> base;
335 pkgCache::Dep::DepType type;
336 PackageReverseDepends(std::unique_ptr<APT::CacheFilter::Matcher> base, pkgCache::Dep::DepType type = pkgCache::Dep::Depends) : base(std::move(base)), type(type) {}
337 bool operator()(pkgCache::PkgIterator const &Pkg) override
338 {
339 for (auto D = Pkg.RevDependsList(); not D.end(); D++)
340 {
341 if (D.IsImplicit())
342 continue;
343 if (D->Type != type)
344 continue;
345 if ((*base)(D.ParentVer()))
346 return true;
347 }
348
349 return false;
350 }
351};
352
353 struct APT_HIDDEN VersionIsAnyVersion : public VersionAnyMatcher
354{
355 std::unique_ptr<APT::CacheFilter::Matcher> base;
356 VersionIsAnyVersion(std::unique_ptr<APT::CacheFilter::Matcher> base) : base(std::move(base)) {}
357 bool operator()(pkgCache::VerIterator const &Ver) override
358 {
359 return (*base)(Ver);
360 }
361};
362
363 struct APT_HIDDEN VersionIsArchive : public VersionAnyMatcher
364{
365 BaseRegexMatcher matcher;
366 VersionIsArchive(std::string const &pattern) : matcher(pattern) {}
367 bool operator()(pkgCache::VerIterator const &Ver) override
368 {
369 for (auto VF = Ver.FileList(); not VF.end(); VF++)
370 {
371 if (VF.File().Archive() && matcher(VF.File().Archive()))
372 return true;
373 }
374 return false;
375 }
376};
377
378 struct APT_HIDDEN VersionIsCodename : public VersionAnyMatcher
379{
380 BaseRegexMatcher matcher;
381 VersionIsCodename(std::string const &pattern) : matcher(pattern) {}
382 bool operator()(pkgCache::VerIterator const &Ver) override
383 {
384 for (auto VF = Ver.FileList(); not VF.end(); VF++)
385 {
386 if (VF.File().Codename() && matcher(VF.File().Codename()))
387 return true;
388 }
389 return false;
390 }
391};
392
393 struct APT_HIDDEN VersionIsOrigin : public VersionAnyMatcher
394{
395 BaseRegexMatcher matcher;
396 VersionIsOrigin(std::string const &pattern) : matcher(pattern) {}
397 bool operator()(pkgCache::VerIterator const &Ver) override
398 {
399 for (auto VF = Ver.FileList(); not VF.end(); VF++)
400 {
401 if (VF.File().Origin() && matcher(VF.File().Origin()))
402 return true;
403 }
404 return false;
405 }
406};
407
408 struct APT_HIDDEN VersionIsSection : public VersionAnyMatcher
409{
410 BaseRegexMatcher matcher;
411 VersionIsSection(std::string const &pattern) : matcher(pattern) {}
412 bool operator()(pkgCache::VerIterator const &Ver) override
413 {
414 return matcher(Ver.Section());
415 }
416};
417
418 struct APT_HIDDEN VersionIsSecurity : public VersionAnyMatcher
419{
420 VersionIsSecurity() {}
421 bool operator()(pkgCache::VerIterator const &Ver) override
422 {
423 return Ver.IsSecurityUpdate();
424 }
425};
426
427 struct APT_HIDDEN VersionIsSourcePackage : public VersionAnyMatcher
428{
429 BaseRegexMatcher matcher;
430 VersionIsSourcePackage(std::string const &pattern) : matcher(pattern) {}
431 bool operator()(pkgCache::VerIterator const &Ver) override
432 {
433 return matcher(Ver.SourcePkgName());
434 }
435};
436
437 struct APT_HIDDEN VersionIsSourceVersion : public VersionAnyMatcher
438{
439 BaseRegexMatcher matcher;
440 VersionIsSourceVersion(std::string const &pattern) : matcher(pattern) {}
441 bool operator()(pkgCache::VerIterator const &Ver) override
442 {
443 return matcher(Ver.SourceVerStr());
444 }
445};
446
447 struct APT_HIDDEN VersionIsVersion : public VersionAnyMatcher
448{
449 BaseRegexMatcher matcher;
450 VersionIsVersion(std::string const &pattern) : matcher(pattern) {}
451 bool operator()(pkgCache::VerIterator const &Ver) override
452 {
453 return matcher(Ver.VerStr());
454 }
455};
456
457 struct APT_HIDDEN VersionIsPriority : public VersionAnyMatcher
458{
459 std::string name;
460 explicit VersionIsPriority(std::string name) : name(name) {}
461 bool operator()(pkgCache::VerIterator const &Ver) override
462 {
463 std::string Mapping[] = {"", "required","important","standard",
464 "optional","extra"};
465 if (Ver->Priority > 0 && Ver->Priority < APT_ARRAY_SIZE(Mapping)) {
466 return name == Mapping[Ver->Priority];
467 }
468 return false;
469 }
470};
471
472} // namespace Patterns
473} // namespace Internal
474} // namespace APT
475#endif
cachefilter.h
APT::CacheFilter::Matcher
Definition cachefilter.h:23
APT::CacheFilter::PackageMatcher
Definition cachefilter.h:31
APT::Internal::Patterns::BaseRegexMatcher
Basic helper class for matching regex.
Definition cachefilter-patterns.h:134
APT::StringView
Simple subset of std::string_view from C++17.
Definition string_view.h:27
pkgCacheFile
Definition cachefile.h:33
APT::Internal::PatternParser
PatternParser parses the given sentence into a parse tree.
Definition cachefilter-patterns.h:121
APT::Internal::PatternTreeParser::Error
Definition cachefilter-patterns.h:52
APT::Internal::PatternTreeParser::Node
Definition cachefilter-patterns.h:40
APT::Internal::PatternTreeParser::PatternNode
Definition cachefilter-patterns.h:61
APT::Internal::PatternTreeParser::State
Definition cachefilter-patterns.h:78
APT::Internal::PatternTreeParser::WordNode
Definition cachefilter-patterns.h:71
APT::Internal::PatternTreeParser
PatternTreeParser parses the given sentence into a parse tree.
Definition cachefilter-patterns.h:37
APT::Internal::Patterns::PackageHasExactName
Definition cachefilter-patterns.h:197
APT::Internal::Patterns::PackageIsAutomatic
Definition cachefilter-patterns.h:148
APT::Internal::Patterns::PackageIsBroken
Definition cachefilter-patterns.h:159
APT::Internal::Patterns::PackageIsConfigFiles
Definition cachefilter-patterns.h:171
APT::Internal::Patterns::PackageIsEssential
Definition cachefilter-patterns.h:189
APT::Internal::Patterns::PackageIsGarbage
Definition cachefilter-patterns.h:179
APT::Internal::Patterns::PackageIsInstalled
Definition cachefilter-patterns.h:207
APT::Internal::Patterns::PackageIsObsolete
Definition cachefilter-patterns.h:223
APT::Internal::Patterns::PackageIsPhasing
Definition cachefilter-patterns.h:247
APT::Internal::Patterns::PackageIsUpgradable
Definition cachefilter-patterns.h:257
APT::Internal::Patterns::PackageIsVirtual
Definition cachefilter-patterns.h:268
APT::Internal::Patterns::PackageReverseDepends
Definition cachefilter-patterns.h:333
APT::Internal::Patterns::VersionAnyMatcher
Definition cachefilter-patterns.h:276
APT::Internal::Patterns::VersionDepends
Definition cachefilter-patterns.h:311
APT::Internal::Patterns::VersionIsAllVersions
Definition cachefilter-patterns.h:291
APT::Internal::Patterns::VersionIsAnyVersion
Definition cachefilter-patterns.h:354
APT::Internal::Patterns::VersionIsArchive
Definition cachefilter-patterns.h:364
APT::Internal::Patterns::VersionIsCodename
Definition cachefilter-patterns.h:379
APT::Internal::Patterns::VersionIsOrigin
Definition cachefilter-patterns.h:394
APT::Internal::Patterns::VersionIsPriority
Definition cachefilter-patterns.h:458
APT::Internal::Patterns::VersionIsSection
Definition cachefilter-patterns.h:409
APT::Internal::Patterns::VersionIsSecurity
Definition cachefilter-patterns.h:419
APT::Internal::Patterns::VersionIsSourcePackage
Definition cachefilter-patterns.h:428
APT::Internal::Patterns::VersionIsSourceVersion
Definition cachefilter-patterns.h:438
APT::Internal::Patterns::VersionIsVersion
Definition cachefilter-patterns.h:448
pkgCache::Flag::NotSource
@ NotSource
Definition pkgcache.h:197