📄 archivecommandline.cpp
字号:
if (i >= command.Length())
return false;
int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));
if (actionPos < 0)
return false;
actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);
if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)
return false;
i++;
}
postString.Empty();
return true;
}
/*
void MakeFullArchiveName(const UString &path, CArchivePath &ap)
{
SplitPathToParts(path, ap.Prefix, ap.Name);
if (ap.Name.IsEmpty())
return;
int dotPos = ap.Name.ReverseFind(L'.');
if (dotPos < 0)
return;
if (dotPos == ap.Name.Length() - 1)
{
ap.Name = ap.Name.Left(dotPos);
ap.BaseExtension.Empty();
return;
}
if (ap.BaseExtension.CompareNoCase(ap.Name.Mid(dotPos + 1)) == 0)
ap.Name = ap.Name.Left(dotPos);
else
ap.BaseExtension.Empty();
}
*/
static void ParseUpdateCommandString(CUpdateOptions &options,
const UStringVector &updatePostStrings,
const NUpdateArchive::CActionSet &defaultActionSet)
{
for(int i = 0; i < updatePostStrings.Size(); i++)
{
const UString &updateString = updatePostStrings[i];
if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
{
if(options.UpdateArchiveItself)
{
options.UpdateArchiveItself = false;
options.Commands.Delete(0);
}
}
else
{
NUpdateArchive::CActionSet actionSet = defaultActionSet;
UString postString;
if (!ParseUpdateCommandString2(updateString, actionSet, postString))
throw kUserErrorMessage;
if(postString.IsEmpty())
{
if(options.UpdateArchiveItself)
options.Commands[0].ActionSet = actionSet;
}
else
{
if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
throw kUserErrorMessage;
CUpdateArchiveCommand uc;
UString archivePath = postString.Mid(1);
if (archivePath.IsEmpty())
throw kUserErrorMessage;
uc.ArchivePath.BaseExtension = options.ArchivePath.BaseExtension;
uc.ArchivePath.VolExtension = options.ArchivePath.VolExtension;
uc.ArchivePath.ParseFromPath(archivePath);
uc.ActionSet = actionSet;
options.Commands.Add(uc);
}
}
}
}
static const char kByteSymbol = 'B';
static const char kKiloSymbol = 'K';
static const char kMegaSymbol = 'M';
static const char kGigaSymbol = 'G';
static bool ParseComplexSize(const UString &src, UInt64 &result)
{
UString s = src;
s.MakeUpper();
const wchar_t *start = s;
const wchar_t *end;
UInt64 number = ConvertStringToUInt64(start, &end);
int numDigits = end - start;
if (numDigits == 0 || s.Length() > numDigits + 1)
return false;
if (s.Length() == numDigits)
{
result = number;
return true;
}
int numBits;
switch (s[numDigits])
{
case kByteSymbol:
result = number;
return true;
case kKiloSymbol:
numBits = 10;
break;
case kMegaSymbol:
numBits = 20;
break;
case kGigaSymbol:
numBits = 30;
break;
default:
return false;
}
if (number >= ((UInt64)1 << (64 - numBits)))
return false;
result = number << numBits;
return true;
}
static void SetAddCommandOptions(
NCommandType::EEnum commandType,
const CParser &parser,
CUpdateOptions &options)
{
NUpdateArchive::CActionSet defaultActionSet;
switch(commandType)
{
case NCommandType::kAdd:
defaultActionSet = NUpdateArchive::kAddActionSet;
break;
case NCommandType::kDelete:
defaultActionSet = NUpdateArchive::kDeleteActionSet;
break;
default:
defaultActionSet = NUpdateArchive::kUpdateActionSet;
}
options.UpdateArchiveItself = true;
options.Commands.Clear();
CUpdateArchiveCommand updateMainCommand;
updateMainCommand.ActionSet = defaultActionSet;
options.Commands.Add(updateMainCommand);
// options.ItselfActionSet = defaultActionSet;
if(parser[NKey::kUpdate].ThereIs)
ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings,
defaultActionSet);
if(parser[NKey::kWorkingDir].ThereIs)
{
const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
if (postString.IsEmpty())
NDirectory::MyGetTempPath(options.WorkingDir);
else
options.WorkingDir = postString;
}
else
{
/*
if (!NDirectory::GetOnlyDirPrefix(options.ArchivePath.GetFullPath(), options.WorkingDir))
throw "bad archive name";
if (options.WorkingDir.IsEmpty())
options.WorkingDir = L".\\";
*/
}
if(options.SfxMode = parser[NKey::kSfx].ThereIs)
options.SfxModule = parser[NKey::kSfx].PostStrings[0];
if (parser[NKey::kVolume].ThereIs)
{
const UStringVector &sv = parser[NKey::kVolume].PostStrings;
for (int i = 0; i < sv.Size(); i++)
{
const UString &s = sv[i];
UInt64 size;
if (!ParseComplexSize(sv[i], size))
throw "incorrect volume size";
options.VolumesSizes.Add(size);
}
}
}
static void SetMethodOptions(const CParser &parser,
CUpdateOptions &options)
{
if (parser[NKey::kProperty].ThereIs)
{
// options.MethodMode.Properties.Clear();
for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
{
CProperty property;
const UString &postString = parser[NKey::kProperty].PostStrings[i];
int index = postString.Find(L'=');
if (index < 0)
property.Name = postString;
else
{
property.Name = postString.Left(index);
property.Value = postString.Mid(index + 1);
}
options.MethodMode.Properties.Add(property);
}
}
}
#ifndef EXCLUDE_COM
void SetArchiveType(const UString &archiveType,
UString &filePath, CLSID &classID, UString &archiveExtension)
#else
void SetArchiveType(const UString &archiveType,
UString &formatName, UString &archiveExtension)
#endif
{
CObjectVector<CArchiverInfo> archiverInfoVector;
ReadArchiverInfoList(archiverInfoVector);
if (archiverInfoVector.Size() == 0)
throw "There are no installed archive handlers";
if (archiveType.IsEmpty())
throw "Incorrect archive type was assigned";
for (int i = 0; i < archiverInfoVector.Size(); i++)
{
const CArchiverInfo &archiverInfo = archiverInfoVector[i];
if (archiverInfo.Name.CompareNoCase(archiveType) == 0)
{
#ifndef EXCLUDE_COM
classID = archiverInfo.ClassID;
filePath = archiverInfo.FilePath;
#else
formatName = archiverInfo.Name;
#endif
archiveExtension = archiverInfo.GetMainExtension();
return;
}
}
throw "Incorrect archive type was assigned";
}
// int Main2(int numArguments, const char *arguments[])
int ParseCommandLine(UStringVector commandStrings,
CArchiveCommandLineOptions &options)
{
CParser parser(kNumSwitches);
try
{
parser.ParseStrings(kSwitchForms, commandStrings);
}
catch(...)
{
throw kUserErrorMessage;
}
options.IsInTerminal = (isatty(fileno(stdin)) != 0);
options.IsOutTerminal = (isatty(fileno(stdout)) != 0);
options.StdOutMode = parser[NKey::kStdOut].ThereIs;
options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
if (options.StdOutMode)
options.EnableHeaders = false;
options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs;
if(options.HelpMode)
{
return 0;
}
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
int numNonSwitchStrings = nonSwitchStrings.Size();
if(numNonSwitchStrings < kMinNonSwitchWords)
throw kUserErrorMessage;
if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
throw kUserErrorMessage;
NRecursedType::EEnum recursedType;
if (parser[NKey::kRecursed].ThereIs)
recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
else
recursedType = options.Command.DefaultRecursedType();
bool thereAreSwitchIncludes = false;
if (parser[NKey::kInclude].ThereIs)
{
thereAreSwitchIncludes = true;
AddSwitchWildCardsToCensor(options.WildcardCensor,
parser[NKey::kInclude].PostStrings, true, recursedType);
}
if (parser[NKey::kExclude].ThereIs)
AddSwitchWildCardsToCensor(options.WildcardCensor,
parser[NKey::kExclude].PostStrings, false, recursedType);
int curCommandIndex = kCommandIndex + 1;
bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs;
if (thereIsArchiveName)
{
if(curCommandIndex >= numNonSwitchStrings)
throw kUserErrorMessage;
options.ArchiveName = nonSwitchStrings[curCommandIndex++];
}
AddToCensorFromNonSwitchesStrings(
curCommandIndex, options.WildcardCensor,
nonSwitchStrings, recursedType, thereAreSwitchIncludes);
options.YesToAll = parser[NKey::kYes].ThereIs;
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
if(options.PasswordEnabled)
options.Password = parser[NKey::kPassword].PostStrings[0];
options.StdInMode = parser[NKey::kStdIn].ThereIs;
options.ShowDialog = parser[NKey::kShowDialog].ThereIs;
if(isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
{
if (options.StdInMode)
throw "reading archives from stdin is not implemented";
if (!options.WildcardCensor.AllAreRelative())
throw "cannot use absolute pathnames for this command";
NWildcard::CCensor archiveWildcardCensor;
if (parser[NKey::kArInclude].ThereIs)
{
AddSwitchWildCardsToCensor(archiveWildcardCensor,
parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed);
}
if (parser[NKey::kArExclude].ThereIs)
AddSwitchWildCardsToCensor(archiveWildcardCensor,
parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed);
if (thereIsArchiveName)
AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
CObjectVector<CDirItem> dirItems;
EnumerateItems(archiveWildcardCensor, dirItems, NULL);
UStringVector archivePaths;
/*
int pos = options.ArchiveName.ReverseFind('\\');
UString base;
if (pos >= 0)
base = options.ArchiveName.Left(pos + 1);
NFind::CEnumeratorW enumerator(options.ArchiveName);
NFind::CFileInfoW fileInfo;
while(enumerator.Next(fileInfo))
{
if (fileInfo.IsDirectory())
continue;
archivePaths.Add(base + fileInfo.Name);
}
*/
int i;
for (i = 0; i < dirItems.Size(); i++)
archivePaths.Add(dirItems[i].FullPath);
if (archivePaths.Size() == 0)
throw "there is no such archive";
UStringVector archivePathsFull;
for (i = 0; i < archivePaths.Size(); i++)
{
UString fullPath;
NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath);
archivePathsFull.Add(fullPath);
}
CIntVector indices;
SortStringsToIndices(archivePathsFull, indices);
options.ArchivePathsSorted.Reserve(indices.Size());
options.ArchivePathsFullSorted.Reserve(indices.Size());
for (i = 0; i < indices.Size(); i++)
{
options.ArchivePathsSorted.Add(archivePaths[indices[i]]);
options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]);
}
if(isExtractGroupCommand)
{
if (options.StdOutMode && options.IsOutTerminal)
throw kTerminalOutError;
if(parser[NKey::kOutputDir].ThereIs)
{
options.OutputDir = parser[NKey::kOutputDir].PostStrings[0];
NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
}
options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
if(parser[NKey::kOverwrite].ThereIs)
options.OverwriteMode =
k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
else if (options.YesToAll)
options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
}
}
else if(options.Command.IsFromUpdateGroup())
{
CUpdateOptions &updateOptions = options.UpdateOptions;
UString archiveType;
if(parser[NKey::kArchiveType].ThereIs)
archiveType = parser[NKey::kArchiveType].PostStrings[0];
else
archiveType = kDefaultArchiveType;
UString typeExtension;
if (!archiveType.IsEmpty())
{
#ifndef EXCLUDE_COM
SetArchiveType(archiveType, updateOptions.MethodMode.FilePath,
updateOptions.MethodMode.ClassID, typeExtension);
#else
SetArchiveType(archiveType, updateOptions.MethodMode.Name, typeExtension);
#endif
}
UString extension = typeExtension;
if(parser[NKey::kSfx].ThereIs)
extension = kSFXExtension;
updateOptions.ArchivePath.BaseExtension = extension;
updateOptions.ArchivePath.VolExtension = typeExtension;
updateOptions.ArchivePath.ParseFromPath(options.ArchiveName);
SetAddCommandOptions(options.Command.CommandType, parser,
updateOptions);
SetMethodOptions(parser, updateOptions);
/*
if (updateOptions.SfxMode)
{
CProperty property;
property.Name = L"rsfx";
property.Value = L"on";
updateOptions.MethodMode.Properties.Add(property);
}
*/
///
options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
if (options.EnablePercents)
{
/*
if (!options.IsTerminal)
options.EnablePercents = false;
*/
}
if (updateOptions.EMailMode = parser[NKey::kEmail].ThereIs)
{
updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
if (updateOptions.EMailAddress.Length() > 0)
if (updateOptions.EMailAddress[0] == L'.')
{
updateOptions.EMailRemoveAfter = true;
updateOptions.EMailAddress.Delete(0);
}
}
updateOptions.StdOutMode = options.StdOutMode;
updateOptions.StdInMode = options.StdInMode;
if (updateOptions.StdOutMode && updateOptions.EMailMode)
throw "stdout and email cannot be combined";
if (updateOptions.StdOutMode && options.IsOutTerminal)
throw kTerminalOutError;
if(updateOptions.StdInMode)
updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
}
else
throw kUserErrorMessage;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -