📄 archivecommandline.cpp
字号:
{ for(int i = 0; i < command.Length();) { wchar_t c = MyCharUpper(command[i]); int statePos = kUpdatePairStateIDSet.Find(c); if (statePos < 0) { postString = command.Mid(i); return true; } i++; 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;}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 = (int)(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); 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; } 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++) { UInt64 size; if (!ParseComplexSize(sv[i], size)) throw "incorrect volume size"; options.VolumesSizes.Add(size); } }}static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &properties){ 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); } properties.Add(property); } }}static void SetArchiveType(const UString &archiveType, #ifndef EXCLUDE_COM UString &filePath, CLSID &classID, #else UString &formatName, #endif UString &archiveExtension){ 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";}CArchiveCommandLineParser::CArchiveCommandLineParser(): parser(kNumSwitches) {}void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options){ try { parser.ParseStrings(kSwitchForms, commandStrings); } catch(...) { throw kUserErrorMessage; } options.IsInTerminal = (isatty(fileno(stdin)) != 0); options.IsStdOutTerminal = (isatty(fileno(stdout)) != 0); options.IsStdErrTerminal = (isatty(fileno(stderr)) != 0); options.StdOutMode = parser[NKey::kStdOut].ThereIs; options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs; #ifdef _WIN32 options.LargePages = false; if (parser[NKey::kLargePages].ThereIs) { const UString &postString = parser[NKey::kLargePages].PostStrings.Front(); if (postString.IsEmpty()) options.LargePages = true; } #endif}void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options){ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; int numNonSwitchStrings = nonSwitchStrings.Size(); if(numNonSwitchStrings < kMinNonSwitchWords) throw kUserErrorMessage; if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command)) throw kUserErrorMessage; options.TechMode = parser[NKey::kTechMode].ThereIs; NRecursedType::EEnum recursedType; if (parser[NKey::kRecursed].ThereIs) recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); else recursedType = NRecursedType::kNonRecursed; UINT codePage = CP_ACP; bool thereAreSwitchIncludes = false; if (parser[NKey::kInclude].ThereIs) { thereAreSwitchIncludes = true; AddSwitchWildCardsToCensor(options.WildcardCensor, parser[NKey::kInclude].PostStrings, true, recursedType, codePage); } if (parser[NKey::kExclude].ThereIs) AddSwitchWildCardsToCensor(options.WildcardCensor, parser[NKey::kExclude].PostStrings, false, recursedType, codePage); 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, codePage); options.YesToAll = parser[NKey::kYes].ThereIs;#ifdef HAVE_LSTAT global_use_lstat = !parser[NKey::kUseLStat].ThereIs;#endif 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, codePage); } if (parser[NKey::kArExclude].ThereIs) AddSwitchWildCardsToCensor(archiveWildcardCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage); bool directlyAddArchiveName = false; if (thereIsArchiveName) { if ((options.ArchiveName.Find(kUniversalWildcard) == -1) && (options.ArchiveName.Find(L"?") == -1)) { // no wildcard => no need to scan directlyAddArchiveName = true; } else { AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed); } } #ifdef _WIN32 ConvertToLongNames(archiveWildcardCensor); #endif archiveWildcardCensor.ExtendExclude(); CObjectVector<CDirItem> dirItems; { UStringVector errorPaths; CRecordVector<DWORD> errorCodes; HRESULT res = EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPaths, errorCodes); if (res != S_OK || errorPaths.Size() > 0) throw "cannot find archive"; } UStringVector archivePaths; int i; for (i = 0; i < dirItems.Size(); i++) archivePaths.Add(dirItems[i].FullPath); // Because the pathname of archive can be a symbolic link // do not use "AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName" if (directlyAddArchiveName) archivePaths.Add(options.ArchiveName); 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) { SetMethodOptions(parser, options.ExtractProperties); if (options.StdOutMode && options.IsStdOutTerminal) 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.MethodMode.Properties); options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs; if (options.EnablePercents) { if ((options.StdOutMode && !options.IsStdErrTerminal) || (!options.StdOutMode && !options.IsStdOutTerminal)) 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 mode and email mode cannot be combined"; if (updateOptions.StdOutMode && options.IsStdOutTerminal) throw kTerminalOutError; if(updateOptions.StdInMode) updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front(); #ifdef _WIN32 ConvertToLongNames(options.WildcardCensor); #endif } else throw kUserErrorMessage; options.WildcardCensor.ExtendExclude();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -