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

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