summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/cachefilter-patterns.cc26
-rw-r--r--apt-pkg/cachefilter-patterns.h1
-rw-r--r--test/libapt/pattern_test.cc4
3 files changed, 31 insertions, 0 deletions
diff --git a/apt-pkg/cachefilter-patterns.cc b/apt-pkg/cachefilter-patterns.cc
index 8c0b35de2..c6875d995 100644
--- a/apt-pkg/cachefilter-patterns.cc
+++ b/apt-pkg/cachefilter-patterns.cc
@@ -169,10 +169,36 @@ std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parsePrimary()
return node;
if ((node = parsePattern()) != nullptr)
return node;
+ if ((node = parseGroup()) != nullptr)
+ return node;
return nullptr;
}
+std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseGroup()
+{
+ if (sentence[state.offset] != '(')
+ return nullptr;
+
+ auto start = state.offset++;
+
+ skipSpace();
+ auto node = parse();
+ if (node == nullptr)
+ throw Error{Node{state.offset, sentence.size()},
+ "Expected pattern after '('"};
+ skipSpace();
+
+ if (sentence[state.offset] != ')')
+ throw Error{Node{state.offset, sentence.size()},
+ "Expected closing parenthesis"};
+
+ auto end = ++state.offset;
+ node->start = start;
+ node->end = end;
+ return node;
+}
+
std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseArgument()
{
std::unique_ptr<Node> node;
diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h
index c6e701880..1b7e70da5 100644
--- a/apt-pkg/cachefilter-patterns.h
+++ b/apt-pkg/cachefilter-patterns.h
@@ -99,6 +99,7 @@ struct PatternTreeParser
std::unique_ptr<Node> parseAnd();
std::unique_ptr<Node> parseUnary();
std::unique_ptr<Node> parsePrimary();
+ std::unique_ptr<Node> parseGroup();
std::unique_ptr<Node> parsePattern();
std::unique_ptr<Node> parseShortPattern();
std::unique_ptr<Node> parseArgument();
diff --git a/test/libapt/pattern_test.cc b/test/libapt/pattern_test.cc
index d8d962758..ca77959e3 100644
--- a/test/libapt/pattern_test.cc
+++ b/test/libapt/pattern_test.cc
@@ -187,4 +187,8 @@ TEST(TreeParserTest, ParseShortPattern)
EXPECT_PATTERN_EQ("!~F~T | ~T", "?or(?and(?not(?false), ?true), ?true)");
EXPECT_PATTERN_EQ("~ramd64|~rall", "?or(?architecture(amd64), ?architecture(all))");
+ EXPECT_PATTERN_EQ("(?A|?B)?C", "?and(?or(?A, ?B), ?C)");
+ EXPECT_PATTERN_EQ("?A|?B?C", "?or(?A, ?and(?B, ?C))");
+ EXPECT_PATTERN_EQ("?A|(?B?C)", "?or(?A, ?and(?B, ?C))");
+ EXPECT_PATTERN_EQ("(?B?C)|?A", "?or(?and(?B, ?C), ?A)");
}