Source code
Revision control
Copy as Markdown
Other Tools
// CommandLineParser.cpp↩
↩
#include "StdAfx.h"↩
↩
#include "CommandLineParser.h"↩
↩
namespace NCommandLineParser {↩
↩
bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)↩
{↩
dest1.Empty();↩
dest2.Empty();↩
bool quoteMode = false;↩
unsigned i;↩
for (i = 0; i < src.Len(); i++)↩
{↩
wchar_t c = src[i];↩
if ((c == L' ' || c == L'\t') && !quoteMode)↩
{↩
dest2 = src.Ptr(i + 1);↩
return i != 0;↩
}↩
if (c == L'\"')↩
quoteMode = !quoteMode;↩
else↩
dest1 += c;↩
}↩
return i != 0;↩
}↩
↩
void SplitCommandLine(const UString &s, UStringVector &parts)↩
{↩
UString sTemp (s);↩
sTemp.Trim();↩
parts.Clear();↩
for (;;)↩
{↩
UString s1, s2;↩
if (SplitCommandLine(sTemp, s1, s2))↩
parts.Add(s1);↩
if (s2.IsEmpty())↩
break;↩
sTemp = s2;↩
}↩
}↩
↩
↩
static const char * const kStopSwitchParsing = "--";↩
↩
static bool inline IsItSwitchChar(wchar_t c)↩
{↩
return (c == '-');↩
}↩
↩
CParser::CParser():↩
_switches(NULL),↩
StopSwitchIndex(-1)↩
{↩
}↩
↩
CParser::~CParser()↩
{↩
delete []_switches;↩
}↩
↩
↩
// if (s) contains switch then function updates switch structures↩
// out: true, if (s) is a switch↩
bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches)↩
{↩
if (s.IsEmpty() || !IsItSwitchChar(s[0]))↩
return false;↩
↩
unsigned pos = 1;↩
unsigned switchIndex = 0;↩
int maxLen = -1;↩
↩
for (unsigned i = 0; i < numSwitches; i++)↩
{↩
const char * const key = switchForms[i].Key;↩
unsigned switchLen = MyStringLen(key);↩
if ((int)switchLen <= maxLen || pos + switchLen > s.Len())↩
continue;↩
if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key))↩
{↩
switchIndex = i;↩
maxLen = switchLen;↩
}↩
}↩
↩
if (maxLen < 0)↩
{↩
ErrorMessage = "Unknown switch:";↩
return false;↩
}↩
↩
pos += maxLen;↩
↩
CSwitchResult &sw = _switches[switchIndex];↩
const CSwitchForm &form = switchForms[switchIndex];↩
↩
if (!form.Multi && sw.ThereIs)↩
{↩
ErrorMessage = "Multiple instances for switch:";↩
return false;↩
}↩
↩
sw.ThereIs = true;↩
↩
int rem = s.Len() - pos;↩
if (rem < form.MinLen)↩
{↩
ErrorMessage = "Too short switch:";↩
return false;↩
}↩
↩
sw.WithMinus = false;↩
sw.PostCharIndex = -1;↩
↩
switch (form.Type)↩
{↩
case NSwitchType::kMinus:↩
if (rem == 1)↩
{↩
sw.WithMinus = (s[pos] == '-');↩
if (sw.WithMinus)↩
return true;↩
ErrorMessage = "Incorrect switch postfix:";↩
return false;↩
}↩
break;↩
↩
case NSwitchType::kChar:↩
if (rem == 1)↩
{↩
wchar_t c = s[pos];↩
if (c <= 0x7F)↩
{↩
sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);↩
if (sw.PostCharIndex >= 0)↩
return true;↩
}↩
ErrorMessage = "Incorrect switch postfix:";↩
return false;↩
}↩
break;↩
↩
case NSwitchType::kString:↩
{↩
sw.PostStrings.Add(s.Ptr(pos));↩
return true;↩
}↩
}↩
↩
if (pos != s.Len())↩
{↩
ErrorMessage = "Too long switch:";↩
return false;↩
}↩
return true;↩
}↩
↩
↩
bool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings)↩
{↩
StopSwitchIndex = -1;↩
ErrorMessage.Empty();↩
ErrorLine.Empty();↩
NonSwitchStrings.Clear();↩
delete []_switches;↩
_switches = NULL;↩
_switches = new CSwitchResult[numSwitches];↩
↩
FOR_VECTOR (i, commandStrings)↩
{↩
const UString &s = commandStrings[i];↩
if (StopSwitchIndex < 0)↩
{↩
if (s.IsEqualTo(kStopSwitchParsing))↩
{↩
StopSwitchIndex = NonSwitchStrings.Size();↩
continue;↩
}↩
if (!s.IsEmpty() && IsItSwitchChar(s[0]))↩
{↩
if (ParseString(s, switchForms, numSwitches))↩
continue;↩
ErrorLine = s;↩
return false;↩
}↩
}↩
NonSwitchStrings.Add(s);↩
}↩
return true;↩
}↩
↩
}↩