misc/libphysfs/lzma/CPP/Common/CommandLineParser.cpp
changeset 12218 bb5522e88ab2
equal deleted inserted replaced
12217:ea891871f481 12218:bb5522e88ab2
       
     1 // CommandLineParser.cpp
       
     2 
       
     3 #include "StdAfx.h"
       
     4 
       
     5 #include "CommandLineParser.h"
       
     6 
       
     7 namespace NCommandLineParser {
       
     8 
       
     9 void SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
       
    10 {
       
    11   dest1.Empty();
       
    12   dest2.Empty();
       
    13   bool quoteMode = false;
       
    14   int i;
       
    15   for (i = 0; i < src.Length(); i++)
       
    16   {
       
    17     wchar_t c = src[i];
       
    18     if (c == L'\"')
       
    19       quoteMode = !quoteMode;
       
    20     else if (c == L' ' && !quoteMode)
       
    21     {
       
    22       i++;
       
    23       break;
       
    24     }
       
    25     else 
       
    26       dest1 += c;
       
    27   }
       
    28   dest2 = src.Mid(i);
       
    29 }
       
    30 
       
    31 void SplitCommandLine(const UString &s, UStringVector &parts)
       
    32 {
       
    33   UString sTemp = s;
       
    34   sTemp.Trim();
       
    35   parts.Clear();
       
    36   for (;;)
       
    37   {
       
    38     UString s1, s2;
       
    39     SplitCommandLine(sTemp, s1, s2);
       
    40     // s1.Trim();
       
    41     // s2.Trim();
       
    42     if (!s1.IsEmpty())
       
    43       parts.Add(s1);
       
    44     if (s2.IsEmpty())
       
    45       break;
       
    46     sTemp = s2;
       
    47   }
       
    48 }
       
    49 
       
    50 
       
    51 static const wchar_t kSwitchID1 = '-';
       
    52 // static const wchar_t kSwitchID2 = '/';
       
    53 
       
    54 static const wchar_t kSwitchMinus = '-';
       
    55 static const wchar_t *kStopSwitchParsing = L"--";
       
    56 
       
    57 static bool IsItSwitchChar(wchar_t c)
       
    58 { 
       
    59   return (c == kSwitchID1 /*|| c == kSwitchID2 */); 
       
    60 }
       
    61 
       
    62 CParser::CParser(int numSwitches):
       
    63   _numSwitches(numSwitches)
       
    64 {
       
    65   _switches = new CSwitchResult[_numSwitches];
       
    66 }
       
    67 
       
    68 CParser::~CParser()
       
    69 {
       
    70   delete []_switches;
       
    71 }
       
    72 
       
    73 void CParser::ParseStrings(const CSwitchForm *switchForms, 
       
    74   const UStringVector &commandStrings)
       
    75 {
       
    76   int numCommandStrings = commandStrings.Size();
       
    77   bool stopSwitch = false;
       
    78   for (int i = 0; i < numCommandStrings; i++)
       
    79   {
       
    80     const UString &s = commandStrings[i];
       
    81     if (stopSwitch)
       
    82       NonSwitchStrings.Add(s);
       
    83     else
       
    84       if (s == kStopSwitchParsing)
       
    85         stopSwitch = true;
       
    86       else
       
    87         if (!ParseString(s, switchForms))
       
    88           NonSwitchStrings.Add(s);
       
    89   }
       
    90 }
       
    91 
       
    92 // if string contains switch then function updates switch structures
       
    93 // out: (string is a switch)
       
    94 bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
       
    95 {
       
    96   int len = s.Length();
       
    97   if (len == 0) 
       
    98     return false;
       
    99   int pos = 0;
       
   100   if (!IsItSwitchChar(s[pos]))
       
   101     return false;
       
   102   while(pos < len)
       
   103   {
       
   104     if (IsItSwitchChar(s[pos]))
       
   105       pos++;
       
   106     const int kNoLen = -1;
       
   107     int matchedSwitchIndex = 0; // GCC Warning
       
   108     int maxLen = kNoLen;
       
   109     for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
       
   110     {
       
   111       int switchLen = MyStringLen(switchForms[switchIndex].IDString);
       
   112       if (switchLen <= maxLen || pos + switchLen > len) 
       
   113         continue;
       
   114 
       
   115       UString temp = s + pos;
       
   116       temp = temp.Left(switchLen);
       
   117       if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
       
   118       // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
       
   119       {
       
   120         matchedSwitchIndex = switchIndex;
       
   121         maxLen = switchLen;
       
   122       }
       
   123     }
       
   124     if (maxLen == kNoLen)
       
   125       throw "maxLen == kNoLen";
       
   126     CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
       
   127     const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
       
   128     if ((!switchForm.Multi) && matchedSwitch.ThereIs)
       
   129       throw "switch must be single";
       
   130     matchedSwitch.ThereIs = true;
       
   131     pos += maxLen;
       
   132     int tailSize = len - pos;
       
   133     NSwitchType::EEnum type = switchForm.Type;
       
   134     switch(type)
       
   135     {
       
   136       case NSwitchType::kPostMinus:
       
   137         {
       
   138           if (tailSize == 0)
       
   139             matchedSwitch.WithMinus = false;
       
   140           else
       
   141           {
       
   142             matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
       
   143             if (matchedSwitch.WithMinus)
       
   144               pos++;
       
   145           }
       
   146           break;
       
   147         }
       
   148       case NSwitchType::kPostChar:
       
   149         {
       
   150           if (tailSize < switchForm.MinLen)
       
   151             throw "switch is not full";
       
   152           UString set = switchForm.PostCharSet;
       
   153           const int kEmptyCharValue = -1;
       
   154           if (tailSize == 0)
       
   155             matchedSwitch.PostCharIndex = kEmptyCharValue;
       
   156           else
       
   157           {
       
   158             int index = set.Find(s[pos]);
       
   159             if (index < 0)
       
   160               matchedSwitch.PostCharIndex =  kEmptyCharValue;
       
   161             else
       
   162             {
       
   163               matchedSwitch.PostCharIndex = index;
       
   164               pos++;
       
   165             }
       
   166           }
       
   167           break;
       
   168         }
       
   169       case NSwitchType::kLimitedPostString: 
       
   170       case NSwitchType::kUnLimitedPostString: 
       
   171         {
       
   172           int minLen = switchForm.MinLen;
       
   173           if (tailSize < minLen)
       
   174             throw "switch is not full";
       
   175           if (type == NSwitchType::kUnLimitedPostString)
       
   176           {
       
   177             matchedSwitch.PostStrings.Add(s.Mid(pos));
       
   178             return true;
       
   179           }
       
   180           int maxLen = switchForm.MaxLen;
       
   181           UString stringSwitch = s.Mid(pos, minLen);
       
   182           pos += minLen;
       
   183           for(int i = minLen; i < maxLen && pos < len; i++, pos++)
       
   184           {
       
   185             wchar_t c = s[pos];
       
   186             if (IsItSwitchChar(c))
       
   187               break;
       
   188             stringSwitch += c;
       
   189           }
       
   190           matchedSwitch.PostStrings.Add(stringSwitch);
       
   191           break;
       
   192         }
       
   193       case NSwitchType::kSimple:
       
   194           break;
       
   195     }
       
   196   }
       
   197   return true;
       
   198 }
       
   199 
       
   200 const CSwitchResult& CParser::operator[](size_t index) const
       
   201 {
       
   202   return _switches[index];
       
   203 }
       
   204 
       
   205 /////////////////////////////////
       
   206 // Command parsing procedures
       
   207 
       
   208 int ParseCommand(int numCommandForms, const CCommandForm *commandForms, 
       
   209     const UString &commandString, UString &postString)
       
   210 {
       
   211   for(int i = 0; i < numCommandForms; i++)
       
   212   {
       
   213     const UString id = commandForms[i].IDString;
       
   214     if (commandForms[i].PostStringMode)
       
   215     {
       
   216       if(commandString.Find(id) == 0)
       
   217       {
       
   218         postString = commandString.Mid(id.Length());
       
   219         return i;
       
   220       }
       
   221     }
       
   222     else
       
   223       if (commandString == id)
       
   224       {
       
   225         postString.Empty();
       
   226         return i;
       
   227       }
       
   228   }
       
   229   return -1;
       
   230 }
       
   231    
       
   232 }