tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CommandLineParser.cpp (4104B)


      1 // CommandLineParser.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "CommandLineParser.h"
      6 
      7 namespace NCommandLineParser {
      8 
      9 bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
     10 {
     11  dest1.Empty();
     12  dest2.Empty();
     13  bool quoteMode = false;
     14  unsigned i;
     15  for (i = 0; i < src.Len(); i++)
     16  {
     17    wchar_t c = src[i];
     18    if ((c == L' ' || c == L'\t') && !quoteMode)
     19    {
     20      dest2 = src.Ptr(i + 1);
     21      return i != 0;
     22    }
     23    if (c == L'\"')
     24      quoteMode = !quoteMode;
     25    else
     26      dest1 += c;
     27  }
     28  return i != 0;
     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    if (SplitCommandLine(sTemp, s1, s2))
     40      parts.Add(s1);
     41    if (s2.IsEmpty())
     42      break;
     43    sTemp = s2;
     44  }
     45 }
     46 
     47 
     48 static const char * const kStopSwitchParsing = "--";
     49 
     50 static bool inline IsItSwitchChar(wchar_t c)
     51 {
     52  return (c == '-');
     53 }
     54 
     55 CParser::CParser():
     56  _switches(NULL),
     57  StopSwitchIndex(-1)
     58 {
     59 }
     60 
     61 CParser::~CParser()
     62 {
     63  delete []_switches;
     64 }
     65 
     66 
     67 // if (s) contains switch then function updates switch structures
     68 // out: true, if (s) is a switch
     69 bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches)
     70 {
     71  if (s.IsEmpty() || !IsItSwitchChar(s[0]))
     72    return false;
     73 
     74  unsigned pos = 1;
     75  unsigned switchIndex = 0;
     76  int maxLen = -1;
     77  
     78  for (unsigned i = 0; i < numSwitches; i++)
     79  {
     80    const char * const key = switchForms[i].Key;
     81    unsigned switchLen = MyStringLen(key);
     82    if ((int)switchLen <= maxLen || pos + switchLen > s.Len())
     83      continue;
     84    if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key))
     85    {
     86      switchIndex = i;
     87      maxLen = switchLen;
     88    }
     89  }
     90 
     91  if (maxLen < 0)
     92  {
     93    ErrorMessage = "Unknown switch:";
     94    return false;
     95  }
     96 
     97  pos += maxLen;
     98  
     99  CSwitchResult &sw = _switches[switchIndex];
    100  const CSwitchForm &form = switchForms[switchIndex];
    101  
    102  if (!form.Multi && sw.ThereIs)
    103  {
    104    ErrorMessage = "Multiple instances for switch:";
    105    return false;
    106  }
    107 
    108  sw.ThereIs = true;
    109 
    110  int rem = s.Len() - pos;
    111  if (rem < form.MinLen)
    112  {
    113    ErrorMessage = "Too short switch:";
    114    return false;
    115  }
    116  
    117  sw.WithMinus = false;
    118  sw.PostCharIndex = -1;
    119  
    120  switch (form.Type)
    121  {
    122    case NSwitchType::kMinus:
    123      if (rem == 1)
    124      {
    125        sw.WithMinus = (s[pos] == '-');
    126        if (sw.WithMinus)
    127          return true;
    128        ErrorMessage = "Incorrect switch postfix:";
    129        return false;
    130      }
    131      break;
    132      
    133    case NSwitchType::kChar:
    134      if (rem == 1)
    135      {
    136        wchar_t c = s[pos];
    137        if (c <= 0x7F)
    138        {
    139          sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
    140          if (sw.PostCharIndex >= 0)
    141            return true;
    142        }
    143        ErrorMessage = "Incorrect switch postfix:";
    144        return false;
    145      }
    146      break;
    147      
    148    case NSwitchType::kString:
    149    {
    150      sw.PostStrings.Add(s.Ptr(pos));
    151      return true;
    152    }
    153  }
    154 
    155  if (pos != s.Len())
    156  {
    157    ErrorMessage = "Too long switch:";
    158    return false;
    159  }
    160  return true;
    161 }
    162 
    163 
    164 bool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings)
    165 {
    166  StopSwitchIndex = -1;
    167  ErrorMessage.Empty();
    168  ErrorLine.Empty();
    169  NonSwitchStrings.Clear();
    170  delete []_switches;
    171  _switches = NULL;
    172  _switches = new CSwitchResult[numSwitches];
    173  
    174  FOR_VECTOR (i, commandStrings)
    175  {
    176    const UString &s = commandStrings[i];
    177    if (StopSwitchIndex < 0)
    178    {
    179      if (s.IsEqualTo(kStopSwitchParsing))
    180      {
    181        StopSwitchIndex = NonSwitchStrings.Size();
    182        continue;
    183      }
    184      if (!s.IsEmpty() && IsItSwitchChar(s[0]))
    185      {
    186        if (ParseString(s, switchForms, numSwitches))
    187          continue;
    188        ErrorLine = s;
    189        return false;
    190      }
    191    }
    192    NonSwitchStrings.Add(s);
    193  }
    194  return true;
    195 }
    196 
    197 }