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