diff options
-rw-r--r-- | apt-pkg/cachefilter-patterns.cc | 32 | ||||
-rw-r--r-- | apt-pkg/cachefilter-patterns.h | 1 | ||||
-rw-r--r-- | doc/apt-patterns.7.xml | 2 | ||||
-rw-r--r-- | test/libapt/pattern_test.cc | 8 |
4 files changed, 41 insertions, 2 deletions
diff --git a/apt-pkg/cachefilter-patterns.cc b/apt-pkg/cachefilter-patterns.cc index cf3e59ac6..dbf58e2a9 100644 --- a/apt-pkg/cachefilter-patterns.cc +++ b/apt-pkg/cachefilter-patterns.cc @@ -70,7 +70,37 @@ std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseTop() // Parse any pattern std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parse() { - return parseUnary(); + return parseAnd(); +} + +std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseAnd() +{ + auto start = state.offset; + std::vector<std::unique_ptr<PatternTreeParser::Node>> nodes; + + for (skipSpace(); state.offset < sentence.size(); skipSpace()) + { + auto node = parseUnary(); + + if (node == nullptr) + break; + + nodes.push_back(std::move(node)); + } + + if (nodes.size() == 0) + return nullptr; + if (nodes.size() == 1) + return std::move(nodes[0]); + + auto node = std::make_unique<PatternNode>(); + node->start = start; + node->end = nodes[nodes.size() - 1]->end; + node->term = "?and"; + node->arguments = std::move(nodes); + node->haveArgumentList = true; + + return node; } std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseUnary() diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h index 1770c7307..7f30a3ea0 100644 --- a/apt-pkg/cachefilter-patterns.h +++ b/apt-pkg/cachefilter-patterns.h @@ -95,6 +95,7 @@ struct PatternTreeParser private: std::unique_ptr<Node> parse(); + std::unique_ptr<Node> parseAnd(); std::unique_ptr<Node> parseUnary(); std::unique_ptr<Node> parsePrimary(); std::unique_ptr<Node> parsePattern(); diff --git a/doc/apt-patterns.7.xml b/doc/apt-patterns.7.xml index 72f1ccbce..3de9b00fc 100644 --- a/doc/apt-patterns.7.xml +++ b/doc/apt-patterns.7.xml @@ -43,7 +43,7 @@ patterns. </para> <variablelist> - <varlistentry><term><code>?and(PATTERN, PATTERN, ...)</code></term> + <varlistentry><term><code>?and(PATTERN, PATTERN, ...)</code></term><term><code>PATTERN PATTERN ...</code></term> <listitem><para>Selects objects where all specified patterns match.</para></listitem> </varlistentry> <varlistentry><term><code>?false</code></term><term><code>~F</code></term> diff --git a/test/libapt/pattern_test.cc b/test/libapt/pattern_test.cc index 7fc6a1f8f..00d356d47 100644 --- a/test/libapt/pattern_test.cc +++ b/test/libapt/pattern_test.cc @@ -176,4 +176,12 @@ TEST(TreeParserTest, ParseShortPattern) caught = true; }; EXPECT_TRUE(caught) << "!X should have thrown an exception"; + + EXPECT_PATTERN_EQ("?a?b", "?and(?a, ?b)"); + EXPECT_PATTERN_EQ("~T~F", "?and(?true, ?false)"); + EXPECT_PATTERN_EQ("~T ~F", "?and(?true, ?false)"); + EXPECT_PATTERN_EQ("~T !~F", "?and(?true, ?not(?false))"); + EXPECT_PATTERN_EQ("!~F ~T", "?and(?not(?false), ?true)"); + EXPECT_PATTERN_EQ("!~F~T", "?and(?not(?false), ?true)"); + } |