summaryrefslogtreecommitdiff
path: root/apt-pkg/cachefilter-patterns.h
blob: 4c2ef48df213d3abf1fa2041d24a9082237a39f0 (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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * 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();
};

/**
 * \brief PatternParser 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 PatternParser
{
   pkgCacheFile *file;

   std::unique_ptr<APT::CacheFilter::Matcher> aPattern(std::unique_ptr<PatternTreeParser::Node> &nodeP);
   std::string aWord(std::unique_ptr<PatternTreeParser::Node> &nodeP);
};

namespace Patterns
{
using namespace APT::CacheFilter;

struct PackageIsAutomatic : public PackageMatcher
{
   pkgCacheFile *Cache;
   explicit PackageIsAutomatic(pkgCacheFile *Cache) : Cache(Cache) {}
   bool operator()(pkgCache::PkgIterator const &Pkg) override
   {
      assert(Cache != nullptr);
      return ((*Cache)[Pkg].Flags & pkgCache::Flag::Auto) != 0;
   }
};

struct PackageIsGarbage : public PackageMatcher
{
   pkgCacheFile *Cache;
   explicit PackageIsGarbage(pkgCacheFile *Cache) : Cache(Cache) {}
   bool operator()(pkgCache::PkgIterator const &Pkg) override
   {
      assert(Cache != nullptr);
      return (*Cache)[Pkg].Garbage;
   }
};
} // namespace Patterns
} // namespace Internal
} // namespace APT
#endif