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

apt 2.7.5 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 <iostream>
18#include <memory>
19#include <sstream>
20#include <string>
21#include <vector>
22#include <assert.h>
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 PackageIsUpgradable : public PackageMatcher
247{
248 pkgCacheFile *Cache;
249 explicit PackageIsUpgradable(pkgCacheFile *Cache) : Cache(Cache) {}
250 bool operator()(pkgCache::PkgIterator const &Pkg) override
251 {
252 assert(Cache != nullptr);
253 return Pkg->CurrentVer != 0 && (*Cache)[Pkg].Upgradable();
254 }
255};
256
257 struct APT_HIDDEN PackageIsVirtual : public PackageMatcher
258{
259 bool operator()(pkgCache::PkgIterator const &Pkg) override
260 {
261 return Pkg->VersionList == 0;
262 }
263};
264
265 struct APT_HIDDEN VersionAnyMatcher : public Matcher
266{
267 bool operator()(pkgCache::GrpIterator const &) override { return false; }
268 bool operator()(pkgCache::VerIterator const &Ver) override = 0;
269 bool operator()(pkgCache::PkgIterator const &Pkg) override
270 {
271 for (auto Ver = Pkg.VersionList(); not Ver.end(); Ver++)
272 {
273 if ((*this)(Ver))
274 return true;
275 }
276 return false;
277 }
278};
279
280 struct APT_HIDDEN VersionIsAllVersions : public Matcher
281{
282 std::unique_ptr<APT::CacheFilter::Matcher> base;
283 VersionIsAllVersions(std::unique_ptr<APT::CacheFilter::Matcher> base) : base(std::move(base)) {}
284 bool operator()(pkgCache::GrpIterator const &) override { return false; }
285 bool operator()(pkgCache::VerIterator const &Ver) override
286 {
287 return (*base)(Ver);
288 }
289 bool operator()(pkgCache::PkgIterator const &Pkg) override
290 {
291 for (auto Ver = Pkg.VersionList(); not Ver.end(); Ver++)
292 {
293 if (not(*this)(Ver))
294 return false;
295 }
296 return true;
297 }
298};
299
300 struct APT_HIDDEN VersionDepends : public VersionAnyMatcher
301{
302 std::unique_ptr<APT::CacheFilter::Matcher> base;
303 pkgCache::Dep::DepType type;
304 VersionDepends(std::unique_ptr<APT::CacheFilter::Matcher> base, pkgCache::Dep::DepType type = pkgCache::Dep::Depends) : base(std::move(base)), type(type) {}
305 bool operator()(pkgCache::GrpIterator const &) override { return false; }
306 bool operator()(pkgCache::VerIterator const &Ver) override
307 {
308 for (auto D = Ver.DependsList(); not D.end(); D++)
309 {
310 if (D.IsImplicit())
311 continue;
312 if (D->Type != type)
313 continue;
314 if ((*base)(D.TargetPkg()))
315 return true;
316 }
317
318 return false;
319 }
320};
321
322 struct APT_HIDDEN PackageReverseDepends : public PackageMatcher
323{
324 std::unique_ptr<APT::CacheFilter::Matcher> base;
325 pkgCache::Dep::DepType type;
326 PackageReverseDepends(std::unique_ptr<APT::CacheFilter::Matcher> base, pkgCache::Dep::DepType type = pkgCache::Dep::Depends) : base(std::move(base)), type(type) {}
327 bool operator()(pkgCache::PkgIterator const &Pkg) override
328 {
329 for (auto D = Pkg.RevDependsList(); not D.end(); D++)
330 {
331 if (D.IsImplicit())
332 continue;
333 if (D->Type != type)
334 continue;
335 if ((*base)(D.ParentVer()))
336 return true;
337 }
338
339 return false;
340 }
341};
342
343 struct APT_HIDDEN VersionIsAnyVersion : public VersionAnyMatcher
344{
345 std::unique_ptr<APT::CacheFilter::Matcher> base;
346 VersionIsAnyVersion(std::unique_ptr<APT::CacheFilter::Matcher> base) : base(std::move(base)) {}
347 bool operator()(pkgCache::VerIterator const &Ver) override
348 {
349 return (*base)(Ver);
350 }
351};
352
353 struct APT_HIDDEN VersionIsArchive : public VersionAnyMatcher
354{
355 BaseRegexMatcher matcher;
356 VersionIsArchive(std::string const &pattern) : matcher(pattern) {}
357 bool operator()(pkgCache::VerIterator const &Ver) override
358 {
359 for (auto VF = Ver.FileList(); not VF.end(); VF++)
360 {
361 if (VF.File().Archive() && matcher(VF.File().Archive()))
362 return true;
363 }
364 return false;
365 }
366};
367
368 struct APT_HIDDEN VersionIsCodename : public VersionAnyMatcher
369{
370 BaseRegexMatcher matcher;
371 VersionIsCodename(std::string const &pattern) : matcher(pattern) {}
372 bool operator()(pkgCache::VerIterator const &Ver) override
373 {
374 for (auto VF = Ver.FileList(); not VF.end(); VF++)
375 {
376 if (VF.File().Codename() && matcher(VF.File().Codename()))
377 return true;
378 }
379 return false;
380 }
381};
382
383 struct APT_HIDDEN VersionIsOrigin : public VersionAnyMatcher
384{
385 BaseRegexMatcher matcher;
386 VersionIsOrigin(std::string const &pattern) : matcher(pattern) {}
387 bool operator()(pkgCache::VerIterator const &Ver) override
388 {
389 for (auto VF = Ver.FileList(); not VF.end(); VF++)
390 {
391 if (VF.File().Origin() && matcher(VF.File().Origin()))
392 return true;
393 }
394 return false;
395 }
396};
397
398 struct APT_HIDDEN VersionIsSection : public VersionAnyMatcher
399{
400 BaseRegexMatcher matcher;
401 VersionIsSection(std::string const &pattern) : matcher(pattern) {}
402 bool operator()(pkgCache::VerIterator const &Ver) override
403 {
404 return matcher(Ver.Section());
405 }
406};
407
408 struct APT_HIDDEN VersionIsSourcePackage : public VersionAnyMatcher
409{
410 BaseRegexMatcher matcher;
411 VersionIsSourcePackage(std::string const &pattern) : matcher(pattern) {}
412 bool operator()(pkgCache::VerIterator const &Ver) override
413 {
414 return matcher(Ver.SourcePkgName());
415 }
416};
417
418 struct APT_HIDDEN VersionIsSourceVersion : public VersionAnyMatcher
419{
420 BaseRegexMatcher matcher;
421 VersionIsSourceVersion(std::string const &pattern) : matcher(pattern) {}
422 bool operator()(pkgCache::VerIterator const &Ver) override
423 {
424 return matcher(Ver.SourceVerStr());
425 }
426};
427
428 struct APT_HIDDEN VersionIsVersion : public VersionAnyMatcher
429{
430 BaseRegexMatcher matcher;
431 VersionIsVersion(std::string const &pattern) : matcher(pattern) {}
432 bool operator()(pkgCache::VerIterator const &Ver) override
433 {
434 return matcher(Ver.VerStr());
435 }
436};
437
438 struct APT_HIDDEN VersionIsPriority : public VersionAnyMatcher
439{
440 std::string name;
441 explicit VersionIsPriority(std::string name) : name(name) {}
442 bool operator()(pkgCache::VerIterator const &Ver) override
443 {
444 std::string Mapping[] = {"", "required","important","standard",
445 "optional","extra"};
446 if (Ver->Priority > 0 && Ver->Priority < APT_ARRAY_SIZE(Mapping)) {
447 return name == Mapping[Ver->Priority];
448 }
449 return false;
450 }
451};
452
453} // namespace Patterns
454} // namespace Internal
455} // namespace APT
456#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::PackageIsUpgradable
Definition cachefilter-patterns.h:247
APT::Internal::Patterns::PackageIsVirtual
Definition cachefilter-patterns.h:258
APT::Internal::Patterns::PackageReverseDepends
Definition cachefilter-patterns.h:323
APT::Internal::Patterns::VersionAnyMatcher
Definition cachefilter-patterns.h:266
APT::Internal::Patterns::VersionDepends
Definition cachefilter-patterns.h:301
APT::Internal::Patterns::VersionIsAllVersions
Definition cachefilter-patterns.h:281
APT::Internal::Patterns::VersionIsAnyVersion
Definition cachefilter-patterns.h:344
APT::Internal::Patterns::VersionIsArchive
Definition cachefilter-patterns.h:354
APT::Internal::Patterns::VersionIsCodename
Definition cachefilter-patterns.h:369
APT::Internal::Patterns::VersionIsOrigin
Definition cachefilter-patterns.h:384
APT::Internal::Patterns::VersionIsPriority
Definition cachefilter-patterns.h:439
APT::Internal::Patterns::VersionIsSection
Definition cachefilter-patterns.h:399
APT::Internal::Patterns::VersionIsSourcePackage
Definition cachefilter-patterns.h:409
APT::Internal::Patterns::VersionIsSourceVersion
Definition cachefilter-patterns.h:419
APT::Internal::Patterns::VersionIsVersion
Definition cachefilter-patterns.h:429
pkgCache::Flag::NotSource
@ NotSource
Definition pkgcache.h:197