4.24 beta

This commit is contained in:
Igor Pavlov
2005-07-05 00:00:00 +00:00
committed by Kornel Lesiński
parent ac2b563958
commit 47f4915611
66 changed files with 757 additions and 366 deletions

View File

@@ -228,7 +228,7 @@ static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
recursed = false;
break;
}
wildcardCensor.AddItem(name, include, recursed);
wildcardCensor.AddItem(include, name, recursed);
return true;
}
@@ -374,6 +374,72 @@ static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
}
}
#ifdef _WIN32
// This code converts all short file names to long file names.
static void ConvertToLongName(const UString &prefix, UString &name)
{
if (name.IsEmpty() || DoesNameContainWildCard(name))
return;
NFind::CFileInfoW fileInfo;
if (NFind::FindFile(prefix + name, fileInfo))
name = fileInfo.Name;
}
static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
{
for (int i = 0; i < items.Size(); i++)
{
NWildcard::CItem &item = items[i];
if (item.Recursive || item.PathParts.Size() != 1)
continue;
ConvertToLongName(prefix, item.PathParts.Front());
}
}
static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
{
ConvertToLongNames(prefix, node.IncludeItems);
ConvertToLongNames(prefix, node.ExcludeItems);
int i;
for (i = 0; i < node.SubNodes.Size(); i++)
ConvertToLongName(prefix, node.SubNodes[i].Name);
// mix folders with same name
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
for (int j = i + 1; j < node.SubNodes.Size();)
{
const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
if (nextNode1.Name.CollateNoCase(nextNode2.Name) == 0)
{
nextNode1.IncludeItems += nextNode2.IncludeItems;
nextNode1.ExcludeItems += nextNode2.ExcludeItems;
node.SubNodes.Delete(j);
}
else
j++;
}
}
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode = node.SubNodes[i];
ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode);
}
}
static void ConvertToLongNames(NWildcard::CCensor &censor)
{
for (int i = 0; i < censor.Pairs.Size(); i++)
{
NWildcard::CPair &pair = censor.Pairs[i];
ConvertToLongNames(pair.Prefix, pair.Head);
}
}
#endif
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
{
switch(i)
@@ -718,6 +784,10 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
if (thereIsArchiveName)
AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
#ifdef _WIN32
ConvertToLongNames(archiveWildcardCensor);
#endif
CObjectVector<CDirItem> dirItems;
UString errorPath;
if (EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPath) != S_OK)
@@ -826,6 +896,10 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
throw kTerminalOutError;
if(updateOptions.StdInMode)
updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
#ifdef _WIN32
ConvertToLongNames(options.WildcardCensor);
#endif
}
else
throw kUserErrorMessage;

View File

@@ -12,12 +12,10 @@ using namespace NWindows;
using namespace NFile;
using namespace NName;
// using namespace NUpdateArchive;
void AddDirFileInfo(
const UString &prefix,
const UString &fullPathName,
NFind::CFileInfoW &fileInfo,
const UString &prefix, // prefix for logical path
const UString &fullPathName, // path on disk: can be relative to some basePrefix
const NFind::CFileInfoW &fileInfo,
CObjectVector<CDirItem> &dirItems)
{
CDirItem item;
@@ -32,9 +30,9 @@ void AddDirFileInfo(
}
static HRESULT EnumerateDirectory(
const UString &baseFolderPrefix,
const UString &directory,
const UString &prefix,
const UString &baseFolderPrefix, // base (disk) prefix for scanning
const UString &directory, // additional disk prefix starting from baseFolderPrefix
const UString &prefix, // logical prefix
CObjectVector<CDirItem> &dirItems,
UString &errorPath)
{
@@ -51,8 +49,7 @@ static HRESULT EnumerateDirectory(
}
if (!found)
break;
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo,
dirItems);
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems);
if (fileInfo.IsDirectory())
{
RINOK(EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter),
@@ -63,8 +60,8 @@ static HRESULT EnumerateDirectory(
}
HRESULT EnumerateDirItems(
const UString &baseFolderPrefix,
const UStringVector &fileNames,
const UString &baseFolderPrefix, // base (disk) prefix for scanning
const UStringVector &fileNames, // names relative to baseFolderPrefix
const UString &archiveNamePrefix,
CObjectVector<CDirItem> &dirItems,
UString &errorPath)
@@ -74,7 +71,11 @@ HRESULT EnumerateDirItems(
const UString &fileName = fileNames[i];
NFind::CFileInfoW fileInfo;
if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo))
throw 1081736;
{
HRESULT error = ::GetLastError();
errorPath = baseFolderPrefix + fileName;
return error;
}
AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems);
if (fileInfo.IsDirectory())
{
@@ -88,9 +89,9 @@ HRESULT EnumerateDirItems(
static HRESULT EnumerateDirItems(
const NWildcard::CCensorNode &curNode,
const UString &diskPrefix,
const UString &archivePrefix,
const UString &addArchivePrefix,
const UString &diskPrefix, // full disk path prefix
const UString &archivePrefix, // prefix from root
const UStringVector &addArchivePrefix, // prefix from curNode
CObjectVector<CDirItem> &dirItems,
bool enterToSubFolders,
IEnumDirItemCallback *callback,
@@ -101,6 +102,107 @@ static HRESULT EnumerateDirItems(
enterToSubFolders = true;
if (callback)
RINOK(callback->CheckBreak());
// try direct_names case at first
if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
{
// check that all names are direct
int i;
for (i = 0; i < curNode.IncludeItems.Size(); i++)
{
const NWildcard::CItem &item = curNode.IncludeItems[i];
if (item.Recursive || item.PathParts.Size() != 1)
break;
const UString &name = item.PathParts.Front();
if (name.IsEmpty() || DoesNameContainWildCard(name))
break;
}
if (i == curNode.IncludeItems.Size())
{
// all names are direct (no wildcards)
// so we don't need file_system's dir enumerator
CRecordVector<bool> needEnterVector;
for (i = 0; i < curNode.IncludeItems.Size(); i++)
{
const NWildcard::CItem &item = curNode.IncludeItems[i];
const UString &name = item.PathParts.Front();
const UString fullPath = diskPrefix + name;
NFind::CFileInfoW fileInfo;
if (!NFind::FindFile(fullPath, fileInfo))
{
HRESULT error = ::GetLastError();
errorPath = fullPath;
return error;
}
bool isDir = fileInfo.IsDirectory();
if (isDir && !item.ForDir || !isDir && !item.ForFile)
{
errorPath = fullPath;
return E_FAIL;
}
const UString realName = fileInfo.Name;
const UString realDiskPath = diskPrefix + realName;
{
UStringVector pathParts;
pathParts.Add(fileInfo.Name);
if (curNode.CheckPathToRoot(false, pathParts, !isDir))
continue;
}
AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems);
if (!isDir)
continue;
UStringVector addArchivePrefixNew;
const NWildcard::CCensorNode *nextNode = 0;
int index = curNode.FindSubNode(name);
if (index >= 0)
{
for (int t = needEnterVector.Size(); t <= index; t++)
needEnterVector.Add(true);
needEnterVector[index] = false;
nextNode = &curNode.SubNodes[index];
}
else
{
nextNode = &curNode;
addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support
}
RINOK(EnumerateDirItems(*nextNode,
realDiskPath + wchar_t(kDirDelimiter),
archivePrefix + realName + wchar_t(kDirDelimiter),
addArchivePrefixNew, dirItems, true, callback, errorPath));
}
for (i = 0; i < curNode.SubNodes.Size(); i++)
{
if (i < needEnterVector.Size())
if (!needEnterVector[i])
continue;
const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
const UString fullPath = diskPrefix + nextNode.Name;
NFind::CFileInfoW fileInfo;
if (!NFind::FindFile(fullPath, fileInfo))
{
if (!nextNode.AreThereIncludeItems())
continue;
HRESULT error = ::GetLastError();
errorPath = fullPath;
return error;
}
if (!fileInfo.IsDirectory())
{
errorPath = fullPath;
return E_FAIL;
}
RINOK(EnumerateDirItems(nextNode,
diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),
archivePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
UStringVector(), dirItems, false, callback, errorPath));
}
return S_OK;
}
}
NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard));
while (true)
{
@@ -117,13 +219,17 @@ static HRESULT EnumerateDirItems(
if (callback)
RINOK(callback->CheckBreak());
UString name = fileInfo.Name;
const UString &name = fileInfo.Name;
bool enterToSubFolders2 = enterToSubFolders;
if (curNode.CheckPathToRoot(addArchivePrefix + name, !fileInfo.IsDirectory()))
UStringVector addArchivePrefixNew = addArchivePrefix;
addArchivePrefixNew.Add(name);
if (curNode.CheckPathToRoot(false, UStringVector(addArchivePrefixNew), !fileInfo.IsDirectory()))
continue;
if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory()))
{
AddDirFileInfo(archivePrefix, diskPrefix + fileInfo.Name, fileInfo, dirItems);
AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems);
if (fileInfo.IsDirectory())
enterToSubFolders2 = true;;
enterToSubFolders2 = true;
}
if (!fileInfo.IsDirectory())
continue;
@@ -138,20 +244,16 @@ static HRESULT EnumerateDirItems(
if (!enterToSubFolders2 && nextNode == 0)
continue;
UString archivePrefixNew = archivePrefix;
UString addArchivePrefixNew = addArchivePrefix;
addArchivePrefixNew = addArchivePrefix;
if (nextNode == 0)
{
nextNode = &curNode;
addArchivePrefixNew += name;
addArchivePrefixNew += wchar_t(kDirDelimiter);
addArchivePrefixNew.Add(name);
}
archivePrefixNew += name;
archivePrefixNew += wchar_t(kDirDelimiter);
RINOK(EnumerateDirItems(*nextNode,
diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),
archivePrefixNew, addArchivePrefixNew,
dirItems, enterToSubFolders2, callback, errorPath));
diskPrefix + name + wchar_t(kDirDelimiter),
archivePrefix + name + wchar_t(kDirDelimiter),
addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPath));
}
return S_OK;
}
@@ -167,7 +269,7 @@ HRESULT EnumerateItems(
if (callback)
RINOK(callback->CheckBreak());
const NWildcard::CPair &pair = censor.Pairs[i];
RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", L"", dirItems, false, callback, errorPath));
RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", UStringVector(), dirItems, false, callback, errorPath));
}
return S_OK;
}

View File

@@ -11,7 +11,7 @@
void AddDirFileInfo(
const UString &prefix,
const UString &fullPathName,
NWindows::NFile::NFind::CFileInfoW &fileInfo,
const NWindows::NFile::NFind::CFileInfoW &fileInfo,
CObjectVector<CDirItem> &dirItems);