blob: dfbcd66a5a9b0a1377da9ff27be0fffb85b55c42 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/*
* cachefilter-patterns.h - Pattern parser and additional patterns as matchers
*
* Copyright (c) 2019 Canonical Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef APT_CACHEFILTER_PATTERNS_H
#define APT_CACHEFILTER_PATTERNS_H
#include <apt-pkg/cachefile.h>
#include <apt-pkg/cachefilter.h>
#include <apt-pkg/error.h>
#include <apt-pkg/string_view.h>
#include <apt-pkg/strutl.h>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include <assert.h>
namespace APT
{
namespace Internal
{
/**
* \brief PatternTreeParser parses the given sentence into a parse tree.
*
* The parse tree consists of nodes:
* - Word nodes which contains words or quoted words
* - Patterns, which represent ?foo and ?foo(...) patterns
*/
struct PatternTreeParser
{
struct Node
{
size_t start = 0;
size_t end = 0;
virtual std::ostream &render(std::ostream &os) { return os; };
std::nullptr_t error(std::string message);
};
struct Error : public std::exception
{
Node location;
std::string message;
Error(Node location, std::string message) : location(location), message(message) {}
const char *what() const throw() override { return message.c_str(); }
};
struct PatternNode : public Node
{
APT::StringView term;
std::vector<std::unique_ptr<Node>> arguments;
bool haveArgumentList = false;
std::ostream &render(std::ostream &stream) override;
bool matches(APT::StringView name, int min, int max);
};
struct WordNode : public Node
{
APT::StringView word;
bool quoted = false;
std::ostream &render(std::ostream &stream) override;
};
struct State
{
off_t offset = 0;
};
APT::StringView sentence;
State state;
PatternTreeParser(APT::StringView sentence) : sentence(sentence){};
off_t skipSpace()
{
while (sentence[state.offset] == ' ' || sentence[state.offset] == '\t' || sentence[state.offset] == '\r' || sentence[state.offset] == '\n')
state.offset++;
return state.offset;
};
/// \brief Parse a complete pattern
///
/// There may not be anything before or after the pattern, except for
/// whitespace.
std::unique_ptr<Node> parseTop();
private:
std::unique_ptr<Node> parse();
std::unique_ptr<Node> parsePattern();
std::unique_ptr<Node> parseWord();
std::unique_ptr<Node> parseQuotedWord();
};
} // namespace Internal
} // namespace APT
#endif
|