From 8d4967d3a187dd66cf14b070a9db63f8ea21b21f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 28 Jan 2020 21:46:10 +0100 Subject: patterns: Implement unary ! --- apt-pkg/cachefilter-patterns.cc | 28 +++++++++++++++++++++++++++- apt-pkg/cachefilter-patterns.h | 2 ++ doc/apt-patterns.7.xml | 2 +- test/libapt/pattern_test.cc | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/apt-pkg/cachefilter-patterns.cc b/apt-pkg/cachefilter-patterns.cc index 11ad5d723..9fab0281d 100644 --- a/apt-pkg/cachefilter-patterns.cc +++ b/apt-pkg/cachefilter-patterns.cc @@ -66,6 +66,32 @@ std::unique_ptr PatternTreeParser::parseTop() // Parse any pattern std::unique_ptr PatternTreeParser::parse() +{ + return parseUnary(); +} + +std::unique_ptr PatternTreeParser::parseUnary() +{ + + if (sentence[state.offset] != '!') + return parsePrimary(); + + auto start = ++state.offset; + auto primary = parsePrimary(); + + if (primary == nullptr) + throw Error{Node{start, sentence.size()}, "Expected pattern"}; + + auto node = std::make_unique(); + node->start = start; + node->end = primary->end; + node->term = "?not"; + node->arguments.push_back(std::move(primary)); + node->haveArgumentList = true; + return node; +} + +std::unique_ptr PatternTreeParser::parsePrimary() { std::unique_ptr node; if ((node = parseShortPattern()) != nullptr) @@ -198,7 +224,7 @@ std::unique_ptr PatternTreeParser::parseQuotedWord() // Parse a bare word atom std::unique_ptr PatternTreeParser::parseWord() { - static const constexpr auto DISALLOWED_START = "?~,()\0"_sv; + static const constexpr auto DISALLOWED_START = "!?~,()\0"_sv; static const constexpr auto DISALLOWED = ",()\0"_sv; if (DISALLOWED_START.find(sentence[state.offset]) != APT::StringView::npos) return nullptr; diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h index 0d6e9d99e..76318eafa 100644 --- a/apt-pkg/cachefilter-patterns.h +++ b/apt-pkg/cachefilter-patterns.h @@ -95,6 +95,8 @@ struct PatternTreeParser private: std::unique_ptr parse(); + std::unique_ptr parseUnary(); + std::unique_ptr parsePrimary(); std::unique_ptr parsePattern(); std::unique_ptr parseShortPattern(); std::unique_ptr parseWord(); diff --git a/doc/apt-patterns.7.xml b/doc/apt-patterns.7.xml index f18fe6a19..72f1ccbce 100644 --- a/doc/apt-patterns.7.xml +++ b/doc/apt-patterns.7.xml @@ -49,7 +49,7 @@ ?false~F Selects nothing. - ?not(PATTERN) + ?not(PATTERN)!PATTERN Selects objects where PATTERN does not match. ?or(PATTERN, PATTERN, ...) diff --git a/test/libapt/pattern_test.cc b/test/libapt/pattern_test.cc index 492a29eac..39959cd31 100644 --- a/test/libapt/pattern_test.cc +++ b/test/libapt/pattern_test.cc @@ -158,4 +158,5 @@ TEST(TreeParserTest, ParseShortPattern) EXPECT_PATTERN_EQ_ATOMIC("~U", "?upgradable"); EXPECT_PATTERN_EQ("~Vverstr", "?version(verstr)"); EXPECT_PATTERN_EQ_ATOMIC("~v", "?virtual"); + EXPECT_PATTERN_EQ("!foo", "?not(foo)"); } -- cgit v1.2.3-70-g09d2