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