📄 archivecommandline.cpp
字号:
property.Name = postString.Left(index);
property.Value = postString.Mid(index + 1);
}
properties.Add(property);
}
}
}
CArchiveCommandLineParser::CArchiveCommandLineParser():
parser(sizeof(kSwitchForms) / sizeof(kSwitchForms[0])) {}
void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
CArchiveCommandLineOptions &options)
{
try
{
parser.ParseStrings(kSwitchForms, commandStrings);
}
catch(...)
{
ThrowUserErrorException();
}
options.IsInTerminal = MY_IS_TERMINAL(stdin);
options.IsStdOutTerminal = MY_IS_TERMINAL(stdout);
options.IsStdErrTerminal = MY_IS_TERMINAL(stderr);
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
}
struct CCodePagePair
{
const wchar_t *Name;
UINT CodePage;
};
static CCodePagePair g_CodePagePairs[] =
{
{ L"UTF-8", CP_UTF8 },
{ L"WIN", CP_ACP },
{ L"DOS", CP_OEMCP }
};
static const int kNumCodePages = sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]);
static bool ConvertStringToUInt32(const wchar_t *s, UInt32 &v)
{
const wchar_t *end;
UInt64 number = ConvertStringToUInt64(s, &end);
if (*end != 0)
return false;
if (number > (UInt32)0xFFFFFFFF)
return false;
v = (UInt32)number;
return true;
}
void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
{
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
int numNonSwitchStrings = nonSwitchStrings.Size();
if(numNonSwitchStrings < kMinNonSwitchWords)
ThrowUserErrorException();
if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
ThrowUserErrorException();
options.TechMode = parser[NKey::kTechMode].ThereIs;
if (parser[NKey::kCaseSensitive].ThereIs)
g_CaseSensitive = (parser[NKey::kCaseSensitive].PostCharIndex < 0);
NRecursedType::EEnum recursedType;
if (parser[NKey::kRecursed].ThereIs)
recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
else
recursedType = NRecursedType::kNonRecursed;
UINT codePage = CP_UTF8;
if (parser[NKey::kCharSet].ThereIs)
{
UString name = parser[NKey::kCharSet].PostStrings.Front();
name.MakeUpper();
int i;
for (i = 0; i < kNumCodePages; i++)
{
const CCodePagePair &pair = g_CodePagePairs[i];
if (name.Compare(pair.Name) == 0)
{
codePage = pair.CodePage;
break;
}
}
if (i >= kNumCodePages)
ThrowUserErrorException();
}
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 &&
options.Command.CommandType != NCommandType::kBenchmark &&
options.Command.CommandType != NCommandType::kInfo;
if (thereIsArchiveName)
{
if(curCommandIndex >= numNonSwitchStrings)
ThrowUserErrorException();
options.ArchiveName = nonSwitchStrings[curCommandIndex++];
}
AddToCensorFromNonSwitchesStrings(
curCommandIndex, options.WildcardCensor,
nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage);
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)
ThrowException("Reading archives from stdin is not implemented");
if (!options.WildcardCensor.AllAreRelative())
ThrowException("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);
if (thereIsArchiveName)
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++)
{
const CDirItem &dirItem = dirItems[i];
if (!dirItem.IsDirectory())
archivePaths.Add(dirItem.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;
SortFileNames(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 && options.IsStdErrTerminal)
throw kSameTerminalError;
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;
if(parser[NKey::kArchiveType].ThereIs)
options.ArcType = parser[NKey::kArchiveType].PostStrings[0];
SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);
SetMethodOptions(parser, updateOptions.MethodMode.Properties);
if (parser[NKey::kShareForWrite].ThereIs)
updateOptions.OpenShareForWrite = true;
options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
if (options.EnablePercents)
{
if ((options.StdOutMode && !options.IsStdErrTerminal) ||
(!options.StdOutMode && !options.IsStdOutTerminal))
options.EnablePercents = false;
}
updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
if (updateOptions.EMailMode)
{
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 if(options.Command.CommandType == NCommandType::kBenchmark)
{
options.NumThreads = (UInt32)-1;
options.DictionarySize = (UInt32)-1;
options.NumIterations = 1;
if (curCommandIndex < numNonSwitchStrings)
{
if (!ConvertStringToUInt32(nonSwitchStrings[curCommandIndex++], options.NumIterations))
ThrowUserErrorException();
}
for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
{
UString postString = parser[NKey::kProperty].PostStrings[i];
postString.MakeUpper();
if (postString.Length() < 2)
ThrowUserErrorException();
if (postString[0] == 'D')
{
int pos = 1;
if (postString[pos] == '=')
pos++;
UInt32 logSize;
if (!ConvertStringToUInt32((const wchar_t *)postString + pos, logSize))
ThrowUserErrorException();
if (logSize > 31)
ThrowUserErrorException();
options.DictionarySize = 1 << logSize;
}
else if (postString[0] == 'M' && postString[1] == 'T' )
{
int pos = 2;
if (postString[pos] == '=')
pos++;
if (postString[pos] != 0)
if (!ConvertStringToUInt32((const wchar_t *)postString + pos, options.NumThreads))
ThrowUserErrorException();
}
else if (postString[0] == 'M' && postString[1] == '=' )
{
int pos = 2;
if (postString[pos] != 0)
options.Method = postString.Mid(2);
}
else
ThrowUserErrorException();
}
}
else if(options.Command.CommandType == NCommandType::kInfo)
{
}
else
ThrowUserErrorException();
options.WildcardCensor.ExtendExclude();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -