CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pathspec_pattern.cc
Go to the documentation of this file.
1 
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  Parse(begin, end);
17 }
18 
20  const PathspecElementPattern &other)
21  : valid_(other.valid_) {
22  subpatterns_.reserve(other.subpatterns_.size());
23  SubPatterns::const_iterator i = other.subpatterns_.begin();
24  const SubPatterns::const_iterator iend = other.subpatterns_.end();
25  for (; i != iend; ++i) {
26  subpatterns_.push_back((*i)->Clone());
27  }
28 }
29 
31  const PathspecElementPattern &other) {
32  if (this != &other) {
33  valid_ = other.valid_;
34  subpatterns_.clear();
35  subpatterns_.reserve(other.subpatterns_.size());
36  SubPatterns::const_iterator i = other.subpatterns_.begin();
37  const SubPatterns::const_iterator iend = other.subpatterns_.end();
38  for (; i != iend; ++i) {
39  subpatterns_.push_back((*i)->Clone());
40  }
41  }
42 
43  return *this;
44 }
45 
46 
48  SubPatterns::const_iterator i = subpatterns_.begin();
49  const SubPatterns::const_iterator iend = subpatterns_.end();
50  for (; i != iend; ++i) {
51  delete *i;
52  }
53  subpatterns_.clear();
54 }
55 
56 
57 void PathspecElementPattern::Parse(const std::string::const_iterator &begin,
58  const std::string::const_iterator &end) {
59  std::string::const_iterator i = begin;
60  while (i != end) {
61  SubPattern *next = (Pathspec::IsSpecialChar(*i)) ? ParseSpecialChar(end, &i)
62  : ParsePlaintext(end, &i);
63  if (next->IsEmpty()) {
64  valid_ = false;
65  delete next;
66  } else {
67  subpatterns_.push_back(next);
68  }
69  }
70 }
71 
72 
74  const std::string::const_iterator &end, std::string::const_iterator *i) {
76  bool next_is_escaped = false;
77 
78  while (*i < end) {
79  if (Pathspec::IsSpecialChar(**i) && !next_is_escaped) {
80  break;
81  }
82 
83  if (**i == Pathspec::kEscaper && !next_is_escaped) {
84  next_is_escaped = true;
85  } else if (next_is_escaped) {
86  if (Pathspec::IsSpecialChar(**i) || **i == Pathspec::kEscaper) {
87  pattern->AddChar(**i);
88  next_is_escaped = false;
89  } else {
90  valid_ = false;
91  }
92  } else {
94  pattern->AddChar(**i);
95  }
96 
97  ++(*i);
98  }
99 
100  return pattern;
101 }
102 
104  const std::string::const_iterator &end, std::string::const_iterator *i) {
106  const char chr = **i;
107  ++(*i);
108 
109  switch (chr) {
110  case Pathspec::kWildcard:
111  return new WildcardSubPattern();
113  return new PlaceholderSubPattern();
114  default:
115  assert(false && "unrecognized special character");
116  }
117 }
118 
120  const bool is_relaxed) const {
121  std::string result;
122  SubPatterns::const_iterator i = subpatterns_.begin();
123  const SubPatterns::const_iterator iend = subpatterns_.end();
124  for (; i != iend; ++i) {
125  result += (*i)->GenerateRegularExpression(is_relaxed);
126  }
127  return result;
128 }
129 
131  std::string result;
132  SubPatterns::const_iterator i = subpatterns_.begin();
133  const SubPatterns::const_iterator iend = subpatterns_.end();
134  for (; i != iend; ++i) {
135  result += (*i)->GenerateGlobString();
136  }
137  return result;
138 }
139 
141  const PathspecElementPattern &other) const {
142  if (subpatterns_.size() != other.subpatterns_.size()
143  || IsValid() != other.IsValid()) {
144  return false;
145  }
146 
147  SubPatterns::const_iterator i = subpatterns_.begin();
148  const SubPatterns::const_iterator iend = subpatterns_.end();
149  SubPatterns::const_iterator j = other.subpatterns_.begin();
150  const SubPatterns::const_iterator jend = other.subpatterns_.end();
151 
152  for (; i != iend && j != jend; ++i, ++j) {
153  if (!(*i)->Compare(*j)) {
154  return false;
155  }
156  }
157 
158  return true;
159 }
160 
161 
162 //------------------------------------------------------------------------------
163 
164 
166  chars_.push_back(chr);
167 }
168 
169 std::string
171  const bool is_relaxed) const {
172  // Note: strict and relaxed regex are the same!
173  std::string::const_iterator i = chars_.begin();
174  const std::string::const_iterator iend = chars_.end();
175  std::string regex;
176  for (; i != iend; ++i) {
177  if (IsSpecialRegexCharacter(*i)) {
178  regex += "\\";
179  }
180  regex += *i;
181  }
182  return regex;
183 }
184 
185 
187  const {
188  std::string::const_iterator i = chars_.begin();
189  const std::string::const_iterator iend = chars_.end();
190  std::string glob_string;
191  for (; i != iend; ++i) {
192  if (Pathspec::IsSpecialChar(*i)) {
193  glob_string += "\\";
194  }
195  glob_string += *i;
196  }
197  return glob_string;
198 }
199 
201  const char chr) const {
202  return (chr == '.' || chr == '\\' || chr == '*' || chr == '?' || chr == '['
203  || chr == ']' || chr == '(' || chr == ')' || chr == '{' || chr == '}'
204  || chr == '^' || chr == '$' || chr == '+');
205 }
206 
208  const SubPattern *other) const {
209  if (!other->IsPlaintext()) {
210  return false;
211  }
212 
213  const PlaintextSubPattern
214  *pt_other = dynamic_cast<const PlaintextSubPattern *>(other);
215  assert(pt_other != NULL);
216  return chars_ == pt_other->chars_;
217 }
218 
219 
220 std::string
222  const bool is_relaxed) const {
223  return (is_relaxed) ? std::string(".*")
224  : std::string("[^") + Pathspec::kSeparator + "]*";
225 }
226 
227 
229  const {
230  return "*";
231 }
232 
233 
235  const SubPattern *other) const {
236  return other->IsWildcard();
237 }
238 
239 
240 std::string
242  const bool is_relaxed) const {
243  // Note: strict and relaxed regex are the same!
244  return std::string("[^") + Pathspec::kSeparator + "]";
245 }
246 
248  const {
249  return "?";
250 }
251 
253  const SubPattern *other) const {
254  return other->IsPlaceholder();
255 }
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