summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/cachefilter-patterns.cc56
-rw-r--r--apt-pkg/cachefilter-patterns.h130
2 files changed, 185 insertions, 1 deletions
diff --git a/apt-pkg/cachefilter-patterns.cc b/apt-pkg/cachefilter-patterns.cc
index bf6166ee4..a9f76ff1d 100644
--- a/apt-pkg/cachefilter-patterns.cc
+++ b/apt-pkg/cachefilter-patterns.cc
@@ -6,8 +6,12 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <config.h>
+
#include <apt-pkg/cachefilter-patterns.h>
+#include <apti18n.h>
+
namespace APT
{
namespace Internal
@@ -210,6 +214,12 @@ std::unique_ptr<APT::CacheFilter::Matcher> PatternParser::aPattern(std::unique_p
if (node->matches("?architecture", 1, 1))
return std::make_unique<APT::CacheFilter::PackageArchitectureMatchesSpecification>(aWord(node->arguments[0]));
+ if (node->matches("?archive", 1, 1))
+ return std::make_unique<Patterns::VersionIsArchive>(aWord(node->arguments[0]));
+ if (node->matches("?all-versions", 1, 1))
+ return std::make_unique<Patterns::VersionIsAllVersions>(aPattern(node->arguments[0]));
+ if (node->matches("?any-version", 1, 1))
+ return std::make_unique<Patterns::VersionIsAnyVersion>(aPattern(node->arguments[0]));
if (node->matches("?automatic", 0, 0))
return std::make_unique<Patterns::PackageIsAutomatic>(file);
if (node->matches("?broken", 0, 0))
@@ -232,21 +242,33 @@ std::unique_ptr<APT::CacheFilter::Matcher> PatternParser::aPattern(std::unique_p
return std::make_unique<APT::CacheFilter::NOTMatcher>(aPattern(node->arguments[0]).release());
if (node->matches("?obsolete", 0, 0))
return std::make_unique<Patterns::PackageIsObsolete>();
+ if (node->matches("?origin", 1, 1))
+ return std::make_unique<Patterns::VersionIsOrigin>(aWord(node->arguments[0]));
+ if (node->matches("?section", 1, 1))
+ return std::make_unique<Patterns::VersionIsSection>(aWord(node->arguments[0]));
+ if (node->matches("?source-package", 1, 1))
+ return std::make_unique<Patterns::VersionIsSourcePackage>(aWord(node->arguments[0]));
+ if (node->matches("?source-version", 1, 1))
+ return std::make_unique<Patterns::VersionIsSourceVersion>(aWord(node->arguments[0]));
if (node->matches("?true", 0, 0))
return std::make_unique<APT::CacheFilter::TrueMatcher>();
if (node->matches("?upgradable", 0, 0))
return std::make_unique<Patterns::PackageIsUpgradable>(file);
+ if (node->matches("?version", 1, 1))
+ return std::make_unique<Patterns::VersionIsVersion>(aWord(node->arguments[0]));
if (node->matches("?virtual", 0, 0))
return std::make_unique<Patterns::PackageIsVirtual>();
if (node->matches("?x-name-fnmatch", 1, 1))
return std::make_unique<APT::CacheFilter::PackageNameMatchesFnmatch>(aWord(node->arguments[0]));
// Variable argument patterns
- if (node->matches("?and", 0, -1))
+ if (node->matches("?and", 0, -1) || node->matches("?narrow", 0, -1))
{
auto pattern = std::make_unique<APT::CacheFilter::ANDMatcher>();
for (auto &arg : node->arguments)
pattern->AND(aPattern(arg).release());
+ if (node->term == "?narrow")
+ return std::make_unique<Patterns::VersionIsAnyVersion>(std::move(pattern));
return pattern;
}
if (node->matches("?or", 0, -1))
@@ -272,6 +294,38 @@ std::string PatternParser::aWord(std::unique_ptr<PatternTreeParser::Node> &nodeP
return node->word.to_string();
}
+namespace Patterns
+{
+
+BaseRegexMatcher::BaseRegexMatcher(std::string const &Pattern)
+{
+ pattern = new regex_t;
+ int const Res = regcomp(pattern, Pattern.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB);
+ if (Res == 0)
+ return;
+
+ delete pattern;
+ pattern = NULL;
+ char Error[300];
+ regerror(Res, pattern, Error, sizeof(Error));
+ _error->Error(_("Regex compilation error - %s"), Error);
+}
+bool BaseRegexMatcher::operator()(const char *string)
+{
+ if (unlikely(pattern == NULL))
+ return false;
+ else
+ return regexec(pattern, string, 0, 0, 0) == 0;
+}
+BaseRegexMatcher::~BaseRegexMatcher()
+{
+ if (pattern == NULL)
+ return;
+ regfree(pattern);
+ delete pattern;
+}
+} // namespace Patterns
+
} // namespace Internal
// The bridge into the public world
diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h
index d37da815f..bd8ce7e7e 100644
--- a/apt-pkg/cachefilter-patterns.h
+++ b/apt-pkg/cachefilter-patterns.h
@@ -117,6 +117,21 @@ namespace Patterns
{
using namespace APT::CacheFilter;
+/** \brief Basic helper class for matching regex */
+class BaseRegexMatcher
+{
+ regex_t *pattern;
+
+ public:
+ BaseRegexMatcher(std::string const &string);
+ ~BaseRegexMatcher();
+ bool operator()(const char *cstring);
+ bool operator()(std::string const &string)
+ {
+ return (*this)(string.c_str());
+ }
+};
+
struct PackageIsAutomatic : public PackageMatcher
{
pkgCacheFile *Cache;
@@ -229,6 +244,121 @@ struct PackageIsVirtual : public PackageMatcher
return Pkg->VersionList == 0;
}
};
+
+struct VersionAnyMatcher : public Matcher
+{
+ bool operator()(pkgCache::GrpIterator const &Grp) override { return false; }
+ bool operator()(pkgCache::VerIterator const &Ver) override = 0;
+ bool operator()(pkgCache::PkgIterator const &Pkg) override
+ {
+ for (auto Ver = Pkg.VersionList(); not Ver.end(); Ver++)
+ {
+ if ((*this)(Ver))
+ return true;
+ }
+ return false;
+ }
+};
+
+struct VersionIsAllVersions : public Matcher
+{
+ std::unique_ptr<APT::CacheFilter::Matcher> base;
+ VersionIsAllVersions(std::unique_ptr<APT::CacheFilter::Matcher> base) : base(std::move(base)) {}
+ bool operator()(pkgCache::GrpIterator const &) override { return false; }
+ bool operator()(pkgCache::VerIterator const &Ver) override
+ {
+ return (*base)(Ver);
+ }
+ bool operator()(pkgCache::PkgIterator const &Pkg) override
+ {
+ for (auto Ver = Pkg.VersionList(); not Ver.end(); Ver++)
+ {
+ if (not(*this)(Ver))
+ return false;
+ }
+ return true;
+ }
+};
+
+struct VersionIsAnyVersion : public VersionAnyMatcher
+{
+ std::unique_ptr<APT::CacheFilter::Matcher> base;
+ VersionIsAnyVersion(std::unique_ptr<APT::CacheFilter::Matcher> base) : base(std::move(base)) {}
+ bool operator()(pkgCache::VerIterator const &Ver) override
+ {
+ return (*base)(Ver);
+ }
+};
+
+struct VersionIsArchive : public VersionAnyMatcher
+{
+ BaseRegexMatcher matcher;
+ VersionIsArchive(std::string const &pattern) : matcher(pattern) {}
+ bool operator()(pkgCache::VerIterator const &Ver) override
+ {
+ for (auto VF = Ver.FileList(); not VF.end(); VF++)
+ {
+ if (VF.File().Archive() && matcher(VF.File().Archive()))
+ return true;
+ }
+ return false;
+ }
+};
+
+struct VersionIsOrigin : public VersionAnyMatcher
+{
+ BaseRegexMatcher matcher;
+ VersionIsOrigin(std::string const &pattern) : matcher(pattern) {}
+ bool operator()(pkgCache::VerIterator const &Ver) override
+ {
+ for (auto VF = Ver.FileList(); not VF.end(); VF++)
+ {
+ if (VF.File().Origin() && matcher(VF.File().Origin()))
+ return true;
+ }
+ return false;
+ }
+};
+
+struct VersionIsSection : public VersionAnyMatcher
+{
+ BaseRegexMatcher matcher;
+ VersionIsSection(std::string const &pattern) : matcher(pattern) {}
+ bool operator()(pkgCache::VerIterator const &Ver) override
+ {
+ return matcher(Ver.Section());
+ }
+};
+
+struct VersionIsSourcePackage : public VersionAnyMatcher
+{
+ BaseRegexMatcher matcher;
+ VersionIsSourcePackage(std::string const &pattern) : matcher(pattern) {}
+ bool operator()(pkgCache::VerIterator const &Ver) override
+ {
+ return matcher(Ver.SourcePkgName());
+ }
+};
+
+struct VersionIsSourceVersion : public VersionAnyMatcher
+{
+ BaseRegexMatcher matcher;
+ VersionIsSourceVersion(std::string const &pattern) : matcher(pattern) {}
+ bool operator()(pkgCache::VerIterator const &Ver) override
+ {
+ return matcher(Ver.SourceVerStr());
+ }
+};
+
+struct VersionIsVersion : public VersionAnyMatcher
+{
+ BaseRegexMatcher matcher;
+ VersionIsVersion(std::string const &pattern) : matcher(pattern) {}
+ bool operator()(pkgCache::VerIterator const &Ver) override
+ {
+ return matcher(Ver.VerStr());
+ }
+};
} // namespace Patterns
} // namespace Internal
} // namespace APT