xref: /aosp_15_r20/external/lzma/CPP/Common/Wildcard.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Common/Wildcard.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "Wildcard.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker extern
8*f6dc9357SAndroid Build Coastguard Worker bool g_CaseSensitive;
9*f6dc9357SAndroid Build Coastguard Worker bool g_CaseSensitive =
10*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
11*f6dc9357SAndroid Build Coastguard Worker     false;
12*f6dc9357SAndroid Build Coastguard Worker   #elif defined (__APPLE__)
13*f6dc9357SAndroid Build Coastguard Worker     #ifdef TARGET_OS_IPHONE
14*f6dc9357SAndroid Build Coastguard Worker       true;
15*f6dc9357SAndroid Build Coastguard Worker     #else
16*f6dc9357SAndroid Build Coastguard Worker       false;
17*f6dc9357SAndroid Build Coastguard Worker     #endif
18*f6dc9357SAndroid Build Coastguard Worker   #else
19*f6dc9357SAndroid Build Coastguard Worker     true;
20*f6dc9357SAndroid Build Coastguard Worker   #endif
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker 
IsPath1PrefixedByPath2(const wchar_t * s1,const wchar_t * s2)23*f6dc9357SAndroid Build Coastguard Worker bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
24*f6dc9357SAndroid Build Coastguard Worker {
25*f6dc9357SAndroid Build Coastguard Worker   if (g_CaseSensitive)
26*f6dc9357SAndroid Build Coastguard Worker     return IsString1PrefixedByString2(s1, s2);
27*f6dc9357SAndroid Build Coastguard Worker   return IsString1PrefixedByString2_NoCase(s1, s2);
28*f6dc9357SAndroid Build Coastguard Worker }
29*f6dc9357SAndroid Build Coastguard Worker 
30*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
31*f6dc9357SAndroid Build Coastguard Worker 
32*f6dc9357SAndroid Build Coastguard Worker /*
33*f6dc9357SAndroid Build Coastguard Worker static int MyStringCompare_PathLinux(const wchar_t *s1, const wchar_t *s2) throw()
34*f6dc9357SAndroid Build Coastguard Worker {
35*f6dc9357SAndroid Build Coastguard Worker   for (;;)
36*f6dc9357SAndroid Build Coastguard Worker   {
37*f6dc9357SAndroid Build Coastguard Worker     wchar_t c1 = *s1++;
38*f6dc9357SAndroid Build Coastguard Worker     wchar_t c2 = *s2++;
39*f6dc9357SAndroid Build Coastguard Worker     if (c1 != c2)
40*f6dc9357SAndroid Build Coastguard Worker     {
41*f6dc9357SAndroid Build Coastguard Worker       if (c1 == 0) return -1;
42*f6dc9357SAndroid Build Coastguard Worker       if (c2 == 0) return 1;
43*f6dc9357SAndroid Build Coastguard Worker       if (c1 == '/') c1 = 0;
44*f6dc9357SAndroid Build Coastguard Worker       if (c2 == '/') c2 = 0;
45*f6dc9357SAndroid Build Coastguard Worker       if (c1 < c2) return -1;
46*f6dc9357SAndroid Build Coastguard Worker       if (c1 > c2) return 1;
47*f6dc9357SAndroid Build Coastguard Worker       continue;
48*f6dc9357SAndroid Build Coastguard Worker     }
49*f6dc9357SAndroid Build Coastguard Worker     if (c1 == 0) return 0;
50*f6dc9357SAndroid Build Coastguard Worker   }
51*f6dc9357SAndroid Build Coastguard Worker }
52*f6dc9357SAndroid Build Coastguard Worker */
53*f6dc9357SAndroid Build Coastguard Worker 
MyStringCompare_Path(const wchar_t * s1,const wchar_t * s2)54*f6dc9357SAndroid Build Coastguard Worker static int MyStringCompare_Path(const wchar_t *s1, const wchar_t *s2) throw()
55*f6dc9357SAndroid Build Coastguard Worker {
56*f6dc9357SAndroid Build Coastguard Worker   for (;;)
57*f6dc9357SAndroid Build Coastguard Worker   {
58*f6dc9357SAndroid Build Coastguard Worker     wchar_t c1 = *s1++;
59*f6dc9357SAndroid Build Coastguard Worker     wchar_t c2 = *s2++;
60*f6dc9357SAndroid Build Coastguard Worker     if (c1 != c2)
61*f6dc9357SAndroid Build Coastguard Worker     {
62*f6dc9357SAndroid Build Coastguard Worker       if (c1 == 0) return -1;
63*f6dc9357SAndroid Build Coastguard Worker       if (c2 == 0) return 1;
64*f6dc9357SAndroid Build Coastguard Worker       if (IS_PATH_SEPAR(c1)) c1 = 0;
65*f6dc9357SAndroid Build Coastguard Worker       if (IS_PATH_SEPAR(c2)) c2 = 0;
66*f6dc9357SAndroid Build Coastguard Worker       if (c1 < c2) return -1;
67*f6dc9357SAndroid Build Coastguard Worker       if (c1 > c2) return 1;
68*f6dc9357SAndroid Build Coastguard Worker       continue;
69*f6dc9357SAndroid Build Coastguard Worker     }
70*f6dc9357SAndroid Build Coastguard Worker     if (c1 == 0) return 0;
71*f6dc9357SAndroid Build Coastguard Worker   }
72*f6dc9357SAndroid Build Coastguard Worker }
73*f6dc9357SAndroid Build Coastguard Worker 
MyStringCompareNoCase_Path(const wchar_t * s1,const wchar_t * s2)74*f6dc9357SAndroid Build Coastguard Worker static int MyStringCompareNoCase_Path(const wchar_t *s1, const wchar_t *s2) throw()
75*f6dc9357SAndroid Build Coastguard Worker {
76*f6dc9357SAndroid Build Coastguard Worker   for (;;)
77*f6dc9357SAndroid Build Coastguard Worker   {
78*f6dc9357SAndroid Build Coastguard Worker     wchar_t c1 = *s1++;
79*f6dc9357SAndroid Build Coastguard Worker     wchar_t c2 = *s2++;
80*f6dc9357SAndroid Build Coastguard Worker     if (c1 != c2)
81*f6dc9357SAndroid Build Coastguard Worker     {
82*f6dc9357SAndroid Build Coastguard Worker       if (c1 == 0) return -1;
83*f6dc9357SAndroid Build Coastguard Worker       if (c2 == 0) return 1;
84*f6dc9357SAndroid Build Coastguard Worker       if (IS_PATH_SEPAR(c1)) c1 = 0;
85*f6dc9357SAndroid Build Coastguard Worker       if (IS_PATH_SEPAR(c2)) c2 = 0;
86*f6dc9357SAndroid Build Coastguard Worker       c1 = MyCharUpper(c1);
87*f6dc9357SAndroid Build Coastguard Worker       c2 = MyCharUpper(c2);
88*f6dc9357SAndroid Build Coastguard Worker       if (c1 < c2) return -1;
89*f6dc9357SAndroid Build Coastguard Worker       if (c1 > c2) return 1;
90*f6dc9357SAndroid Build Coastguard Worker       continue;
91*f6dc9357SAndroid Build Coastguard Worker     }
92*f6dc9357SAndroid Build Coastguard Worker     if (c1 == 0) return 0;
93*f6dc9357SAndroid Build Coastguard Worker   }
94*f6dc9357SAndroid Build Coastguard Worker }
95*f6dc9357SAndroid Build Coastguard Worker 
CompareFileNames(const wchar_t * s1,const wchar_t * s2)96*f6dc9357SAndroid Build Coastguard Worker int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
97*f6dc9357SAndroid Build Coastguard Worker {
98*f6dc9357SAndroid Build Coastguard Worker   /*
99*f6dc9357SAndroid Build Coastguard Worker   printf("\nCompareFileNames");
100*f6dc9357SAndroid Build Coastguard Worker   printf("\n S1: %ls", s1);
101*f6dc9357SAndroid Build Coastguard Worker   printf("\n S2: %ls", s2);
102*f6dc9357SAndroid Build Coastguard Worker   printf("\n");
103*f6dc9357SAndroid Build Coastguard Worker   */
104*f6dc9357SAndroid Build Coastguard Worker   // 21.07 : we parse PATH_SEPARATOR so: 0 < PATH_SEPARATOR < 1
105*f6dc9357SAndroid Build Coastguard Worker   if (g_CaseSensitive)
106*f6dc9357SAndroid Build Coastguard Worker     return MyStringCompare_Path(s1, s2);
107*f6dc9357SAndroid Build Coastguard Worker   return MyStringCompareNoCase_Path(s1, s2);
108*f6dc9357SAndroid Build Coastguard Worker }
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
CompareFileNames(const char * s1,const char * s2)111*f6dc9357SAndroid Build Coastguard Worker int CompareFileNames(const char *s1, const char *s2)
112*f6dc9357SAndroid Build Coastguard Worker {
113*f6dc9357SAndroid Build Coastguard Worker   const UString u1 = fs2us(s1);
114*f6dc9357SAndroid Build Coastguard Worker   const UString u2 = fs2us(s2);
115*f6dc9357SAndroid Build Coastguard Worker   return CompareFileNames(u1, u2);
116*f6dc9357SAndroid Build Coastguard Worker }
117*f6dc9357SAndroid Build Coastguard Worker #endif
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker // -----------------------------------------
120*f6dc9357SAndroid Build Coastguard Worker // this function compares name with mask
121*f6dc9357SAndroid Build Coastguard Worker // ? - any char
122*f6dc9357SAndroid Build Coastguard Worker // * - any char or empty
123*f6dc9357SAndroid Build Coastguard Worker 
EnhancedMaskTest(const wchar_t * mask,const wchar_t * name)124*f6dc9357SAndroid Build Coastguard Worker static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
125*f6dc9357SAndroid Build Coastguard Worker {
126*f6dc9357SAndroid Build Coastguard Worker   for (;;)
127*f6dc9357SAndroid Build Coastguard Worker   {
128*f6dc9357SAndroid Build Coastguard Worker     const wchar_t m = *mask;
129*f6dc9357SAndroid Build Coastguard Worker     const wchar_t c = *name;
130*f6dc9357SAndroid Build Coastguard Worker     if (m == 0)
131*f6dc9357SAndroid Build Coastguard Worker       return (c == 0);
132*f6dc9357SAndroid Build Coastguard Worker     if (m == '*')
133*f6dc9357SAndroid Build Coastguard Worker     {
134*f6dc9357SAndroid Build Coastguard Worker       if (EnhancedMaskTest(mask + 1, name))
135*f6dc9357SAndroid Build Coastguard Worker         return true;
136*f6dc9357SAndroid Build Coastguard Worker       if (c == 0)
137*f6dc9357SAndroid Build Coastguard Worker         return false;
138*f6dc9357SAndroid Build Coastguard Worker     }
139*f6dc9357SAndroid Build Coastguard Worker     else
140*f6dc9357SAndroid Build Coastguard Worker     {
141*f6dc9357SAndroid Build Coastguard Worker       if (m == '?')
142*f6dc9357SAndroid Build Coastguard Worker       {
143*f6dc9357SAndroid Build Coastguard Worker         if (c == 0)
144*f6dc9357SAndroid Build Coastguard Worker           return false;
145*f6dc9357SAndroid Build Coastguard Worker       }
146*f6dc9357SAndroid Build Coastguard Worker       else if (m != c)
147*f6dc9357SAndroid Build Coastguard Worker         if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c))
148*f6dc9357SAndroid Build Coastguard Worker           return false;
149*f6dc9357SAndroid Build Coastguard Worker       mask++;
150*f6dc9357SAndroid Build Coastguard Worker     }
151*f6dc9357SAndroid Build Coastguard Worker     name++;
152*f6dc9357SAndroid Build Coastguard Worker   }
153*f6dc9357SAndroid Build Coastguard Worker }
154*f6dc9357SAndroid Build Coastguard Worker 
155*f6dc9357SAndroid Build Coastguard Worker // --------------------------------------------------
156*f6dc9357SAndroid Build Coastguard Worker // Splits path to strings
157*f6dc9357SAndroid Build Coastguard Worker 
SplitPathToParts(const UString & path,UStringVector & pathParts)158*f6dc9357SAndroid Build Coastguard Worker void SplitPathToParts(const UString &path, UStringVector &pathParts)
159*f6dc9357SAndroid Build Coastguard Worker {
160*f6dc9357SAndroid Build Coastguard Worker   pathParts.Clear();
161*f6dc9357SAndroid Build Coastguard Worker   unsigned len = path.Len();
162*f6dc9357SAndroid Build Coastguard Worker   if (len == 0)
163*f6dc9357SAndroid Build Coastguard Worker     return;
164*f6dc9357SAndroid Build Coastguard Worker   UString name;
165*f6dc9357SAndroid Build Coastguard Worker   unsigned prev = 0;
166*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < len; i++)
167*f6dc9357SAndroid Build Coastguard Worker     if (IsPathSepar(path[i]))
168*f6dc9357SAndroid Build Coastguard Worker     {
169*f6dc9357SAndroid Build Coastguard Worker       name.SetFrom(path.Ptr(prev), i - prev);
170*f6dc9357SAndroid Build Coastguard Worker       pathParts.Add(name);
171*f6dc9357SAndroid Build Coastguard Worker       prev = i + 1;
172*f6dc9357SAndroid Build Coastguard Worker     }
173*f6dc9357SAndroid Build Coastguard Worker   name.SetFrom(path.Ptr(prev), len - prev);
174*f6dc9357SAndroid Build Coastguard Worker   pathParts.Add(name);
175*f6dc9357SAndroid Build Coastguard Worker }
176*f6dc9357SAndroid Build Coastguard Worker 
SplitPathToParts_2(const UString & path,UString & dirPrefix,UString & name)177*f6dc9357SAndroid Build Coastguard Worker void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name)
178*f6dc9357SAndroid Build Coastguard Worker {
179*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *start = path;
180*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *p = start + path.Len();
181*f6dc9357SAndroid Build Coastguard Worker   for (; p != start; p--)
182*f6dc9357SAndroid Build Coastguard Worker     if (IsPathSepar(*(p - 1)))
183*f6dc9357SAndroid Build Coastguard Worker       break;
184*f6dc9357SAndroid Build Coastguard Worker   dirPrefix.SetFrom(path, (unsigned)(p - start));
185*f6dc9357SAndroid Build Coastguard Worker   name = p;
186*f6dc9357SAndroid Build Coastguard Worker }
187*f6dc9357SAndroid Build Coastguard Worker 
SplitPathToParts_Smart(const UString & path,UString & dirPrefix,UString & name)188*f6dc9357SAndroid Build Coastguard Worker void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name)
189*f6dc9357SAndroid Build Coastguard Worker {
190*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *start = path;
191*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *p = start + path.Len();
192*f6dc9357SAndroid Build Coastguard Worker   if (p != start)
193*f6dc9357SAndroid Build Coastguard Worker   {
194*f6dc9357SAndroid Build Coastguard Worker     if (IsPathSepar(*(p - 1)))
195*f6dc9357SAndroid Build Coastguard Worker       p--;
196*f6dc9357SAndroid Build Coastguard Worker     for (; p != start; p--)
197*f6dc9357SAndroid Build Coastguard Worker       if (IsPathSepar(*(p - 1)))
198*f6dc9357SAndroid Build Coastguard Worker         break;
199*f6dc9357SAndroid Build Coastguard Worker   }
200*f6dc9357SAndroid Build Coastguard Worker   dirPrefix.SetFrom(path, (unsigned)(p - start));
201*f6dc9357SAndroid Build Coastguard Worker   name = p;
202*f6dc9357SAndroid Build Coastguard Worker }
203*f6dc9357SAndroid Build Coastguard Worker 
204*f6dc9357SAndroid Build Coastguard Worker /*
205*f6dc9357SAndroid Build Coastguard Worker UString ExtractDirPrefixFromPath(const UString &path)
206*f6dc9357SAndroid Build Coastguard Worker {
207*f6dc9357SAndroid Build Coastguard Worker   return path.Left(path.ReverseFind_PathSepar() + 1));
208*f6dc9357SAndroid Build Coastguard Worker }
209*f6dc9357SAndroid Build Coastguard Worker */
210*f6dc9357SAndroid Build Coastguard Worker 
ExtractFileNameFromPath(const UString & path)211*f6dc9357SAndroid Build Coastguard Worker UString ExtractFileNameFromPath(const UString &path)
212*f6dc9357SAndroid Build Coastguard Worker {
213*f6dc9357SAndroid Build Coastguard Worker   return UString(path.Ptr((unsigned)(path.ReverseFind_PathSepar() + 1)));
214*f6dc9357SAndroid Build Coastguard Worker }
215*f6dc9357SAndroid Build Coastguard Worker 
216*f6dc9357SAndroid Build Coastguard Worker 
DoesWildcardMatchName(const UString & mask,const UString & name)217*f6dc9357SAndroid Build Coastguard Worker bool DoesWildcardMatchName(const UString &mask, const UString &name)
218*f6dc9357SAndroid Build Coastguard Worker {
219*f6dc9357SAndroid Build Coastguard Worker   return EnhancedMaskTest(mask, name);
220*f6dc9357SAndroid Build Coastguard Worker }
221*f6dc9357SAndroid Build Coastguard Worker 
DoesNameContainWildcard(const UString & path)222*f6dc9357SAndroid Build Coastguard Worker bool DoesNameContainWildcard(const UString &path)
223*f6dc9357SAndroid Build Coastguard Worker {
224*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < path.Len(); i++)
225*f6dc9357SAndroid Build Coastguard Worker   {
226*f6dc9357SAndroid Build Coastguard Worker     wchar_t c = path[i];
227*f6dc9357SAndroid Build Coastguard Worker     if (c == '*' || c == '?')
228*f6dc9357SAndroid Build Coastguard Worker       return true;
229*f6dc9357SAndroid Build Coastguard Worker   }
230*f6dc9357SAndroid Build Coastguard Worker   return false;
231*f6dc9357SAndroid Build Coastguard Worker }
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker 
234*f6dc9357SAndroid Build Coastguard Worker // ----------------------------------------------------------'
235*f6dc9357SAndroid Build Coastguard Worker // NWildcard
236*f6dc9357SAndroid Build Coastguard Worker 
237*f6dc9357SAndroid Build Coastguard Worker namespace NWildcard {
238*f6dc9357SAndroid Build Coastguard Worker 
239*f6dc9357SAndroid Build Coastguard Worker /*
240*f6dc9357SAndroid Build Coastguard Worker 
241*f6dc9357SAndroid Build Coastguard Worker M = MaskParts.Size();
242*f6dc9357SAndroid Build Coastguard Worker N = TestNameParts.Size();
243*f6dc9357SAndroid Build Coastguard Worker 
244*f6dc9357SAndroid Build Coastguard Worker                            File                          Dir
245*f6dc9357SAndroid Build Coastguard Worker ForFile     rec   M<=N  [N-M, N)                          -
246*f6dc9357SAndroid Build Coastguard Worker !ForDir  nonrec   M=N   [0, M)                            -
247*f6dc9357SAndroid Build Coastguard Worker 
248*f6dc9357SAndroid Build Coastguard Worker ForDir      rec   M<N   [0, M) ... [N-M-1, N-1)  same as ForBoth-File
249*f6dc9357SAndroid Build Coastguard Worker !ForFile nonrec         [0, M)                   same as ForBoth-File
250*f6dc9357SAndroid Build Coastguard Worker 
251*f6dc9357SAndroid Build Coastguard Worker ForFile     rec   m<=N  [0, M) ... [N-M, N)      same as ForBoth-File
252*f6dc9357SAndroid Build Coastguard Worker ForDir   nonrec         [0, M)                   same as ForBoth-File
253*f6dc9357SAndroid Build Coastguard Worker 
254*f6dc9357SAndroid Build Coastguard Worker */
255*f6dc9357SAndroid Build Coastguard Worker 
AreAllAllowed() const256*f6dc9357SAndroid Build Coastguard Worker bool CItem::AreAllAllowed() const
257*f6dc9357SAndroid Build Coastguard Worker {
258*f6dc9357SAndroid Build Coastguard Worker   return ForFile && ForDir && WildcardMatching && PathParts.Size() == 1 && PathParts.Front() == L"*";
259*f6dc9357SAndroid Build Coastguard Worker }
260*f6dc9357SAndroid Build Coastguard Worker 
CheckPath(const UStringVector & pathParts,bool isFile) const261*f6dc9357SAndroid Build Coastguard Worker bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
262*f6dc9357SAndroid Build Coastguard Worker {
263*f6dc9357SAndroid Build Coastguard Worker   if (!isFile && !ForDir)
264*f6dc9357SAndroid Build Coastguard Worker     return false;
265*f6dc9357SAndroid Build Coastguard Worker 
266*f6dc9357SAndroid Build Coastguard Worker   /*
267*f6dc9357SAndroid Build Coastguard Worker   if (PathParts.IsEmpty())
268*f6dc9357SAndroid Build Coastguard Worker   {
269*f6dc9357SAndroid Build Coastguard Worker     // PathParts.IsEmpty() means all items (universal wildcard)
270*f6dc9357SAndroid Build Coastguard Worker     if (!isFile)
271*f6dc9357SAndroid Build Coastguard Worker       return true;
272*f6dc9357SAndroid Build Coastguard Worker     if (pathParts.Size() <= 1)
273*f6dc9357SAndroid Build Coastguard Worker       return ForFile;
274*f6dc9357SAndroid Build Coastguard Worker     return (ForDir || Recursive && ForFile);
275*f6dc9357SAndroid Build Coastguard Worker   }
276*f6dc9357SAndroid Build Coastguard Worker   */
277*f6dc9357SAndroid Build Coastguard Worker 
278*f6dc9357SAndroid Build Coastguard Worker   int delta = (int)pathParts.Size() - (int)PathParts.Size();
279*f6dc9357SAndroid Build Coastguard Worker   if (delta < 0)
280*f6dc9357SAndroid Build Coastguard Worker     return false;
281*f6dc9357SAndroid Build Coastguard Worker   int start = 0;
282*f6dc9357SAndroid Build Coastguard Worker   int finish = 0;
283*f6dc9357SAndroid Build Coastguard Worker 
284*f6dc9357SAndroid Build Coastguard Worker   if (isFile)
285*f6dc9357SAndroid Build Coastguard Worker   {
286*f6dc9357SAndroid Build Coastguard Worker     if (!ForDir)
287*f6dc9357SAndroid Build Coastguard Worker     {
288*f6dc9357SAndroid Build Coastguard Worker       if (Recursive)
289*f6dc9357SAndroid Build Coastguard Worker         start = delta;
290*f6dc9357SAndroid Build Coastguard Worker       else if (delta !=0)
291*f6dc9357SAndroid Build Coastguard Worker         return false;
292*f6dc9357SAndroid Build Coastguard Worker     }
293*f6dc9357SAndroid Build Coastguard Worker     if (!ForFile && delta == 0)
294*f6dc9357SAndroid Build Coastguard Worker       return false;
295*f6dc9357SAndroid Build Coastguard Worker   }
296*f6dc9357SAndroid Build Coastguard Worker 
297*f6dc9357SAndroid Build Coastguard Worker   if (Recursive)
298*f6dc9357SAndroid Build Coastguard Worker   {
299*f6dc9357SAndroid Build Coastguard Worker     finish = delta;
300*f6dc9357SAndroid Build Coastguard Worker     if (isFile && !ForFile)
301*f6dc9357SAndroid Build Coastguard Worker       finish = delta - 1;
302*f6dc9357SAndroid Build Coastguard Worker   }
303*f6dc9357SAndroid Build Coastguard Worker 
304*f6dc9357SAndroid Build Coastguard Worker   for (int d = start; d <= finish; d++)
305*f6dc9357SAndroid Build Coastguard Worker   {
306*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
307*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < PathParts.Size(); i++)
308*f6dc9357SAndroid Build Coastguard Worker     {
309*f6dc9357SAndroid Build Coastguard Worker       if (WildcardMatching)
310*f6dc9357SAndroid Build Coastguard Worker       {
311*f6dc9357SAndroid Build Coastguard Worker         if (!DoesWildcardMatchName(PathParts[i], pathParts[i + (unsigned)d]))
312*f6dc9357SAndroid Build Coastguard Worker           break;
313*f6dc9357SAndroid Build Coastguard Worker       }
314*f6dc9357SAndroid Build Coastguard Worker       else
315*f6dc9357SAndroid Build Coastguard Worker       {
316*f6dc9357SAndroid Build Coastguard Worker         if (CompareFileNames(PathParts[i], pathParts[i + (unsigned)d]) != 0)
317*f6dc9357SAndroid Build Coastguard Worker           break;
318*f6dc9357SAndroid Build Coastguard Worker       }
319*f6dc9357SAndroid Build Coastguard Worker     }
320*f6dc9357SAndroid Build Coastguard Worker     if (i == PathParts.Size())
321*f6dc9357SAndroid Build Coastguard Worker       return true;
322*f6dc9357SAndroid Build Coastguard Worker   }
323*f6dc9357SAndroid Build Coastguard Worker   return false;
324*f6dc9357SAndroid Build Coastguard Worker }
325*f6dc9357SAndroid Build Coastguard Worker 
AreAllAllowed() const326*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::AreAllAllowed() const
327*f6dc9357SAndroid Build Coastguard Worker {
328*f6dc9357SAndroid Build Coastguard Worker   if (!Name.IsEmpty() ||
329*f6dc9357SAndroid Build Coastguard Worker       !SubNodes.IsEmpty() ||
330*f6dc9357SAndroid Build Coastguard Worker       !ExcludeItems.IsEmpty() ||
331*f6dc9357SAndroid Build Coastguard Worker       IncludeItems.Size() != 1)
332*f6dc9357SAndroid Build Coastguard Worker     return false;
333*f6dc9357SAndroid Build Coastguard Worker   return IncludeItems.Front().AreAllAllowed();
334*f6dc9357SAndroid Build Coastguard Worker }
335*f6dc9357SAndroid Build Coastguard Worker 
FindSubNode(const UString & name) const336*f6dc9357SAndroid Build Coastguard Worker int CCensorNode::FindSubNode(const UString &name) const
337*f6dc9357SAndroid Build Coastguard Worker {
338*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, SubNodes)
339*f6dc9357SAndroid Build Coastguard Worker     if (CompareFileNames(SubNodes[i].Name, name) == 0)
340*f6dc9357SAndroid Build Coastguard Worker       return (int)i;
341*f6dc9357SAndroid Build Coastguard Worker   return -1;
342*f6dc9357SAndroid Build Coastguard Worker }
343*f6dc9357SAndroid Build Coastguard Worker 
AddItemSimple(bool include,CItem & item)344*f6dc9357SAndroid Build Coastguard Worker void CCensorNode::AddItemSimple(bool include, CItem &item)
345*f6dc9357SAndroid Build Coastguard Worker {
346*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
347*f6dc9357SAndroid Build Coastguard Worker   items.Add(item);
348*f6dc9357SAndroid Build Coastguard Worker }
349*f6dc9357SAndroid Build Coastguard Worker 
AddItem(bool include,CItem & item,int ignoreWildcardIndex)350*f6dc9357SAndroid Build Coastguard Worker void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex)
351*f6dc9357SAndroid Build Coastguard Worker {
352*f6dc9357SAndroid Build Coastguard Worker   if (item.PathParts.Size() <= 1)
353*f6dc9357SAndroid Build Coastguard Worker   {
354*f6dc9357SAndroid Build Coastguard Worker     if (item.PathParts.Size() != 0 && item.WildcardMatching)
355*f6dc9357SAndroid Build Coastguard Worker     {
356*f6dc9357SAndroid Build Coastguard Worker       if (!DoesNameContainWildcard(item.PathParts.Front()))
357*f6dc9357SAndroid Build Coastguard Worker         item.WildcardMatching = false;
358*f6dc9357SAndroid Build Coastguard Worker     }
359*f6dc9357SAndroid Build Coastguard Worker     AddItemSimple(include, item);
360*f6dc9357SAndroid Build Coastguard Worker     return;
361*f6dc9357SAndroid Build Coastguard Worker   }
362*f6dc9357SAndroid Build Coastguard Worker 
363*f6dc9357SAndroid Build Coastguard Worker   const UString &front = item.PathParts.Front();
364*f6dc9357SAndroid Build Coastguard Worker 
365*f6dc9357SAndroid Build Coastguard Worker   // WIN32 doesn't support wildcards in file names
366*f6dc9357SAndroid Build Coastguard Worker   if (item.WildcardMatching
367*f6dc9357SAndroid Build Coastguard Worker       && ignoreWildcardIndex != 0
368*f6dc9357SAndroid Build Coastguard Worker       && DoesNameContainWildcard(front))
369*f6dc9357SAndroid Build Coastguard Worker   {
370*f6dc9357SAndroid Build Coastguard Worker     AddItemSimple(include, item);
371*f6dc9357SAndroid Build Coastguard Worker     return;
372*f6dc9357SAndroid Build Coastguard Worker   }
373*f6dc9357SAndroid Build Coastguard Worker   CCensorNode &subNode = Find_SubNode_Or_Add_New(front);
374*f6dc9357SAndroid Build Coastguard Worker   item.PathParts.Delete(0);
375*f6dc9357SAndroid Build Coastguard Worker   subNode.AddItem(include, item, ignoreWildcardIndex - 1);
376*f6dc9357SAndroid Build Coastguard Worker }
377*f6dc9357SAndroid Build Coastguard Worker 
378*f6dc9357SAndroid Build Coastguard Worker /*
379*f6dc9357SAndroid Build Coastguard Worker void CCensorNode::AddItem(bool include, const UString &path, const CCensorPathProps &props)
380*f6dc9357SAndroid Build Coastguard Worker {
381*f6dc9357SAndroid Build Coastguard Worker   CItem item;
382*f6dc9357SAndroid Build Coastguard Worker   SplitPathToParts(path, item.PathParts);
383*f6dc9357SAndroid Build Coastguard Worker   item.Recursive = props.Recursive;
384*f6dc9357SAndroid Build Coastguard Worker   item.ForFile = props.ForFile;
385*f6dc9357SAndroid Build Coastguard Worker   item.ForDir = props.ForDir;
386*f6dc9357SAndroid Build Coastguard Worker   item.WildcardMatching = props.WildcardMatching;
387*f6dc9357SAndroid Build Coastguard Worker   AddItem(include, item);
388*f6dc9357SAndroid Build Coastguard Worker }
389*f6dc9357SAndroid Build Coastguard Worker */
390*f6dc9357SAndroid Build Coastguard Worker 
NeedCheckSubDirs() const391*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::NeedCheckSubDirs() const
392*f6dc9357SAndroid Build Coastguard Worker {
393*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, IncludeItems)
394*f6dc9357SAndroid Build Coastguard Worker   {
395*f6dc9357SAndroid Build Coastguard Worker     const CItem &item = IncludeItems[i];
396*f6dc9357SAndroid Build Coastguard Worker     if (item.Recursive || item.PathParts.Size() > 1)
397*f6dc9357SAndroid Build Coastguard Worker       return true;
398*f6dc9357SAndroid Build Coastguard Worker   }
399*f6dc9357SAndroid Build Coastguard Worker   return false;
400*f6dc9357SAndroid Build Coastguard Worker }
401*f6dc9357SAndroid Build Coastguard Worker 
AreThereIncludeItems() const402*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::AreThereIncludeItems() const
403*f6dc9357SAndroid Build Coastguard Worker {
404*f6dc9357SAndroid Build Coastguard Worker   if (IncludeItems.Size() > 0)
405*f6dc9357SAndroid Build Coastguard Worker     return true;
406*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, SubNodes)
407*f6dc9357SAndroid Build Coastguard Worker     if (SubNodes[i].AreThereIncludeItems())
408*f6dc9357SAndroid Build Coastguard Worker       return true;
409*f6dc9357SAndroid Build Coastguard Worker   return false;
410*f6dc9357SAndroid Build Coastguard Worker }
411*f6dc9357SAndroid Build Coastguard Worker 
CheckPathCurrent(bool include,const UStringVector & pathParts,bool isFile) const412*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
413*f6dc9357SAndroid Build Coastguard Worker {
414*f6dc9357SAndroid Build Coastguard Worker   const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
415*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, items)
416*f6dc9357SAndroid Build Coastguard Worker     if (items[i].CheckPath(pathParts, isFile))
417*f6dc9357SAndroid Build Coastguard Worker       return true;
418*f6dc9357SAndroid Build Coastguard Worker   return false;
419*f6dc9357SAndroid Build Coastguard Worker }
420*f6dc9357SAndroid Build Coastguard Worker 
CheckPathVect(const UStringVector & pathParts,bool isFile,bool & include) const421*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const
422*f6dc9357SAndroid Build Coastguard Worker {
423*f6dc9357SAndroid Build Coastguard Worker   if (CheckPathCurrent(false, pathParts, isFile))
424*f6dc9357SAndroid Build Coastguard Worker   {
425*f6dc9357SAndroid Build Coastguard Worker     include = false;
426*f6dc9357SAndroid Build Coastguard Worker     return true;
427*f6dc9357SAndroid Build Coastguard Worker   }
428*f6dc9357SAndroid Build Coastguard Worker   if (pathParts.Size() > 1)
429*f6dc9357SAndroid Build Coastguard Worker   {
430*f6dc9357SAndroid Build Coastguard Worker     int index = FindSubNode(pathParts.Front());
431*f6dc9357SAndroid Build Coastguard Worker     if (index >= 0)
432*f6dc9357SAndroid Build Coastguard Worker     {
433*f6dc9357SAndroid Build Coastguard Worker       UStringVector pathParts2 = pathParts;
434*f6dc9357SAndroid Build Coastguard Worker       pathParts2.Delete(0);
435*f6dc9357SAndroid Build Coastguard Worker       if (SubNodes[(unsigned)index].CheckPathVect(pathParts2, isFile, include))
436*f6dc9357SAndroid Build Coastguard Worker         return true;
437*f6dc9357SAndroid Build Coastguard Worker     }
438*f6dc9357SAndroid Build Coastguard Worker   }
439*f6dc9357SAndroid Build Coastguard Worker   bool finded = CheckPathCurrent(true, pathParts, isFile);
440*f6dc9357SAndroid Build Coastguard Worker   include = finded; // if (!finded), then (true) is allowed also
441*f6dc9357SAndroid Build Coastguard Worker   return finded;
442*f6dc9357SAndroid Build Coastguard Worker }
443*f6dc9357SAndroid Build Coastguard Worker 
444*f6dc9357SAndroid Build Coastguard Worker /*
445*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const
446*f6dc9357SAndroid Build Coastguard Worker {
447*f6dc9357SAndroid Build Coastguard Worker   UStringVector pathParts;
448*f6dc9357SAndroid Build Coastguard Worker   SplitPathToParts(path, pathParts);
449*f6dc9357SAndroid Build Coastguard Worker   if (CheckPathVect(pathParts, isFile, include))
450*f6dc9357SAndroid Build Coastguard Worker   {
451*f6dc9357SAndroid Build Coastguard Worker     if (!include || !isAltStream)
452*f6dc9357SAndroid Build Coastguard Worker       return true;
453*f6dc9357SAndroid Build Coastguard Worker   }
454*f6dc9357SAndroid Build Coastguard Worker   if (isAltStream && !pathParts.IsEmpty())
455*f6dc9357SAndroid Build Coastguard Worker   {
456*f6dc9357SAndroid Build Coastguard Worker     UString &back = pathParts.Back();
457*f6dc9357SAndroid Build Coastguard Worker     int pos = back.Find(L':');
458*f6dc9357SAndroid Build Coastguard Worker     if (pos > 0)
459*f6dc9357SAndroid Build Coastguard Worker     {
460*f6dc9357SAndroid Build Coastguard Worker       back.DeleteFrom(pos);
461*f6dc9357SAndroid Build Coastguard Worker       return CheckPathVect(pathParts, isFile, include);
462*f6dc9357SAndroid Build Coastguard Worker     }
463*f6dc9357SAndroid Build Coastguard Worker   }
464*f6dc9357SAndroid Build Coastguard Worker   return false;
465*f6dc9357SAndroid Build Coastguard Worker }
466*f6dc9357SAndroid Build Coastguard Worker 
467*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const
468*f6dc9357SAndroid Build Coastguard Worker {
469*f6dc9357SAndroid Build Coastguard Worker   bool include;
470*f6dc9357SAndroid Build Coastguard Worker   if (CheckPath2(isAltStream, path, isFile, include))
471*f6dc9357SAndroid Build Coastguard Worker     return include;
472*f6dc9357SAndroid Build Coastguard Worker   return false;
473*f6dc9357SAndroid Build Coastguard Worker }
474*f6dc9357SAndroid Build Coastguard Worker */
475*f6dc9357SAndroid Build Coastguard Worker 
CheckPathToRoot_Change(bool include,UStringVector & pathParts,bool isFile) const476*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::CheckPathToRoot_Change(bool include, UStringVector &pathParts, bool isFile) const
477*f6dc9357SAndroid Build Coastguard Worker {
478*f6dc9357SAndroid Build Coastguard Worker   if (CheckPathCurrent(include, pathParts, isFile))
479*f6dc9357SAndroid Build Coastguard Worker     return true;
480*f6dc9357SAndroid Build Coastguard Worker   if (!Parent)
481*f6dc9357SAndroid Build Coastguard Worker     return false;
482*f6dc9357SAndroid Build Coastguard Worker   pathParts.Insert(0, Name);
483*f6dc9357SAndroid Build Coastguard Worker   return Parent->CheckPathToRoot_Change(include, pathParts, isFile);
484*f6dc9357SAndroid Build Coastguard Worker }
485*f6dc9357SAndroid Build Coastguard Worker 
CheckPathToRoot(bool include,const UStringVector & pathParts,bool isFile) const486*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::CheckPathToRoot(bool include, const UStringVector &pathParts, bool isFile) const
487*f6dc9357SAndroid Build Coastguard Worker {
488*f6dc9357SAndroid Build Coastguard Worker   if (CheckPathCurrent(include, pathParts, isFile))
489*f6dc9357SAndroid Build Coastguard Worker     return true;
490*f6dc9357SAndroid Build Coastguard Worker   if (!Parent)
491*f6dc9357SAndroid Build Coastguard Worker     return false;
492*f6dc9357SAndroid Build Coastguard Worker   UStringVector pathParts2;
493*f6dc9357SAndroid Build Coastguard Worker   pathParts2.Add(Name);
494*f6dc9357SAndroid Build Coastguard Worker   pathParts2 += pathParts;
495*f6dc9357SAndroid Build Coastguard Worker   return Parent->CheckPathToRoot_Change(include, pathParts2, isFile);
496*f6dc9357SAndroid Build Coastguard Worker }
497*f6dc9357SAndroid Build Coastguard Worker 
498*f6dc9357SAndroid Build Coastguard Worker /*
499*f6dc9357SAndroid Build Coastguard Worker bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const
500*f6dc9357SAndroid Build Coastguard Worker {
501*f6dc9357SAndroid Build Coastguard Worker   UStringVector pathParts;
502*f6dc9357SAndroid Build Coastguard Worker   SplitPathToParts(path, pathParts);
503*f6dc9357SAndroid Build Coastguard Worker   return CheckPathToRoot(include, pathParts, isFile);
504*f6dc9357SAndroid Build Coastguard Worker }
505*f6dc9357SAndroid Build Coastguard Worker */
506*f6dc9357SAndroid Build Coastguard Worker 
ExtendExclude(const CCensorNode & fromNodes)507*f6dc9357SAndroid Build Coastguard Worker void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
508*f6dc9357SAndroid Build Coastguard Worker {
509*f6dc9357SAndroid Build Coastguard Worker   ExcludeItems += fromNodes.ExcludeItems;
510*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, fromNodes.SubNodes)
511*f6dc9357SAndroid Build Coastguard Worker   {
512*f6dc9357SAndroid Build Coastguard Worker     const CCensorNode &node = fromNodes.SubNodes[i];
513*f6dc9357SAndroid Build Coastguard Worker     Find_SubNode_Or_Add_New(node.Name).ExtendExclude(node);
514*f6dc9357SAndroid Build Coastguard Worker   }
515*f6dc9357SAndroid Build Coastguard Worker }
516*f6dc9357SAndroid Build Coastguard Worker 
FindPairForPrefix(const UString & prefix) const517*f6dc9357SAndroid Build Coastguard Worker int CCensor::FindPairForPrefix(const UString &prefix) const
518*f6dc9357SAndroid Build Coastguard Worker {
519*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, Pairs)
520*f6dc9357SAndroid Build Coastguard Worker     if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
521*f6dc9357SAndroid Build Coastguard Worker       return (int)i;
522*f6dc9357SAndroid Build Coastguard Worker   return -1;
523*f6dc9357SAndroid Build Coastguard Worker }
524*f6dc9357SAndroid Build Coastguard Worker 
525*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
526*f6dc9357SAndroid Build Coastguard Worker 
IsDriveColonName(const wchar_t * s)527*f6dc9357SAndroid Build Coastguard Worker bool IsDriveColonName(const wchar_t *s)
528*f6dc9357SAndroid Build Coastguard Worker {
529*f6dc9357SAndroid Build Coastguard Worker   unsigned c = s[0];
530*f6dc9357SAndroid Build Coastguard Worker   c |= 0x20;
531*f6dc9357SAndroid Build Coastguard Worker   c -= 'a';
532*f6dc9357SAndroid Build Coastguard Worker   return c <= (unsigned)('z' - 'a') && s[1] == ':' && s[2] == 0;
533*f6dc9357SAndroid Build Coastguard Worker }
534*f6dc9357SAndroid Build Coastguard Worker 
GetNumPrefixParts_if_DrivePath(UStringVector & pathParts)535*f6dc9357SAndroid Build Coastguard Worker unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts)
536*f6dc9357SAndroid Build Coastguard Worker {
537*f6dc9357SAndroid Build Coastguard Worker   if (pathParts.IsEmpty())
538*f6dc9357SAndroid Build Coastguard Worker     return 0;
539*f6dc9357SAndroid Build Coastguard Worker 
540*f6dc9357SAndroid Build Coastguard Worker   unsigned testIndex = 0;
541*f6dc9357SAndroid Build Coastguard Worker   if (pathParts[0].IsEmpty())
542*f6dc9357SAndroid Build Coastguard Worker   {
543*f6dc9357SAndroid Build Coastguard Worker     if (pathParts.Size() < 4
544*f6dc9357SAndroid Build Coastguard Worker         || !pathParts[1].IsEmpty()
545*f6dc9357SAndroid Build Coastguard Worker         || pathParts[2] != L"?")
546*f6dc9357SAndroid Build Coastguard Worker       return 0;
547*f6dc9357SAndroid Build Coastguard Worker     testIndex = 3;
548*f6dc9357SAndroid Build Coastguard Worker   }
549*f6dc9357SAndroid Build Coastguard Worker   if (NWildcard::IsDriveColonName(pathParts[testIndex]))
550*f6dc9357SAndroid Build Coastguard Worker     return testIndex + 1;
551*f6dc9357SAndroid Build Coastguard Worker   return 0;
552*f6dc9357SAndroid Build Coastguard Worker }
553*f6dc9357SAndroid Build Coastguard Worker 
554*f6dc9357SAndroid Build Coastguard Worker #endif
555*f6dc9357SAndroid Build Coastguard Worker 
GetNumPrefixParts(const UStringVector & pathParts)556*f6dc9357SAndroid Build Coastguard Worker static unsigned GetNumPrefixParts(const UStringVector &pathParts)
557*f6dc9357SAndroid Build Coastguard Worker {
558*f6dc9357SAndroid Build Coastguard Worker   if (pathParts.IsEmpty())
559*f6dc9357SAndroid Build Coastguard Worker     return 0;
560*f6dc9357SAndroid Build Coastguard Worker 
561*f6dc9357SAndroid Build Coastguard Worker   /* empty last part could be removed already from (pathParts),
562*f6dc9357SAndroid Build Coastguard Worker      if there was tail path separator (slash) in original full path string. */
563*f6dc9357SAndroid Build Coastguard Worker 
564*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
565*f6dc9357SAndroid Build Coastguard Worker 
566*f6dc9357SAndroid Build Coastguard Worker   if (IsDriveColonName(pathParts[0]))
567*f6dc9357SAndroid Build Coastguard Worker     return 1;
568*f6dc9357SAndroid Build Coastguard Worker   if (!pathParts[0].IsEmpty())
569*f6dc9357SAndroid Build Coastguard Worker     return 0;
570*f6dc9357SAndroid Build Coastguard Worker 
571*f6dc9357SAndroid Build Coastguard Worker   if (pathParts.Size() == 1)
572*f6dc9357SAndroid Build Coastguard Worker     return 1;
573*f6dc9357SAndroid Build Coastguard Worker   if (!pathParts[1].IsEmpty())
574*f6dc9357SAndroid Build Coastguard Worker     return 1;
575*f6dc9357SAndroid Build Coastguard Worker   if (pathParts.Size() == 2)
576*f6dc9357SAndroid Build Coastguard Worker     return 2;
577*f6dc9357SAndroid Build Coastguard Worker   if (pathParts[2] == L".")
578*f6dc9357SAndroid Build Coastguard Worker     return 3;
579*f6dc9357SAndroid Build Coastguard Worker 
580*f6dc9357SAndroid Build Coastguard Worker   unsigned networkParts = 2;
581*f6dc9357SAndroid Build Coastguard Worker   if (pathParts[2] == L"?")
582*f6dc9357SAndroid Build Coastguard Worker   {
583*f6dc9357SAndroid Build Coastguard Worker     if (pathParts.Size() == 3)
584*f6dc9357SAndroid Build Coastguard Worker       return 3;
585*f6dc9357SAndroid Build Coastguard Worker     if (IsDriveColonName(pathParts[3]))
586*f6dc9357SAndroid Build Coastguard Worker       return 4;
587*f6dc9357SAndroid Build Coastguard Worker     if (!pathParts[3].IsEqualTo_Ascii_NoCase("UNC"))
588*f6dc9357SAndroid Build Coastguard Worker       return 3;
589*f6dc9357SAndroid Build Coastguard Worker     networkParts = 4;
590*f6dc9357SAndroid Build Coastguard Worker   }
591*f6dc9357SAndroid Build Coastguard Worker 
592*f6dc9357SAndroid Build Coastguard Worker   networkParts +=
593*f6dc9357SAndroid Build Coastguard Worker       // 2; // server/share
594*f6dc9357SAndroid Build Coastguard Worker       1; // server
595*f6dc9357SAndroid Build Coastguard Worker   if (pathParts.Size() <= networkParts)
596*f6dc9357SAndroid Build Coastguard Worker     return pathParts.Size();
597*f6dc9357SAndroid Build Coastguard Worker   return networkParts;
598*f6dc9357SAndroid Build Coastguard Worker 
599*f6dc9357SAndroid Build Coastguard Worker   #else
600*f6dc9357SAndroid Build Coastguard Worker 
601*f6dc9357SAndroid Build Coastguard Worker   return pathParts[0].IsEmpty() ? 1 : 0;
602*f6dc9357SAndroid Build Coastguard Worker 
603*f6dc9357SAndroid Build Coastguard Worker   #endif
604*f6dc9357SAndroid Build Coastguard Worker }
605*f6dc9357SAndroid Build Coastguard Worker 
AddItem(ECensorPathMode pathMode,bool include,const UString & path,const CCensorPathProps & props)606*f6dc9357SAndroid Build Coastguard Worker void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path,
607*f6dc9357SAndroid Build Coastguard Worker     const CCensorPathProps &props)
608*f6dc9357SAndroid Build Coastguard Worker {
609*f6dc9357SAndroid Build Coastguard Worker   if (path.IsEmpty())
610*f6dc9357SAndroid Build Coastguard Worker     throw "Empty file path";
611*f6dc9357SAndroid Build Coastguard Worker 
612*f6dc9357SAndroid Build Coastguard Worker   UStringVector pathParts;
613*f6dc9357SAndroid Build Coastguard Worker   SplitPathToParts(path, pathParts);
614*f6dc9357SAndroid Build Coastguard Worker 
615*f6dc9357SAndroid Build Coastguard Worker   CCensorPathProps props2 = props;
616*f6dc9357SAndroid Build Coastguard Worker 
617*f6dc9357SAndroid Build Coastguard Worker   bool forFile = true;
618*f6dc9357SAndroid Build Coastguard Worker   bool forDir = true;
619*f6dc9357SAndroid Build Coastguard Worker   const UString &back = pathParts.Back();
620*f6dc9357SAndroid Build Coastguard Worker   if (back.IsEmpty())
621*f6dc9357SAndroid Build Coastguard Worker   {
622*f6dc9357SAndroid Build Coastguard Worker     // we have tail path separator. So it's directory.
623*f6dc9357SAndroid Build Coastguard Worker     // we delete tail path separator here even for "\" and "c:\"
624*f6dc9357SAndroid Build Coastguard Worker     forFile = false;
625*f6dc9357SAndroid Build Coastguard Worker     pathParts.DeleteBack();
626*f6dc9357SAndroid Build Coastguard Worker   }
627*f6dc9357SAndroid Build Coastguard Worker   else
628*f6dc9357SAndroid Build Coastguard Worker   {
629*f6dc9357SAndroid Build Coastguard Worker     if (props.MarkMode == kMark_StrictFile
630*f6dc9357SAndroid Build Coastguard Worker         || (props.MarkMode == kMark_StrictFile_IfWildcard
631*f6dc9357SAndroid Build Coastguard Worker             && DoesNameContainWildcard(back)))
632*f6dc9357SAndroid Build Coastguard Worker       forDir = false;
633*f6dc9357SAndroid Build Coastguard Worker   }
634*f6dc9357SAndroid Build Coastguard Worker 
635*f6dc9357SAndroid Build Coastguard Worker 
636*f6dc9357SAndroid Build Coastguard Worker   UString prefix;
637*f6dc9357SAndroid Build Coastguard Worker 
638*f6dc9357SAndroid Build Coastguard Worker   int ignoreWildcardIndex = -1;
639*f6dc9357SAndroid Build Coastguard Worker 
640*f6dc9357SAndroid Build Coastguard Worker   // #ifdef _WIN32
641*f6dc9357SAndroid Build Coastguard Worker   // we ignore "?" wildcard in "\\?\" prefix.
642*f6dc9357SAndroid Build Coastguard Worker   if (pathParts.Size() >= 3
643*f6dc9357SAndroid Build Coastguard Worker       && pathParts[0].IsEmpty()
644*f6dc9357SAndroid Build Coastguard Worker       && pathParts[1].IsEmpty()
645*f6dc9357SAndroid Build Coastguard Worker       && pathParts[2] == L"?")
646*f6dc9357SAndroid Build Coastguard Worker     ignoreWildcardIndex = 2;
647*f6dc9357SAndroid Build Coastguard Worker   // #endif
648*f6dc9357SAndroid Build Coastguard Worker 
649*f6dc9357SAndroid Build Coastguard Worker   if (pathMode != k_AbsPath)
650*f6dc9357SAndroid Build Coastguard Worker   {
651*f6dc9357SAndroid Build Coastguard Worker     // detection of the number of Skip Parts for prefix
652*f6dc9357SAndroid Build Coastguard Worker     ignoreWildcardIndex = -1;
653*f6dc9357SAndroid Build Coastguard Worker 
654*f6dc9357SAndroid Build Coastguard Worker     const unsigned numPrefixParts = GetNumPrefixParts(pathParts);
655*f6dc9357SAndroid Build Coastguard Worker     unsigned numSkipParts = numPrefixParts;
656*f6dc9357SAndroid Build Coastguard Worker 
657*f6dc9357SAndroid Build Coastguard Worker     if (pathMode != k_FullPath)
658*f6dc9357SAndroid Build Coastguard Worker     {
659*f6dc9357SAndroid Build Coastguard Worker       // if absolute path, then all parts before last part will be in prefix
660*f6dc9357SAndroid Build Coastguard Worker       if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts)
661*f6dc9357SAndroid Build Coastguard Worker         numSkipParts = pathParts.Size() - 1;
662*f6dc9357SAndroid Build Coastguard Worker     }
663*f6dc9357SAndroid Build Coastguard Worker     {
664*f6dc9357SAndroid Build Coastguard Worker       int dotsIndex = -1;
665*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = numPrefixParts; i < pathParts.Size(); i++)
666*f6dc9357SAndroid Build Coastguard Worker       {
667*f6dc9357SAndroid Build Coastguard Worker         const UString &part = pathParts[i];
668*f6dc9357SAndroid Build Coastguard Worker         if (part == L".." || part == L".")
669*f6dc9357SAndroid Build Coastguard Worker           dotsIndex = (int)i;
670*f6dc9357SAndroid Build Coastguard Worker       }
671*f6dc9357SAndroid Build Coastguard Worker 
672*f6dc9357SAndroid Build Coastguard Worker       if (dotsIndex >= 0)
673*f6dc9357SAndroid Build Coastguard Worker       {
674*f6dc9357SAndroid Build Coastguard Worker         if (dotsIndex == (int)pathParts.Size() - 1)
675*f6dc9357SAndroid Build Coastguard Worker           numSkipParts = pathParts.Size();
676*f6dc9357SAndroid Build Coastguard Worker         else
677*f6dc9357SAndroid Build Coastguard Worker           numSkipParts = pathParts.Size() - 1;
678*f6dc9357SAndroid Build Coastguard Worker       }
679*f6dc9357SAndroid Build Coastguard Worker     }
680*f6dc9357SAndroid Build Coastguard Worker 
681*f6dc9357SAndroid Build Coastguard Worker     // we split (pathParts) to (prefix) and (pathParts).
682*f6dc9357SAndroid Build Coastguard Worker     for (unsigned i = 0; i < numSkipParts; i++)
683*f6dc9357SAndroid Build Coastguard Worker     {
684*f6dc9357SAndroid Build Coastguard Worker       {
685*f6dc9357SAndroid Build Coastguard Worker         const UString &front = pathParts.Front();
686*f6dc9357SAndroid Build Coastguard Worker         // WIN32 doesn't support wildcards in file names
687*f6dc9357SAndroid Build Coastguard Worker         if (props.WildcardMatching)
688*f6dc9357SAndroid Build Coastguard Worker           if (i >= numPrefixParts && DoesNameContainWildcard(front))
689*f6dc9357SAndroid Build Coastguard Worker             break;
690*f6dc9357SAndroid Build Coastguard Worker         prefix += front;
691*f6dc9357SAndroid Build Coastguard Worker         prefix.Add_PathSepar();
692*f6dc9357SAndroid Build Coastguard Worker       }
693*f6dc9357SAndroid Build Coastguard Worker       pathParts.Delete(0);
694*f6dc9357SAndroid Build Coastguard Worker     }
695*f6dc9357SAndroid Build Coastguard Worker   }
696*f6dc9357SAndroid Build Coastguard Worker 
697*f6dc9357SAndroid Build Coastguard Worker   int index = FindPairForPrefix(prefix);
698*f6dc9357SAndroid Build Coastguard Worker   if (index < 0)
699*f6dc9357SAndroid Build Coastguard Worker   {
700*f6dc9357SAndroid Build Coastguard Worker     index = (int)Pairs.Size();
701*f6dc9357SAndroid Build Coastguard Worker     Pairs.AddNew().Prefix = prefix;
702*f6dc9357SAndroid Build Coastguard Worker   }
703*f6dc9357SAndroid Build Coastguard Worker 
704*f6dc9357SAndroid Build Coastguard Worker   if (pathMode != k_AbsPath)
705*f6dc9357SAndroid Build Coastguard Worker   {
706*f6dc9357SAndroid Build Coastguard Worker     if (pathParts.IsEmpty() || (pathParts.Size() == 1 && pathParts[0].IsEmpty()))
707*f6dc9357SAndroid Build Coastguard Worker     {
708*f6dc9357SAndroid Build Coastguard Worker       // we create universal item, if we skip all parts as prefix (like \ or L:\ )
709*f6dc9357SAndroid Build Coastguard Worker       pathParts.Clear();
710*f6dc9357SAndroid Build Coastguard Worker       pathParts.Add(UString("*"));
711*f6dc9357SAndroid Build Coastguard Worker       forFile = true;
712*f6dc9357SAndroid Build Coastguard Worker       forDir = true;
713*f6dc9357SAndroid Build Coastguard Worker       props2.WildcardMatching = true;
714*f6dc9357SAndroid Build Coastguard Worker       props2.Recursive = false;
715*f6dc9357SAndroid Build Coastguard Worker     }
716*f6dc9357SAndroid Build Coastguard Worker   }
717*f6dc9357SAndroid Build Coastguard Worker 
718*f6dc9357SAndroid Build Coastguard Worker   /*
719*f6dc9357SAndroid Build Coastguard Worker   // not possible now
720*f6dc9357SAndroid Build Coastguard Worker   if (!forDir && !forFile)
721*f6dc9357SAndroid Build Coastguard Worker   {
722*f6dc9357SAndroid Build Coastguard Worker     UString s ("file path was blocked for files and directories: ");
723*f6dc9357SAndroid Build Coastguard Worker     s += path;
724*f6dc9357SAndroid Build Coastguard Worker     throw s;
725*f6dc9357SAndroid Build Coastguard Worker     // return; // for debug : ignore item (don't create Item)
726*f6dc9357SAndroid Build Coastguard Worker   }
727*f6dc9357SAndroid Build Coastguard Worker   */
728*f6dc9357SAndroid Build Coastguard Worker 
729*f6dc9357SAndroid Build Coastguard Worker   CItem item;
730*f6dc9357SAndroid Build Coastguard Worker   item.PathParts = pathParts;
731*f6dc9357SAndroid Build Coastguard Worker   item.ForDir = forDir;
732*f6dc9357SAndroid Build Coastguard Worker   item.ForFile = forFile;
733*f6dc9357SAndroid Build Coastguard Worker   item.Recursive = props2.Recursive;
734*f6dc9357SAndroid Build Coastguard Worker   item.WildcardMatching = props2.WildcardMatching;
735*f6dc9357SAndroid Build Coastguard Worker   Pairs[(unsigned)index].Head.AddItem(include, item, ignoreWildcardIndex);
736*f6dc9357SAndroid Build Coastguard Worker }
737*f6dc9357SAndroid Build Coastguard Worker 
738*f6dc9357SAndroid Build Coastguard Worker /*
739*f6dc9357SAndroid Build Coastguard Worker bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const
740*f6dc9357SAndroid Build Coastguard Worker {
741*f6dc9357SAndroid Build Coastguard Worker   bool finded = false;
742*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR (i, Pairs)
743*f6dc9357SAndroid Build Coastguard Worker   {
744*f6dc9357SAndroid Build Coastguard Worker     bool include;
745*f6dc9357SAndroid Build Coastguard Worker     if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include))
746*f6dc9357SAndroid Build Coastguard Worker     {
747*f6dc9357SAndroid Build Coastguard Worker       if (!include)
748*f6dc9357SAndroid Build Coastguard Worker         return false;
749*f6dc9357SAndroid Build Coastguard Worker       finded = true;
750*f6dc9357SAndroid Build Coastguard Worker     }
751*f6dc9357SAndroid Build Coastguard Worker   }
752*f6dc9357SAndroid Build Coastguard Worker   return finded;
753*f6dc9357SAndroid Build Coastguard Worker }
754*f6dc9357SAndroid Build Coastguard Worker */
755*f6dc9357SAndroid Build Coastguard Worker 
ExtendExclude()756*f6dc9357SAndroid Build Coastguard Worker void CCensor::ExtendExclude()
757*f6dc9357SAndroid Build Coastguard Worker {
758*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
759*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < Pairs.Size(); i++)
760*f6dc9357SAndroid Build Coastguard Worker     if (Pairs[i].Prefix.IsEmpty())
761*f6dc9357SAndroid Build Coastguard Worker       break;
762*f6dc9357SAndroid Build Coastguard Worker   if (i == Pairs.Size())
763*f6dc9357SAndroid Build Coastguard Worker     return;
764*f6dc9357SAndroid Build Coastguard Worker   unsigned index = i;
765*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < Pairs.Size(); i++)
766*f6dc9357SAndroid Build Coastguard Worker     if (index != i)
767*f6dc9357SAndroid Build Coastguard Worker       Pairs[i].Head.ExtendExclude(Pairs[index].Head);
768*f6dc9357SAndroid Build Coastguard Worker }
769*f6dc9357SAndroid Build Coastguard Worker 
AddPathsToCensor(ECensorPathMode censorPathMode)770*f6dc9357SAndroid Build Coastguard Worker void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode)
771*f6dc9357SAndroid Build Coastguard Worker {
772*f6dc9357SAndroid Build Coastguard Worker   FOR_VECTOR(i, CensorPaths)
773*f6dc9357SAndroid Build Coastguard Worker   {
774*f6dc9357SAndroid Build Coastguard Worker     const CCensorPath &cp = CensorPaths[i];
775*f6dc9357SAndroid Build Coastguard Worker     AddItem(censorPathMode, cp.Include, cp.Path, cp.Props);
776*f6dc9357SAndroid Build Coastguard Worker   }
777*f6dc9357SAndroid Build Coastguard Worker   CensorPaths.Clear();
778*f6dc9357SAndroid Build Coastguard Worker }
779*f6dc9357SAndroid Build Coastguard Worker 
AddPreItem(bool include,const UString & path,const CCensorPathProps & props)780*f6dc9357SAndroid Build Coastguard Worker void CCensor::AddPreItem(bool include, const UString &path, const CCensorPathProps &props)
781*f6dc9357SAndroid Build Coastguard Worker {
782*f6dc9357SAndroid Build Coastguard Worker   CCensorPath &cp = CensorPaths.AddNew();
783*f6dc9357SAndroid Build Coastguard Worker   cp.Path = path;
784*f6dc9357SAndroid Build Coastguard Worker   cp.Include = include;
785*f6dc9357SAndroid Build Coastguard Worker   cp.Props = props;
786*f6dc9357SAndroid Build Coastguard Worker }
787*f6dc9357SAndroid Build Coastguard Worker 
788*f6dc9357SAndroid Build Coastguard Worker }
789