misc/libphysfs/lzma/CPP/Common/CommandLineParser.cpp
changeset 12218 bb5522e88ab2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/CommandLineParser.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,232 @@
+// CommandLineParser.cpp
+
+#include "StdAfx.h"
+
+#include "CommandLineParser.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
+{
+  dest1.Empty();
+  dest2.Empty();
+  bool quoteMode = false;
+  int i;
+  for (i = 0; i < src.Length(); i++)
+  {
+    wchar_t c = src[i];
+    if (c == L'\"')
+      quoteMode = !quoteMode;
+    else if (c == L' ' && !quoteMode)
+    {
+      i++;
+      break;
+    }
+    else 
+      dest1 += c;
+  }
+  dest2 = src.Mid(i);
+}
+
+void SplitCommandLine(const UString &s, UStringVector &parts)
+{
+  UString sTemp = s;
+  sTemp.Trim();
+  parts.Clear();
+  for (;;)
+  {
+    UString s1, s2;
+    SplitCommandLine(sTemp, s1, s2);
+    // s1.Trim();
+    // s2.Trim();
+    if (!s1.IsEmpty())
+      parts.Add(s1);
+    if (s2.IsEmpty())
+      break;
+    sTemp = s2;
+  }
+}
+
+
+static const wchar_t kSwitchID1 = '-';
+// static const wchar_t kSwitchID2 = '/';
+
+static const wchar_t kSwitchMinus = '-';
+static const wchar_t *kStopSwitchParsing = L"--";
+
+static bool IsItSwitchChar(wchar_t c)
+{ 
+  return (c == kSwitchID1 /*|| c == kSwitchID2 */); 
+}
+
+CParser::CParser(int numSwitches):
+  _numSwitches(numSwitches)
+{
+  _switches = new CSwitchResult[_numSwitches];
+}
+
+CParser::~CParser()
+{
+  delete []_switches;
+}
+
+void CParser::ParseStrings(const CSwitchForm *switchForms, 
+  const UStringVector &commandStrings)
+{
+  int numCommandStrings = commandStrings.Size();
+  bool stopSwitch = false;
+  for (int i = 0; i < numCommandStrings; i++)
+  {
+    const UString &s = commandStrings[i];
+    if (stopSwitch)
+      NonSwitchStrings.Add(s);
+    else
+      if (s == kStopSwitchParsing)
+        stopSwitch = true;
+      else
+        if (!ParseString(s, switchForms))
+          NonSwitchStrings.Add(s);
+  }
+}
+
+// if string contains switch then function updates switch structures
+// out: (string is a switch)
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
+{
+  int len = s.Length();
+  if (len == 0) 
+    return false;
+  int pos = 0;
+  if (!IsItSwitchChar(s[pos]))
+    return false;
+  while(pos < len)
+  {
+    if (IsItSwitchChar(s[pos]))
+      pos++;
+    const int kNoLen = -1;
+    int matchedSwitchIndex = 0; // GCC Warning
+    int maxLen = kNoLen;
+    for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
+    {
+      int switchLen = MyStringLen(switchForms[switchIndex].IDString);
+      if (switchLen <= maxLen || pos + switchLen > len) 
+        continue;
+
+      UString temp = s + pos;
+      temp = temp.Left(switchLen);
+      if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
+      // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
+      {
+        matchedSwitchIndex = switchIndex;
+        maxLen = switchLen;
+      }
+    }
+    if (maxLen == kNoLen)
+      throw "maxLen == kNoLen";
+    CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
+    const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
+    if ((!switchForm.Multi) && matchedSwitch.ThereIs)
+      throw "switch must be single";
+    matchedSwitch.ThereIs = true;
+    pos += maxLen;
+    int tailSize = len - pos;
+    NSwitchType::EEnum type = switchForm.Type;
+    switch(type)
+    {
+      case NSwitchType::kPostMinus:
+        {
+          if (tailSize == 0)
+            matchedSwitch.WithMinus = false;
+          else
+          {
+            matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
+            if (matchedSwitch.WithMinus)
+              pos++;
+          }
+          break;
+        }
+      case NSwitchType::kPostChar:
+        {
+          if (tailSize < switchForm.MinLen)
+            throw "switch is not full";
+          UString set = switchForm.PostCharSet;
+          const int kEmptyCharValue = -1;
+          if (tailSize == 0)
+            matchedSwitch.PostCharIndex = kEmptyCharValue;
+          else
+          {
+            int index = set.Find(s[pos]);
+            if (index < 0)
+              matchedSwitch.PostCharIndex =  kEmptyCharValue;
+            else
+            {
+              matchedSwitch.PostCharIndex = index;
+              pos++;
+            }
+          }
+          break;
+        }
+      case NSwitchType::kLimitedPostString: 
+      case NSwitchType::kUnLimitedPostString: 
+        {
+          int minLen = switchForm.MinLen;
+          if (tailSize < minLen)
+            throw "switch is not full";
+          if (type == NSwitchType::kUnLimitedPostString)
+          {
+            matchedSwitch.PostStrings.Add(s.Mid(pos));
+            return true;
+          }
+          int maxLen = switchForm.MaxLen;
+          UString stringSwitch = s.Mid(pos, minLen);
+          pos += minLen;
+          for(int i = minLen; i < maxLen && pos < len; i++, pos++)
+          {
+            wchar_t c = s[pos];
+            if (IsItSwitchChar(c))
+              break;
+            stringSwitch += c;
+          }
+          matchedSwitch.PostStrings.Add(stringSwitch);
+          break;
+        }
+      case NSwitchType::kSimple:
+          break;
+    }
+  }
+  return true;
+}
+
+const CSwitchResult& CParser::operator[](size_t index) const
+{
+  return _switches[index];
+}
+
+/////////////////////////////////
+// Command parsing procedures
+
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms, 
+    const UString &commandString, UString &postString)
+{
+  for(int i = 0; i < numCommandForms; i++)
+  {
+    const UString id = commandForms[i].IDString;
+    if (commandForms[i].PostStringMode)
+    {
+      if(commandString.Find(id) == 0)
+      {
+        postString = commandString.Mid(id.Length());
+        return i;
+      }
+    }
+    else
+      if (commandString == id)
+      {
+        postString.Empty();
+        return i;
+      }
+  }
+  return -1;
+}
+   
+}