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