| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- // Common/Wildcard.cpp
- #include "StdAfx.h"
- #include "Wildcard.h"
- bool g_CaseSensitive =
- #ifdef _WIN32
- false;
- #else
- true;
- #endif
- static const wchar_t kAnyCharsChar = L'*';
- static const wchar_t kAnyCharChar = L'?';
- #ifdef _WIN32
- static const wchar_t kDirDelimiter1 = L'\\';
- #endif
- static const wchar_t kDirDelimiter2 = L'/';
- static const UString kWildCardCharSet = L"?*";
- static const UString kIllegalWildCardFileNameChars=
- L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"
- L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
- L"\"/:<>\\|";
- static inline bool IsCharDirLimiter(wchar_t c)
- {
- return (
- #ifdef _WIN32
- c == kDirDelimiter1 ||
- #endif
- c == kDirDelimiter2);
- }
- int CompareFileNames(const UString &s1, const UString &s2)
- {
- if (g_CaseSensitive)
- return s1.Compare(s2);
- return s1.CompareNoCase(s2);
- }
- // -----------------------------------------
- // this function compares name with mask
- // ? - any char
- // * - any char or empty
- static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
- {
- for (;;)
- {
- wchar_t m = *mask;
- wchar_t c = *name;
- if (m == 0)
- return (c == 0);
- if (m == kAnyCharsChar)
- {
- if (EnhancedMaskTest(mask + 1, name))
- return true;
- if (c == 0)
- return false;
- }
- else
- {
- if (m == kAnyCharChar)
- {
- if (c == 0)
- return false;
- }
- else if (m != c)
- if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c))
- return false;
- mask++;
- }
- name++;
- }
- }
- // --------------------------------------------------
- // Splits path to strings
- void SplitPathToParts(const UString &path, UStringVector &pathParts)
- {
- pathParts.Clear();
- UString name;
- int len = path.Length();
- if (len == 0)
- return;
- for (int i = 0; i < len; i++)
- {
- wchar_t c = path[i];
- if (IsCharDirLimiter(c))
- {
- pathParts.Add(name);
- name.Empty();
- }
- else
- name += c;
- }
- pathParts.Add(name);
- }
- void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name)
- {
- int i;
- for(i = path.Length() - 1; i >= 0; i--)
- if(IsCharDirLimiter(path[i]))
- break;
- dirPrefix = path.Left(i + 1);
- name = path.Mid(i + 1);
- }
- UString ExtractDirPrefixFromPath(const UString &path)
- {
- int i;
- for(i = path.Length() - 1; i >= 0; i--)
- if(IsCharDirLimiter(path[i]))
- break;
- return path.Left(i + 1);
- }
- UString ExtractFileNameFromPath(const UString &path)
- {
- int i;
- for(i = path.Length() - 1; i >= 0; i--)
- if(IsCharDirLimiter(path[i]))
- break;
- return path.Mid(i + 1);
- }
- bool CompareWildCardWithName(const UString &mask, const UString &name)
- {
- return EnhancedMaskTest(mask, name);
- }
- bool DoesNameContainWildCard(const UString &path)
- {
- return (path.FindOneOf(kWildCardCharSet) >= 0);
- }
- // ----------------------------------------------------------'
- // NWildcard
- namespace NWildcard {
- /*
- M = MaskParts.Size();
- N = TestNameParts.Size();
- File Dir
- ForFile req M<=N [N-M, N) -
- nonreq M=N [0, M) -
-
- ForDir req M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
- nonreq [0, M) same as ForBoth-File
- ForBoth req m<=N [0, M) ... [N-M, N) same as ForBoth-File
- nonreq [0, M) same as ForBoth-File
- */
- bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
- {
- if (!isFile && !ForDir)
- return false;
- int delta = (int)pathParts.Size() - (int)PathParts.Size();
- if (delta < 0)
- return false;
- int start = 0;
- int finish = 0;
- if (isFile)
- {
- if (!ForDir && !Recursive && delta !=0)
- return false;
- if (!ForFile && delta == 0)
- return false;
- if (!ForDir && Recursive)
- start = delta;
- }
- if (Recursive)
- {
- finish = delta;
- if (isFile && !ForFile)
- finish = delta - 1;
- }
- for (int d = start; d <= finish; d++)
- {
- int i;
- for (i = 0; i < PathParts.Size(); i++)
- if (!CompareWildCardWithName(PathParts[i], pathParts[i + d]))
- break;
- if (i == PathParts.Size())
- return true;
- }
- return false;
- }
- int CCensorNode::FindSubNode(const UString &name) const
- {
- for (int i = 0; i < SubNodes.Size(); i++)
- if (CompareFileNames(SubNodes[i].Name, name) == 0)
- return i;
- return -1;
- }
- void CCensorNode::AddItemSimple(bool include, CItem &item)
- {
- if (include)
- IncludeItems.Add(item);
- else
- ExcludeItems.Add(item);
- }
- void CCensorNode::AddItem(bool include, CItem &item)
- {
- if (item.PathParts.Size() <= 1)
- {
- AddItemSimple(include, item);
- return;
- }
- const UString &front = item.PathParts.Front();
- if (DoesNameContainWildCard(front))
- {
- AddItemSimple(include, item);
- return;
- }
- int index = FindSubNode(front);
- if (index < 0)
- index = SubNodes.Add(CCensorNode(front, this));
- item.PathParts.Delete(0);
- SubNodes[index].AddItem(include, item);
- }
- void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir)
- {
- CItem item;
- SplitPathToParts(path, item.PathParts);
- item.Recursive = recursive;
- item.ForFile = forFile;
- item.ForDir = forDir;
- AddItem(include, item);
- }
- bool CCensorNode::NeedCheckSubDirs() const
- {
- for (int i = 0; i < IncludeItems.Size(); i++)
- {
- const CItem &item = IncludeItems[i];
- if (item.Recursive || item.PathParts.Size() > 1)
- return true;
- }
- return false;
- }
- bool CCensorNode::AreThereIncludeItems() const
- {
- if (IncludeItems.Size() > 0)
- return true;
- for (int i = 0; i < SubNodes.Size(); i++)
- if (SubNodes[i].AreThereIncludeItems())
- return true;
- return false;
- }
- bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
- {
- const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
- for (int i = 0; i < items.Size(); i++)
- if (items[i].CheckPath(pathParts, isFile))
- return true;
- return false;
- }
- bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const
- {
- if (CheckPathCurrent(false, pathParts, isFile))
- {
- include = false;
- return true;
- }
- include = true;
- bool finded = CheckPathCurrent(true, pathParts, isFile);
- if (pathParts.Size() == 1)
- return finded;
- int index = FindSubNode(pathParts.Front());
- if (index >= 0)
- {
- UStringVector pathParts2 = pathParts;
- pathParts2.Delete(0);
- if (SubNodes[index].CheckPath(pathParts2, isFile, include))
- return true;
- }
- return finded;
- }
- bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const
- {
- UStringVector pathParts;
- SplitPathToParts(path, pathParts);
- return CheckPath(pathParts, isFile, include);
- }
- bool CCensorNode::CheckPath(const UString &path, bool isFile) const
- {
- bool include;
- if(CheckPath(path, isFile, include))
- return include;
- return false;
- }
- bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
- {
- if (CheckPathCurrent(include, pathParts, isFile))
- return true;
- if (Parent == 0)
- return false;
- pathParts.Insert(0, Name);
- return Parent->CheckPathToRoot(include, pathParts, isFile);
- }
- /*
- bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const
- {
- UStringVector pathParts;
- SplitPathToParts(path, pathParts);
- return CheckPathToRoot(include, pathParts, isFile);
- }
- */
- void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
- {
- if (path.IsEmpty())
- return;
- bool forFile = true;
- bool forFolder = true;
- UString path2 = path;
- if (IsCharDirLimiter(path[path.Length() - 1]))
- {
- path2.Delete(path.Length() - 1);
- forFile = false;
- }
- AddItem(include, path2, recursive, forFile, forFolder);
- }
- void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
- {
- ExcludeItems += fromNodes.ExcludeItems;
- for (int i = 0; i < fromNodes.SubNodes.Size(); i++)
- {
- const CCensorNode &node = fromNodes.SubNodes[i];
- int subNodeIndex = FindSubNode(node.Name);
- if (subNodeIndex < 0)
- subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this));
- SubNodes[subNodeIndex].ExtendExclude(node);
- }
- }
- int CCensor::FindPrefix(const UString &prefix) const
- {
- for (int i = 0; i < Pairs.Size(); i++)
- if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
- return i;
- return -1;
- }
- void CCensor::AddItem(bool include, const UString &path, bool recursive)
- {
- UStringVector pathParts;
- SplitPathToParts(path, pathParts);
- bool forFile = true;
- if (pathParts.Back().IsEmpty())
- {
- forFile = false;
- pathParts.DeleteBack();
- }
- const UString &front = pathParts.Front();
- bool isAbs = false;
- if (front.IsEmpty())
- isAbs = true;
- else if (front.Length() == 2 && front[1] == L':')
- isAbs = true;
- else
- {
- for (int i = 0; i < pathParts.Size(); i++)
- {
- const UString &part = pathParts[i];
- if (part == L".." || part == L".")
- {
- isAbs = true;
- break;
- }
- }
- }
- int numAbsParts = 0;
- if (isAbs)
- if (pathParts.Size() > 1)
- numAbsParts = pathParts.Size() - 1;
- else
- numAbsParts = 1;
- UString prefix;
- for (int i = 0; i < numAbsParts; i++)
- {
- const UString &front = pathParts.Front();
- if (DoesNameContainWildCard(front))
- break;
- prefix += front;
- prefix += WCHAR_PATH_SEPARATOR;
- pathParts.Delete(0);
- }
- int index = FindPrefix(prefix);
- if (index < 0)
- index = Pairs.Add(CPair(prefix));
- CItem item;
- item.PathParts = pathParts;
- item.ForDir = true;
- item.ForFile = forFile;
- item.Recursive = recursive;
- Pairs[index].Head.AddItem(include, item);
- }
- bool CCensor::CheckPath(const UString &path, bool isFile) const
- {
- bool finded = false;
- for (int i = 0; i < Pairs.Size(); i++)
- {
- bool include;
- if (Pairs[i].Head.CheckPath(path, isFile, include))
- {
- if (!include)
- return false;
- finded = true;
- }
- }
- return finded;
- }
- void CCensor::ExtendExclude()
- {
- int i;
- for (i = 0; i < Pairs.Size(); i++)
- if (Pairs[i].Prefix.IsEmpty())
- break;
- if (i == Pairs.Size())
- return;
- int index = i;
- for (i = 0; i < Pairs.Size(); i++)
- if (index != i)
- Pairs[i].Head.ExtendExclude(Pairs[index].Head);
- }
- }
|