summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2020-01-28 22:38:46 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2020-02-03 12:55:54 +0100
commit250119362e44599aad7e75462fa4298ad1ab1ad9 (patch)
tree8dc35269b74db8d099d8638866c404fc7c00d0bb
parentebe5f39bfbb64921d5d31e0a6e49287356a5e6e2 (diff)
patterns: Parse sequence of patterns as ?and
-rw-r--r--apt-pkg/cachefilter-patterns.cc32
-rw-r--r--apt-pkg/cachefilter-patterns.h1
-rw-r--r--doc/apt-patterns.7.xml2
-rw-r--r--test/libapt/pattern_test.cc8
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)");
+
}