diff options
-rw-r--r-- | apt-pkg/cachefilter-patterns.cc | 26 | ||||
-rw-r--r-- | apt-pkg/cachefilter-patterns.h | 1 | ||||
-rw-r--r-- | test/libapt/pattern_test.cc | 4 |
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)"); } |