other-licenses/7zstub/src/Common/CommandLineParser.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 // CommandLineParser.cpp
     3 #include "StdAfx.h"
     5 #include "CommandLineParser.h"
     7 namespace NCommandLineParser {
     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 }
    31 void SplitCommandLine(const UString &s, UStringVector &parts)
    32 {
    33   UString sTemp = s;
    34   sTemp.Trim();
    35   parts.Clear();
    36   while (true)
    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       return;
    46     sTemp = s2;
    47   }
    48 }
    51 static const wchar_t kSwitchID1 = '-';
    52 // static const wchar_t kSwitchID2 = '/';
    54 static const wchar_t kSwitchMinus = '-';
    55 static const wchar_t *kStopSwitchParsing = L"--";
    57 static bool IsItSwitchChar(wchar_t c)
    58 { 
    59   return (c == kSwitchID1 /*|| c == kSwitchID2 */); 
    60 }
    62 CParser::CParser(int numSwitches):
    63   _numSwitches(numSwitches)
    64 {
    65   _switches = new CSwitchResult[_numSwitches];
    66 }
    68 CParser::~CParser()
    69 {
    70   delete []_switches;
    71 }
    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 }
    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;
   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 }
   200 const CSwitchResult& CParser::operator[](size_t index) const
   201 {
   202   return _switches[index];
   203 }
   205 /////////////////////////////////
   206 // Command parsing procedures
   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 }
   232 }

mercurial