21
21
#include " path.h"
22
22
23
23
#include < algorithm>
24
- #include < cctype>
25
- #include < cstdio>
26
24
#include < stack>
27
25
#include < string>
28
26
#include < vector>
29
27
30
- struct Pathstr
31
- {
32
- static Pathstr from_pattern (const std::string &pattern, const std::string &basepath, bool icase)
33
- {
34
- if (!pattern.empty () && pattern[0 ] == ' .' )
35
- return Pathstr (basepath.c_str (), pattern.c_str (), icase);
36
- return Pathstr (pattern.c_str (), nullptr , icase);
37
- }
38
-
39
- static Pathstr from_path (const std::string &path, const std::string &basepath, bool icase)
40
- {
41
- if (Path::isAbsolute (path))
42
- return Pathstr (path.c_str (), nullptr , icase);
43
- return Pathstr (basepath.c_str (), path.c_str (), icase);
44
- }
45
-
46
- explicit Pathstr (const char *a = nullptr , const char *b = nullptr , bool lowercase = false ) :
47
- s{a, b}, lcase(lowercase)
48
- {
49
- for (int i = 0 ; i < 2 ; i++) {
50
- e[i] = s[i];
51
-
52
- if (s[i] == nullptr || *s[i] == ' \0 ' )
53
- continue ;
54
-
55
- if (st.l != 0 )
56
- st.l ++;
57
-
58
- while (*e[i] != ' \0 ' ) {
59
- e[i]++;
60
- st.l ++;
61
- }
62
-
63
- st.p = e[i];
64
- }
65
-
66
- if (st.l == 0 )
67
- st.c = ' \0 ' ;
68
-
69
- simplify (false );
70
- }
71
-
72
- std::size_t left () const
73
- {
74
- return st.l ;
75
- }
76
-
77
- char current () const
78
- {
79
- if (st.c != EOF)
80
- return st.c ;
81
-
82
- char c = st.p [-1 ];
83
-
84
- if (c == ' \\ ' )
85
- return ' /' ;
86
-
87
- if (lcase)
88
- return std::tolower (c);
89
-
90
- return c;
91
- }
92
-
93
- void simplify (bool leadsep)
94
- {
95
- while (left () != 0 ) {
96
- State rst = st;
97
-
98
- if (leadsep) {
99
- if (current () != ' /' )
100
- break ;
101
- nextc ();
102
- }
103
-
104
- char c = current ();
105
- if (c == ' .' ) {
106
- nextc ();
107
- c = current ();
108
- if (c == ' .' ) {
109
- nextc ();
110
- c = current ();
111
- if (c == ' /' ) {
112
- /* Skip '<name>/../' */
113
- nextc ();
114
- simplify (false );
115
- while (left () != 0 && current () != ' /' )
116
- nextc ();
117
- continue ;
118
- }
119
- } else if (c == ' /' ) {
120
- /* Skip '/./' */
121
- continue ;
122
- } else if (c == ' \0 ' ) {
123
- /* Skip leading './' */
124
- break ;
125
- }
126
- } else if (c == ' /' && left () != 1 ) {
127
- /* Skip double separator (keep root) */
128
- nextc ();
129
- leadsep = false ;
130
- continue ;
131
- }
132
-
133
- st = rst;
134
- break ;
135
- }
136
- }
137
-
138
- void advance ()
139
- {
140
- nextc ();
141
-
142
- if (current () == ' /' )
143
- simplify (true );
144
- }
145
28
146
- void nextc ()
147
- {
148
- if (st.l == 0 )
149
- return ;
150
-
151
- st.l --;
152
-
153
- if (st.l == 0 )
154
- st.c = ' \0 ' ;
155
- else if (st.c != EOF) {
156
- st.c = EOF;
157
- } else {
158
- st.p --;
159
- if (st.p == s[1 ]) {
160
- st.p = e[0 ];
161
- st.c = ' /' ;
162
- }
163
- }
164
- }
165
-
166
- void operator ++()
167
- {
168
- advance ();
169
- }
170
-
171
- char operator *() const
172
- {
173
- return current ();
174
- }
175
-
176
- struct State
177
- {
178
- const char *p;
179
- std::size_t l;
180
- int c {EOF};
181
- };
182
-
183
- const char *s[2 ] {};
184
- const char *e[2 ] {};
185
- State st {};
186
- bool lcase;
187
- };
29
+ PathMatch::PathMatch (std::vector<std::string> patterns, std::string basepath, Mode mode) :
30
+ mPatterns(std::move(patterns)), mBasepath(std::move(basepath)), mMode(mode)
31
+ {}
188
32
33
+ bool PathMatch::match (const std::string &path) const
34
+ {
35
+ return std::any_of (mPatterns .cbegin (), mPatterns .cend (), [=] (const std::string &pattern) {
36
+ return match (pattern, path, mBasepath , mMode );
37
+ });
38
+ }
189
39
190
- static bool match_one (const std::string &pattern, const std::string &path, const std::string &basepath, bool icase )
40
+ bool PathMatch::match (const std::string &pattern, const std::string &path, const std::string &basepath, Mode mode )
191
41
{
192
42
if (pattern.empty ())
193
43
return false ;
@@ -197,13 +47,12 @@ static bool match_one(const std::string &pattern, const std::string &path, const
197
47
198
48
bool real = Path::isAbsolute (pattern) || pattern[0 ] == ' .' ;
199
49
200
- Pathstr s = Pathstr::from_pattern (pattern, basepath, icase);
201
- Pathstr t = Pathstr::from_path (path, basepath, icase);
202
-
203
- Pathstr p = s;
204
- Pathstr q = t;
50
+ PathIterator s = PathIterator::from_pattern (pattern, basepath, mode == Mode::icase);
51
+ PathIterator t = PathIterator::from_path (path, basepath, mode == Mode::icase);
52
+ PathIterator p = s;
53
+ PathIterator q = t;
205
54
206
- std::stack<std::pair<Pathstr::State, Pathstr::State >> b;
55
+ std::stack<std::pair<PathIterator::Pos, PathIterator::Pos >> b;
207
56
208
57
for (;;) {
209
58
switch (*s) {
@@ -214,10 +63,10 @@ static bool match_one(const std::string &pattern, const std::string &path, const
214
63
slash = true ;
215
64
++s;
216
65
}
217
- b.emplace (s.st , t.st );
66
+ b.emplace (s.getpos () , t.getpos () );
218
67
while (*t != ' \0 ' && (slash || *t != ' /' )) {
219
68
if (*s == *t)
220
- b.emplace (s.st , t.st );
69
+ b.emplace (s.getpos () , t.getpos () );
221
70
++t;
222
71
}
223
72
continue ;
@@ -248,8 +97,8 @@ static bool match_one(const std::string &pattern, const std::string &path, const
248
97
if (!b.empty ()) {
249
98
const auto &bp = b.top ();
250
99
b.pop ();
251
- s.st = bp.first ;
252
- t.st = bp.second ;
100
+ s.setpos ( bp.first ) ;
101
+ t.setpos ( bp.second ) ;
253
102
continue ;
254
103
}
255
104
@@ -266,20 +115,3 @@ static bool match_one(const std::string &pattern, const std::string &path, const
266
115
return false ;
267
116
}
268
117
}
269
-
270
-
271
- PathMatch::PathMatch (std::vector<std::string> patterns, std::string basepath, Mode mode) :
272
- mPatterns(std::move(patterns)), mBasepath(std::move(basepath)), mMode(mode)
273
- {}
274
-
275
- bool PathMatch::match (const std::string &path) const
276
- {
277
- return std::any_of (mPatterns .cbegin (), mPatterns .cend (), [=] (const std::string &pattern) {
278
- return match_one (pattern, path, mBasepath , mMode == Mode::icase);
279
- });
280
- }
281
-
282
- bool PathMatch::match (const std::string &pattern, const std::string &path, const std::string &basepath, Mode mode)
283
- {
284
- return match_one (pattern, path, basepath, mode == Mode::icase);
285
- }
0 commit comments