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

📄 main.cpp

📁 7-Zip 3.11的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    char 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;
}

UString MakeFullArchiveName(const UString &name, const UString &extension)
{
  if (extension.IsEmpty())
    return name;
  if (name.IsEmpty())
    return name;
  if (name[name.Length() - 1] == L'.')
    return name.Left(name.Length() - 1);
  int slash1Pos = name.ReverseFind(L'\\');
  int slash2Pos = name.ReverseFind(L'/');
  int slashPos = MyMax(slash1Pos, slash2Pos);
  int dotPos = name.ReverseFind(L'.');
  if (dotPos >= 0 && (dotPos > slashPos || slashPos < 0))
    return name;
  return name + L'.' + extension;
}

void ParseUpdateCommandString(CUpdateArchiveOptions &options, 
    const UStringVector &updatePostStrings, 
    const NUpdateArchive::CActionSet &defaultActionSet,
    const UString &extension)
{
  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))
        PrintHelpAndExit();
      if(postString.IsEmpty())
      {
        if(options.UpdateArchiveItself)
        {
          options.Commands[0].ActionSet = actionSet;
        }
      }
      else
      {
        if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
          PrintHelpAndExit();
        CUpdateArchiveCommand updateCommand;

        UString archivePath = postString.Mid(1);

        if (archivePath.IsEmpty())
          PrintHelpAndExit();
        updateCommand.ArchivePath = MakeFullArchiveName(archivePath, extension);
        updateCommand.ActionSet = actionSet;
        options.Commands.Add(updateCommand);
      }
    }
  }
}

static void SetAddCommandOptions(NCommandType::EEnum commandType, 
    const CParser &parser, 
    const UString &archivePath, 
    CUpdateArchiveOptions &options, UString &workingDir, 
    const UString &extension)
{
  NUpdateArchive::CActionSet defaultActionSet;
  switch(commandType)
  {
    case NCommandType::kAdd: 
      defaultActionSet = NUpdateArchive::kAddActionSet;
      break;
    case NCommandType::kDelete: 
      defaultActionSet = NUpdateArchive::kDeleteActionSet;
      break;
    default: 
      defaultActionSet = NUpdateArchive::kUpdateActionSet;
  }
  
  options.ArchivePath = archivePath;
  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, extension);
  if(parser[NKey::kWorkingDir].ThereIs)
  {
    const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
    if (postString.IsEmpty())
      NDirectory::MyGetTempPath(workingDir);
    else
      workingDir = postString;
  }
  else
  {
    if (!NDirectory::GetOnlyDirPrefix(archivePath, workingDir))
      throw "bad archive name";
    if (workingDir.IsEmpty())
      workingDir = L".\\";
  }
  if(options.SfxMode = parser[NKey::kSfx].ThereIs)
  {
    UString moduleName = parser[NKey::kSfx].PostStrings[0];
    if (moduleName.IsEmpty())
      moduleName = kDefaultSfxModule;
    if (!NDirectory::MySearchPath(NULL, moduleName, NULL, options.SfxModule))
      throw "can't find specified sfx module";
  }
}

static const char kByteSymbol = 'B';
static const char kKiloByteSymbol = 'K';
static const char kMegaByteSymbol = 'M';

static void SetMethodOptions(const CParser &parser, 
    CUpdateArchiveOptions &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);
    }
  }
}

static void MyOpenArhive(const UString &archiveName, 
    const NFind::CFileInfoW &archiveFileInfo,
    #ifndef EXCLUDE_COM
    HMODULE *module,
    #endif
    IInArchive **archiveHandler,
    UString &defaultItemName,
    bool &passwordEnabled, 
    UString &password)
{
  COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
  CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
  if (passwordEnabled)
  {
    openCallbackSpec->PasswordIsDefined = passwordEnabled;
    openCallbackSpec->Password = password;
  }

  UString fullName;
  int fileNamePartStartIndex;
  NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
  openCallbackSpec->LoadFileInfo(
      fullName.Left(fileNamePartStartIndex), 
      fullName.Mid(fileNamePartStartIndex));

  CArchiverInfo archiverInfo;
  int subExtIndex;
  HRESULT result = OpenArchive(archiveName, 
      #ifndef EXCLUDE_COM
      module,
      #endif
      archiveHandler, 
      archiverInfo, 
      subExtIndex,
      openCallback);
  if (result == S_FALSE)
    throw "file is not supported archive";
  if (result != S_OK)
    throw "error";
  defaultItemName = GetDefaultName(archiveName, 
      archiverInfo.Extensions[subExtIndex].Extension, 
      archiverInfo.Extensions[subExtIndex].AddExtension);
  passwordEnabled = openCallbackSpec->PasswordIsDefined;
  password = openCallbackSpec->Password;
}

#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 Main2()
{
  SetFileApisToOEM();
  
  g_StdOut << kCopyrightString;

  UStringVector commandStrings;
  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);

  if(commandStrings.Size() == 1)
  {
    PrintHelp();
    return 0;
  }
  commandStrings.Delete(0);

  CParser parser(kNumSwitches);
  try
  {
    parser.ParseStrings(kSwitchForms, commandStrings);
  }
  catch(...) 
  {
    PrintHelpAndExit();
  }

  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
  {
    PrintHelp();
    return 0;
  }
  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;

  int numNonSwitchStrings = nonSwitchStrings.Size();
  if(numNonSwitchStrings < kMinNonSwitchWords)  
    PrintHelpAndExit();
  CArchiveCommand command;
  if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command))
    PrintHelpAndExit();

  NRecursedType::EEnum recursedType;
  if (parser[NKey::kRecursed].ThereIs)
    recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
  else
    recursedType = command.DefaultRecursedType();

  NWildcard::CCensor wildcardCensor;
  
  bool thereAreSwitchIncludeWildCards;
  if (parser[NKey::kInclude].ThereIs)
  {
    thereAreSwitchIncludeWildCards = true;
    AddSwitchWildCardsToCensor(wildcardCensor, parser[NKey::kInclude].PostStrings, 
        true, recursedType);
  }
  else
    thereAreSwitchIncludeWildCards = false;
  if (parser[NKey::kExclude].ThereIs)
    AddSwitchWildCardsToCensor(wildcardCensor, parser[NKey::kExclude].PostStrings, 
        false, recursedType);
 
  AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType,
      thereAreSwitchIncludeWildCards);


  bool yesToAll = parser[NKey::kYes].ThereIs;

  UString archiveName;
  archiveName = nonSwitchStrings[kArchiveNameIndex];

  NExtractMode::EEnum extractMode;
  bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);

  bool passwordEnabled = parser[NKey::kPassword].ThereIs;

  UString password;
  if(passwordEnabled)
    password = parser[NKey::kPassword].PostStrings[0];

  if(isExtractGroupCommand || command.CommandType == NCommandType::kList)
  {
    NFind::CFileInfoW archiveFileInfo;
    if (!NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
      throw "there is no such archive";

   if (archiveFileInfo.IsDirectory())
      throw "there is no such archive";

    UString defaultItemName;

    #ifndef EXCLUDE_COM
    NDLL::CLibrary library;
    #endif
    CMyComPtr<IInArchive> archiveHandler;
    CArchiverInfo archiverInfo;

    MyOpenArhive(archiveName, archiveFileInfo, 
        #ifndef EXCLUDE_COM
        &library,
        #endif
        &archiveHandler, 
        defaultItemName, passwordEnabled, password);

    if(isExtractGroupCommand)
    {
      PrintProcessTitle(kExtractGroupProcessMessage, archiveName);
      UString outputDir;
      if(parser[NKey::kOutputDir].ThereIs)
      {
        outputDir = parser[NKey::kOutputDir].PostStrings[0]; // test this DirPath
        NName::NormalizeDirPathPrefix(outputDir);
      }

      NExtraction::NOverwriteMode::EEnum overwriteMode = 
          NExtraction::NOverwriteMode::kAskBefore;
      if(parser[NKey::kOverwrite].ThereIs)
        overwriteMode = k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
     

      CExtractOptions options(extractMode, outputDir, yesToAll, 
          passwordEnabled, password, overwriteMode);
      options.DefaultItemName = defaultItemName;
      options.ArchiveFileInfo = archiveFileInfo;
      // options.ArchiveFileInfo = archiveFileInfo;
      HRESULT result = DeCompressArchiveSTD(archiveHandler, wildcardCensor, options);
      if (result != S_OK)
      {
        return NExitCode::kErrorsDuringDecompression;
      }
    }
    else
    {
      PrintProcessTitle(kListingProcessMessage, archiveName);
      ListArchive(archiveHandler, defaultItemName, archiveFileInfo, 
          wildcardCensor/*, command.ListFullPathes, command.ListMode*/);
    }
  }
  else if(command.IsFromUpdateGroup())
  {
    CUpdateArchiveOptions options;

    options.MethodMode.PasswordIsDefined = passwordEnabled && !password.IsEmpty();
    options.MethodMode.AskPassword = passwordEnabled && password.IsEmpty();
    options.MethodMode.Password = password;

    UString workingDir;

    UString archiveType;
    if(parser[NKey::kArchiveType].ThereIs)
      archiveType = parser[NKey::kArchiveType].PostStrings[0];
    else
      archiveType = kDefaultArchiveType;

    UString extension;
    if (!archiveType.IsEmpty())
    {
      #ifndef EXCLUDE_COM
      SetArchiveType(archiveType, options.MethodMode.FilePath, 
          options.MethodMode.ClassID1, extension);
      #else
      SetArchiveType(archiveType, options.MethodMode.Name, extension);
      #endif
    }
    if(parser[NKey::kSfx].ThereIs)
      extension = kSFXExtension;
    archiveName = MakeFullArchiveName(archiveName, extension);

    SetAddCommandOptions(command.CommandType, parser, archiveName, options,
        workingDir, extension); 
    
    SetMethodOptions(parser, options); 

    if (options.SfxMode)
    {
      CProperty property;
      property.Name = L"rsfx";
      property.Value = L"on";
      options.MethodMode.Properties.Add(property);
    }

    NFind::CFileInfoW archiveFileInfo;
    #ifndef EXCLUDE_COM
    NDLL::CLibrary library;
    #endif
    CMyComPtr<IInArchive> archive;

    UString defaultItemName;
    if (NFind::FindFile(archiveName, archiveFileInfo))
    {
      if (archiveFileInfo.IsDirectory())
        throw "there is no such archive";
      MyOpenArhive(archiveName, archiveFileInfo, 
          #ifndef EXCLUDE_COM
          &library,
          #endif
          &archive, 
          defaultItemName, passwordEnabled, password);
    }
    else
      if (archiveType.IsEmpty())
        throw "type of archive is not specified";
    bool enableParcents = !parser[NKey::kDisablePercents].ThereIs;
    if (enableParcents)
    {
      if (!isatty(fileno(stdout)))  
        enableParcents = false;
    }
    HRESULT result  = UpdateArchiveStdMain(wildcardCensor, options, workingDir, 
        archive, &defaultItemName, &archiveFileInfo, enableParcents);
    if (result != S_OK)
      throw NExitCode::CSystemError(result);
  }
  else 
    PrintHelpAndExit();
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -