Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/Common/Wildcard.cpp')
-rw-r--r--CPP/Common/Wildcard.cpp257
1 files changed, 162 insertions, 95 deletions
diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp
index 9614f63d..a83f9f10 100644
--- a/CPP/Common/Wildcard.cpp
+++ b/CPP/Common/Wildcard.cpp
@@ -15,22 +15,8 @@ bool g_CaseSensitive =
bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2)
{
if (g_CaseSensitive)
- {
- for (;;)
- {
- wchar_t c2 = *s2++; if (c2 == 0) return true;
- wchar_t c1 = *s1++;
- if (MyCharUpper(c1) !=
- MyCharUpper(c2))
- return false;
- }
- }
-
- for (;;)
- {
- wchar_t c2 = *s2++; if (c2 == 0) return true;
- wchar_t c1 = *s1++; if (c1 != c2) return false;
- }
+ return IsString1PrefixedByString2(s1, s2);
+ return IsString1PrefixedByString2_NoCase(s1, s2);
}
int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW
@@ -97,7 +83,7 @@ void SplitPathToParts(const UString &path, UStringVector &pathParts)
UString name;
unsigned prev = 0;
for (unsigned i = 0; i < len; i++)
- if (IsCharDirLimiter(path[i]))
+ if (IsPathSepar(path[i]))
{
name.SetFrom(path.Ptr(prev), i - prev);
pathParts.Add(name);
@@ -112,7 +98,7 @@ void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name)
const wchar_t *start = path;
const wchar_t *p = start + path.Len();
for (; p != start; p--)
- if (IsCharDirLimiter(*(p - 1)))
+ if (IsPathSepar(*(p - 1)))
break;
dirPrefix.SetFrom(path, (unsigned)(p - start));
name = p;
@@ -124,10 +110,10 @@ void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &na
const wchar_t *p = start + path.Len();
if (p != start)
{
- if (IsCharDirLimiter(*(p - 1)))
+ if (IsPathSepar(*(p - 1)))
p--;
for (; p != start; p--)
- if (IsCharDirLimiter(*(p - 1)))
+ if (IsPathSepar(*(p - 1)))
break;
}
dirPrefix.SetFrom(path, (unsigned)(p - start));
@@ -139,7 +125,7 @@ UString ExtractDirPrefixFromPath(const UString &path)
const wchar_t *start = path;
const wchar_t *p = start + path.Len();
for (; p != start; p--)
- if (IsCharDirLimiter(*(p - 1)))
+ if (IsPathSepar(*(p - 1)))
break;
return path.Left((unsigned)(p - start));
}
@@ -149,7 +135,7 @@ UString ExtractFileNameFromPath(const UString &path)
const wchar_t *start = path;
const wchar_t *p = start + path.Len();
for (; p != start; p--)
- if (IsCharDirLimiter(*(p - 1)))
+ if (IsPathSepar(*(p - 1)))
break;
return p;
}
@@ -177,15 +163,6 @@ bool DoesNameContainWildcard(const UString &path)
namespace NWildcard {
-
-#ifdef _WIN32
-bool IsDriveColonName(const wchar_t *s)
-{
- wchar_t c = s[0];
- return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
-}
-#endif
-
/*
M = MaskParts.Size();
@@ -212,6 +189,19 @@ bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
{
if (!isFile && !ForDir)
return false;
+
+ /*
+ if (PathParts.IsEmpty())
+ {
+ // PathParts.IsEmpty() means all items (universal wildcard)
+ if (!isFile)
+ return true;
+ if (pathParts.Size() <= 1)
+ return ForFile;
+ return (ForDir || Recursive && ForFile);
+ }
+ */
+
int delta = (int)pathParts.Size() - (int)PathParts.Size();
if (delta < 0)
return false;
@@ -286,7 +276,7 @@ void CCensorNode::AddItemSimple(bool include, CItem &item)
ExcludeItems.Add(item);
}
-void CCensorNode::AddItem(bool include, CItem &item)
+void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex)
{
if (item.PathParts.Size() <= 1)
{
@@ -300,9 +290,10 @@ void CCensorNode::AddItem(bool include, CItem &item)
}
const UString &front = item.PathParts.Front();
- // We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name
- // if (item.Wildcard)
- if (DoesNameContainWildcard(front))
+ // WIN32 doesn't support wildcards in file names
+ if (item.WildcardMatching
+ && ignoreWildcardIndex != 0
+ && DoesNameContainWildcard(front))
{
AddItemSimple(include, item);
return;
@@ -311,7 +302,7 @@ void CCensorNode::AddItem(bool include, CItem &item)
if (index < 0)
index = SubNodes.Add(CCensorNode(front, this));
item.PathParts.Delete(0);
- SubNodes[index].AddItem(include, item);
+ SubNodes[index].AddItem(include, item, ignoreWildcardIndex - 1);
}
void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching)
@@ -377,6 +368,7 @@ bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, boo
return finded;
}
+/*
bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const
{
UStringVector pathParts;
@@ -406,6 +398,7 @@ bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile)
return include;
return false;
}
+*/
bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
{
@@ -433,7 +426,7 @@ void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bo
bool forFile = true;
bool forFolder = true;
UString path2 = path;
- if (IsCharDirLimiter(path.Back()))
+ if (IsPathSepar(path.Back()))
{
path2.DeleteBack();
forFile = false;
@@ -462,12 +455,90 @@ int CCensor::FindPrefix(const UString &prefix) const
return -1;
}
+#ifdef _WIN32
+
+bool IsDriveColonName(const wchar_t *s)
+{
+ wchar_t c = s[0];
+ return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
+}
+
+unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts)
+{
+ if (pathParts.IsEmpty())
+ return 0;
+
+ unsigned testIndex = 0;
+ if (pathParts[0].IsEmpty())
+ {
+ if (pathParts.Size() < 4
+ || !pathParts[1].IsEmpty()
+ || pathParts[2] != L"?")
+ return 0;
+ testIndex = 3;
+ }
+ if (NWildcard::IsDriveColonName(pathParts[testIndex]))
+ return testIndex + 1;
+ return 0;
+}
+
+#endif
+
+static unsigned GetNumPrefixParts(const UStringVector pathParts)
+{
+ if (pathParts.IsEmpty())
+ return 0;
+
+ #ifdef _WIN32
+
+ if (IsDriveColonName(pathParts[0]))
+ return 1;
+ if (!pathParts[0].IsEmpty())
+ return 0;
+
+ if (pathParts.Size() == 1)
+ return 1;
+ if (!pathParts[1].IsEmpty())
+ return 1;
+ if (pathParts.Size() == 2)
+ return 2;
+ if (pathParts[2] == L".")
+ return 3;
+
+ unsigned networkParts = 2;
+ if (pathParts[2] == L"?")
+ {
+ if (pathParts.Size() == 3)
+ return 3;
+ if (IsDriveColonName(pathParts[3]))
+ return 4;
+ if (!pathParts[3].IsEqualTo_Ascii_NoCase("UNC"))
+ return 3;
+ networkParts = 4;
+ }
+
+ networkParts +=
+ // 2; // server/share
+ 1; // server
+ if (pathParts.Size() <= networkParts)
+ return pathParts.Size();
+ return networkParts;
+
+ #else
+
+ return pathParts[0].IsEmpty() ? 1 : 0;
+
+ #endif
+}
+
void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching)
{
- UStringVector pathParts;
if (path.IsEmpty())
throw "Empty file path";
+
+ UStringVector pathParts;
SplitPathToParts(path, pathParts);
+
bool forFile = true;
if (pathParts.Back().IsEmpty())
{
@@ -477,74 +548,55 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
UString prefix;
+ int ignoreWildcardIndex = -1;
+
+ // #ifdef _WIN32
+ // we ignore "?" wildcard in "\\?\" prefix.
+ if (pathParts.Size() >= 3
+ && pathParts[0].IsEmpty()
+ && pathParts[1].IsEmpty()
+ && pathParts[2] == L"?")
+ ignoreWildcardIndex = 2;
+ // #endif
+
if (pathMode != k_AbsPath)
{
- const UString &front = pathParts.Front();
- bool isAbs = false;
-
- if (front.IsEmpty())
- isAbs = true;
- else
+ ignoreWildcardIndex = -1;
+
+ const unsigned numPrefixParts = GetNumPrefixParts(pathParts);
+ unsigned numSkipParts = numPrefixParts;
+
+ if (pathMode != k_FullPath)
{
- #ifdef _WIN32
-
- if (IsDriveColonName(front))
- isAbs = true;
- else
-
- #endif
-
- FOR_VECTOR (i, pathParts)
- {
- const UString &part = pathParts[i];
- if (part == L".." || part == L".")
- {
- isAbs = true;
- break;
- }
- }
+ if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts)
+ numSkipParts = pathParts.Size() - 1;
}
-
- unsigned numAbsParts = 0;
- if (isAbs)
- if (pathParts.Size() > 1)
- numAbsParts = pathParts.Size() - 1;
- else
- numAbsParts = 1;
-
- #ifdef _WIN32
-
- // \\?\ case
- if (numAbsParts >= 3)
{
- if (pathParts[0].IsEmpty() &&
- pathParts[1].IsEmpty() &&
- pathParts[2] == L"?")
+ int dotsIndex = -1;
+ for (unsigned i = numPrefixParts; i < pathParts.Size(); i++)
{
- prefix =
- WSTRING_PATH_SEPARATOR
- WSTRING_PATH_SEPARATOR L"?"
- WSTRING_PATH_SEPARATOR;
- numAbsParts -= 3;
- pathParts.DeleteFrontal(3);
+ const UString &part = pathParts[i];
+ if (part == L".." || part == L".")
+ dotsIndex = i;
}
+
+ if (dotsIndex >= 0)
+ if (dotsIndex == (int)pathParts.Size() - 1)
+ numSkipParts = pathParts.Size();
+ else
+ numSkipParts = pathParts.Size() - 1;
}
-
- #endif
-
- if (numAbsParts > 1 && pathMode == k_FullPath)
- numAbsParts = 1;
-
- // We can't ignore wildcard, since we don't allow wildcard in SubNodes[].Name
- // if (wildcardMatching)
- for (unsigned i = 0; i < numAbsParts; i++)
+
+ for (unsigned i = 0; i < numSkipParts; i++)
{
{
const UString &front = pathParts.Front();
- if (DoesNameContainWildcard(front))
- break;
+ // WIN32 doesn't support wildcards in file names
+ if (wildcardMatching)
+ if (i >= numPrefixParts && DoesNameContainWildcard(front))
+ break;
prefix += front;
- prefix += WCHAR_PATH_SEPARATOR;
+ prefix.Add_PathSepar();
}
pathParts.Delete(0);
}
@@ -554,15 +606,29 @@ void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &pat
if (index < 0)
index = Pairs.Add(CPair(prefix));
+ if (pathMode != k_AbsPath)
+ {
+ if (pathParts.IsEmpty() || pathParts.Size() == 1 && pathParts[0].IsEmpty())
+ {
+ // we create universal item, if we skip all parts as prefix (like \ or L:\ )
+ pathParts.Clear();
+ pathParts.Add(L"*");
+ forFile = true;
+ wildcardMatching = true;
+ recursive = false;
+ }
+ }
+
CItem item;
item.PathParts = pathParts;
item.ForDir = true;
item.ForFile = forFile;
item.Recursive = recursive;
item.WildcardMatching = wildcardMatching;
- Pairs[index].Head.AddItem(include, item);
+ Pairs[index].Head.AddItem(include, item, ignoreWildcardIndex);
}
+/*
bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const
{
bool finded = false;
@@ -578,6 +644,7 @@ bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) cons
}
return finded;
}
+*/
void CCensor::ExtendExclude()
{