⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archivecommandline.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{  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 + -