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.

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

mercurial