|
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 } |