summaryrefslogtreecommitdiffstats
path: root/other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp')
-rw-r--r--other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp197
1 files changed, 197 insertions, 0 deletions
diff --git a/other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp b/other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp
new file mode 100644
index 000000000..94aabce6d
--- /dev/null
+++ b/other-licenses/7zstub/src/CPP/Common/CommandLineParser.cpp
@@ -0,0 +1,197 @@
+// 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;
+}
+
+}