CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pathspec_pattern.cc
Go to the documentation of this file.
1 
5 #include "cvmfs_config.h"
6 #include "pathspec_pattern.h"
7 
8 #include <cassert>
9 
10 #include "pathspec/pathspec.h"
11 
13  const std::string::const_iterator begin,
14  const std::string::const_iterator &end)
15  : valid_(true)
16 {
17  Parse(begin, end);
18 }
19 
21  const PathspecElementPattern& other)
22  : valid_(other.valid_)
23 {
24  subpatterns_.reserve(other.subpatterns_.size());
25  SubPatterns::const_iterator i = other.subpatterns_.begin();
26  SubPatterns::const_iterator iend = other.subpatterns_.end();
27  for (; i != iend; ++i) {
28  subpatterns_.push_back((*i)->Clone());
29  }
30 }
31 
33  const PathspecElementPattern& other)
34 {
35  if (this != &other) {
36  valid_ = other.valid_;
37  subpatterns_.clear();
38  subpatterns_.reserve(other.subpatterns_.size());
39  SubPatterns::const_iterator i = other.subpatterns_.begin();
40  SubPatterns::const_iterator iend = other.subpatterns_.end();
41  for (; i != iend; ++i) {
42  subpatterns_.push_back((*i)->Clone());
43  }
44  }
45 
46  return *this;
47 }
48 
49 
51  SubPatterns::const_iterator i = subpatterns_.begin();
52  SubPatterns::const_iterator iend = subpatterns_.end();
53  for (; i != iend; ++i) {
54  delete *i;
55  }
56  subpatterns_.clear();
57 }
58 
59 
60 void PathspecElementPattern::Parse(const std::string::const_iterator &begin,
61  const std::string::const_iterator &end) {
62  std::string::const_iterator i = begin;
63  while (i != end) {
65  ? ParseSpecialChar(end, &i)
66  : ParsePlaintext(end, &i);
67  if (next->IsEmpty()) {
68  valid_ = false;
69  delete next;
70  } else {
71  subpatterns_.push_back(next);
72  }
73  }
74 }
75 
76 
78  const std::string::const_iterator &end,
79  std::string::const_iterator *i
80 ) {
82  bool next_is_escaped = false;
83 
84  while (*i < end) {
85  if (Pathspec::IsSpecialChar(**i) && !next_is_escaped) {
86  break;
87  }
88 
89  if (**i == Pathspec::kEscaper && !next_is_escaped) {
90  next_is_escaped = true;
91  } else if (next_is_escaped) {
92  if (Pathspec::IsSpecialChar(**i) || **i == Pathspec::kEscaper) {
93  pattern->AddChar(**i);
94  next_is_escaped = false;
95  } else {
96  valid_ = false;
97  }
98  } else {
100  pattern->AddChar(**i);
101  }
102 
103  ++(*i);
104  }
105 
106  return pattern;
107 }
108 
110  const std::string::const_iterator &end,
111  std::string::const_iterator *i
112 ) {
114  const char chr = **i;
115  ++(*i);
116 
117  switch (chr) {
118  case Pathspec::kWildcard:
119  return new WildcardSubPattern();
121  return new PlaceholderSubPattern();
122  default:
123  assert(false && "unrecognized special character");
124  }
125 }
126 
128  const bool is_relaxed) const {
129  std::string result;
130  SubPatterns::const_iterator i = subpatterns_.begin();
131  const SubPatterns::const_iterator iend = subpatterns_.end();
132  for (; i != iend; ++i) {
133  result += (*i)->GenerateRegularExpression(is_relaxed);
134  }
135  return result;
136 }
137 
139  std::string result;
140  SubPatterns::const_iterator i = subpatterns_.begin();
141  const SubPatterns::const_iterator iend = subpatterns_.end();
142  for (; i != iend; ++i) {
143  result += (*i)->GenerateGlobString();
144  }
145  return result;
146 }
147 
149  const PathspecElementPattern &other) const
150 {
151  if (subpatterns_.size() != other.subpatterns_.size() ||
152  IsValid() != other.IsValid()) {
153  return false;
154  }
155 
156  SubPatterns::const_iterator i = subpatterns_.begin();
157  const SubPatterns::const_iterator iend = subpatterns_.end();
158  SubPatterns::const_iterator j = other.subpatterns_.begin();
159  const SubPatterns::const_iterator jend = other.subpatterns_.end();
160 
161  for (; i != iend && j != jend; ++i, ++j) {
162  if (!(*i)->Compare(*j)) {
163  return false;
164  }
165  }
166 
167  return true;
168 }
169 
170 
171 //------------------------------------------------------------------------------
172 
173 
175  chars_.push_back(chr);
176 }
177 
178 std::string
180  const bool is_relaxed) const
181 {
182  // Note: strict and relaxed regex are the same!
183  std::string::const_iterator i = chars_.begin();
184  const std::string::const_iterator iend = chars_.end();
185  std::string regex;
186  for (; i != iend; ++i) {
187  if (IsSpecialRegexCharacter(*i)) {
188  regex += "\\";
189  }
190  regex += *i;
191  }
192  return regex;
193 }
194 
195 
196 std::string
198 {
199  std::string::const_iterator i = chars_.begin();
200  const std::string::const_iterator iend = chars_.end();
201  std::string glob_string;
202  for (; i != iend; ++i) {
203  if (Pathspec::IsSpecialChar(*i)) {
204  glob_string += "\\";
205  }
206  glob_string += *i;
207  }
208  return glob_string;
209 }
210 
212  const char chr) const
213 {
214  return (chr == '.' ||
215  chr == '\\' ||
216  chr == '*' ||
217  chr == '?' ||
218  chr == '[' ||
219  chr == ']' ||
220  chr == '(' ||
221  chr == ')' ||
222  chr == '{' ||
223  chr == '}' ||
224  chr == '^' ||
225  chr == '$' ||
226  chr == '+');
227 }
228 
230  const SubPattern *other) const
231 {
232  if (!other->IsPlaintext()) {
233  return false;
234  }
235 
236  const PlaintextSubPattern *pt_other =
237  dynamic_cast<const PlaintextSubPattern*>(other);
238  assert(pt_other != NULL);
239  return chars_ == pt_other->chars_;
240 }
241 
242 
243 std::string
245  const bool is_relaxed) const
246 {
247  return (is_relaxed)
248  ? std::string(".*")
249  : std::string("[^") + Pathspec::kSeparator + "]*";
250 }
251 
252 
253 std::string
255 {
256  return "*";
257 }
258 
259 
261  const SubPattern *other) const
262 {
263  return other->IsWildcard();
264 }
265 
266 
267 std::string
269  const bool is_relaxed) const
270 {
271  // Note: strict and relaxed regex are the same!
272  return std::string("[^") + Pathspec::kSeparator + "]";
273 }
274 
275 std::string
277 {
278  return "?";
279 }
280 
282  const SubPattern *other) const
283 {
284  return other->IsPlaceholder();
285 }
PathspecElementPattern(const std::string::const_iterator begin, const std::string::const_iterator &end)
bool Compare(const SubPattern *other) const
void Parse(const std::string::const_iterator &begin, const std::string::const_iterator &end)
bool IsSpecialRegexCharacter(const char chr) const
virtual bool IsPlaceholder() const
std::string GenerateRegularExpression(const bool is_relaxed) const
assert((mem||(size==0))&&"Out Of Memory")
static bool IsSpecialChar(const char chr)
Definition: pathspec.h:135
bool operator==(const PathspecElementPattern &other) const
SubPattern * ParsePlaintext(const std::string::const_iterator &end, std::string::const_iterator *i)
std::string GenerateGlobString() const
static const char kEscaper
Definition: pathspec.h:50
bool Compare(const SubPattern *other) const
PathspecElementPattern & operator=(const PathspecElementPattern &other)
std::string GenerateRegularExpression(const bool is_relaxed=false) const
static const char kSeparator
Definition: pathspec.h:49
std::string GenerateRegularExpression(const bool is_relaxed) const
static const char kWildcard
Definition: pathspec.h:51
std::string GenerateRegularExpression(const bool is_relaxed) const
bool Compare(const SubPattern *other) const
SubPattern * ParseSpecialChar(const std::string::const_iterator &end, std::string::const_iterator *i)
static const char kPlaceholder
Definition: pathspec.h:52