📄 main.cpp
字号:
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 + -