1 //===-- MICmdArgValOptionLong.cpp -------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // In-house headers:
11 #include "MICmdArgValOptionLong.h"
12 #include "MICmdArgContext.h"
13
14 //++
15 //------------------------------------------------------------------------------------
16 // Details: CMICmdArgValOptionLong constructor.
17 // Type: Method.
18 // Args: None.
19 // Return: None.
20 // Throws: None.
21 //--
CMICmdArgValOptionLong()22 CMICmdArgValOptionLong::CMICmdArgValOptionLong()
23 : m_nExpectingNOptions(0), m_eExpectingOptionType(eArgValType_invalid) {}
24
25 //++
26 //------------------------------------------------------------------------------------
27 // Details: CMICmdArgValOptionLong constructor.
28 // Type: Method.
29 // Args: vrArgName - (R) Argument's name to search by.
30 // vbMandatory - (R) True = Yes must be present, false = optional
31 // argument.
32 // vbHandleByCmd - (R) True = Command processes *this option, false =
33 // not handled.
34 // Return: None.
35 // Throws: None.
36 //--
CMICmdArgValOptionLong(const CMIUtilString & vrArgName,const bool vbMandatory,const bool vbHandleByCmd)37 CMICmdArgValOptionLong::CMICmdArgValOptionLong(const CMIUtilString &vrArgName,
38 const bool vbMandatory,
39 const bool vbHandleByCmd)
40 : CMICmdArgValListBase(vrArgName, vbMandatory, vbHandleByCmd),
41 m_nExpectingNOptions(0), m_eExpectingOptionType(eArgValType_invalid) {}
42
43 //++
44 //------------------------------------------------------------------------------------
45 // Details: CMICmdArgValOptionLong constructor.
46 // Type: Method.
47 // Args: vrArgName - (R) Argument's name to search by.
48 // vbMandatory - (R) True = Yes must be present, false =
49 // optional argument.
50 // vbHandleByCmd - (R) True = Command processes *this option,
51 // false = not handled.
52 // veType - (R) The type of argument to look for and
53 // create argument object of a certain type.
54 // vnExpectingNOptions - (R) The number of options expected to read
55 // following *this argument.
56 // Return: None.
57 // Throws: None.
58 //--
CMICmdArgValOptionLong(const CMIUtilString & vrArgName,const bool vbMandatory,const bool vbHandleByCmd,const ArgValType_e veType,const MIuint vnExpectingNOptions)59 CMICmdArgValOptionLong::CMICmdArgValOptionLong(const CMIUtilString &vrArgName,
60 const bool vbMandatory,
61 const bool vbHandleByCmd,
62 const ArgValType_e veType,
63 const MIuint vnExpectingNOptions)
64 : CMICmdArgValListBase(vrArgName, vbMandatory, vbHandleByCmd),
65 m_nExpectingNOptions(vnExpectingNOptions),
66 m_eExpectingOptionType(veType) {}
67
68 //++
69 //------------------------------------------------------------------------------------
70 // Details: CMICmdArgValOptionLong destructor.
71 // Type: Overridden.
72 // Args: None.
73 // Return: None.
74 // Throws: None.
75 //--
~CMICmdArgValOptionLong()76 CMICmdArgValOptionLong::~CMICmdArgValOptionLong() {
77 // Tidy up
78 Destroy();
79 }
80
81 //++
82 //------------------------------------------------------------------------------------
83 // Details: Tear down resources used by *this object.
84 // Type: Method.
85 // Args: None.
86 // Return: None.
87 // Throws: None.
88 //--
Destroy()89 void CMICmdArgValOptionLong::Destroy() {
90 // Tidy up
91 VecArgObjPtr_t::const_iterator it = m_vecArgsExpected.begin();
92 while (it != m_vecArgsExpected.end()) {
93 CMICmdArgValBase *pOptionObj = *it;
94 delete pOptionObj;
95
96 // Next
97 ++it;
98 }
99 m_vecArgsExpected.clear();
100 }
101
102 //++
103 //------------------------------------------------------------------------------------
104 // Details: Parse the command's argument options string and try to extract the
105 // long
106 // argument *this argument type is looking for.
107 // Type: Overridden.
108 // Args: vwArgContext - (RW) The command's argument options string.
109 // Return: MIstatus::success - Functional succeeded.
110 // MIstatus::failure - Functional failed.
111 // Throws: None.
112 //--
Validate(CMICmdArgContext & vwArgContext)113 bool CMICmdArgValOptionLong::Validate(CMICmdArgContext &vwArgContext) {
114 if (vwArgContext.IsEmpty())
115 return m_bMandatory ? MIstatus::failure : MIstatus::success;
116
117 if (vwArgContext.GetNumberArgsPresent() == 1) {
118 const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse());
119 if (IsArgLongOption(rArg) && ArgNameMatch(rArg)) {
120 m_bFound = true;
121
122 if (!vwArgContext.RemoveArg(rArg))
123 return MIstatus::failure;
124
125 if (m_nExpectingNOptions == 0) {
126 m_bValid = true;
127 return MIstatus::success;
128 }
129
130 m_bIsMissingOptions = true;
131 return MIstatus::failure;
132 } else
133 return MIstatus::failure;
134 }
135
136 // More than one option...
137 MIuint nArgIndex = 0;
138 const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
139 CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
140 while (it != vecOptions.end()) {
141 const CMIUtilString &rArg(*it);
142 if (IsArgOptionCorrect(rArg) && ArgNameMatch(rArg)) {
143 m_bFound = true;
144
145 if (!vwArgContext.RemoveArg(rArg))
146 return MIstatus::failure;
147
148 if (m_nExpectingNOptions != 0) {
149 if (ExtractExpectedOptions(vwArgContext, nArgIndex)) {
150 m_bValid = true;
151 return MIstatus::success;
152 }
153
154 m_bIsMissingOptions = true;
155 return MIstatus::failure;
156 } else {
157 m_bValid = true;
158 return MIstatus::success;
159 }
160 }
161
162 // Next
163 ++it;
164 ++nArgIndex;
165 }
166
167 return MIstatus::failure;
168 }
169
170 //++
171 //------------------------------------------------------------------------------------
172 // Details: Parse the text following *this argument and extract the options the
173 // values of
174 // CMICmdArgValListBase::m_eArgType forming argument objects for each
175 // of those
176 // options extracted.
177 // Type: Method.
178 // Args: vrwTxt - (RW) The command's argument options string.
179 // nArgIndex - (R) The Nth arg position in argument context from
180 // the left.
181 // Return: MIstatus::success - Functional succeeded.
182 // MIstatus::failure - Functional failed.
183 // Throws: None.
184 //--
ExtractExpectedOptions(CMICmdArgContext & vrwTxt,const MIuint nArgIndex)185 bool CMICmdArgValOptionLong::ExtractExpectedOptions(CMICmdArgContext &vrwTxt,
186 const MIuint nArgIndex) {
187 CMIUtilString::VecString_t vecOptions = vrwTxt.GetArgs();
188 if (vecOptions.size() == 0)
189 return MIstatus::failure;
190
191 MIuint nArgIndexCnt = 0;
192 MIuint nTypeCnt = 0;
193 MIuint nTypeCnt2 = 0;
194 MIuint nFoundNOptionsCnt = 0;
195 CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
196 while (it != vecOptions.end()) {
197 // Move to the Nth argument position from left before do validation/checking
198 if (nArgIndexCnt++ == nArgIndex) {
199 nTypeCnt++;
200 const CMIUtilString &rOption(*it);
201 if (IsExpectedCorrectType(rOption, m_eExpectingOptionType)) {
202 nTypeCnt2++;
203 CMICmdArgValBase *pOptionObj =
204 CreationObj(rOption, m_eExpectingOptionType);
205 if ((pOptionObj != nullptr) &&
206 vrwTxt.RemoveArgAtPos(rOption, nArgIndex)) {
207 nFoundNOptionsCnt++;
208 m_vecArgsExpected.push_back(pOptionObj);
209 }
210 }
211
212 // Is the sequence 'options' of same type broken. Expecting the same type
213 // until the
214 // next argument.
215 if (nTypeCnt != nTypeCnt2)
216 return MIstatus::failure;
217
218 if (nFoundNOptionsCnt == m_nExpectingNOptions)
219 return MIstatus::success;
220 }
221
222 // Next
223 ++it;
224 }
225 if (nFoundNOptionsCnt != m_nExpectingNOptions)
226 return MIstatus::failure;
227
228 return MIstatus::success;
229 }
230
231 //++
232 //------------------------------------------------------------------------------------
233 // Details: Examine the string and determine if it is a valid long type option
234 // argument.
235 // Long type argument looks like --someLongOption.
236 // Type: Method.
237 // Args: vrTxt - (R) Some text.
238 // Return: bool - True = yes valid arg, false = no.
239 // Throws: None.
240 //--
IsArgLongOption(const CMIUtilString & vrTxt) const241 bool CMICmdArgValOptionLong::IsArgLongOption(const CMIUtilString &vrTxt) const {
242 const bool bHavePosSlash = (vrTxt.find('/') != std::string::npos);
243 const bool bHaveBckSlash = (vrTxt.find('\\') != std::string::npos);
244 if (bHavePosSlash || bHaveBckSlash)
245 return false;
246
247 const size_t nPos = vrTxt.find("--");
248 if (nPos != 0)
249 return false;
250
251 if (vrTxt.length() < 3)
252 return false;
253
254 const CMIUtilString strArg = vrTxt.substr(2);
255 return !strArg.IsNumber();
256 }
257
258 //++
259 //------------------------------------------------------------------------------------
260 // Details: Examine the string and determine if it is a valid long type option
261 // argument.
262 // Long type argument looks like --someLongOption.
263 // Type: Overideable.
264 // Args: vrTxt - (R) Some text.
265 // Return: bool - True = yes valid arg, false = no.
266 // Throws: None.
267 //--
IsArgOptionCorrect(const CMIUtilString & vrTxt) const268 bool CMICmdArgValOptionLong::IsArgOptionCorrect(
269 const CMIUtilString &vrTxt) const {
270 return IsArgLongOption(vrTxt);
271 }
272
273 //++
274 //------------------------------------------------------------------------------------
275 // Details: Does the argument name of the argument being parsed ATM match the
276 // name of
277 // *this argument object.
278 // Type: Method.
279 // Args: vrTxt - (R) Some text.
280 // Return: bool - True = yes arg name matched, false = no.
281 // Throws: None.
282 //--
ArgNameMatch(const CMIUtilString & vrTxt) const283 bool CMICmdArgValOptionLong::ArgNameMatch(const CMIUtilString &vrTxt) const {
284 const CMIUtilString strArg = vrTxt.substr(2);
285 return (strArg == GetName());
286 }
287
288 //++
289 //------------------------------------------------------------------------------------
290 // Details: Retrieve the list of CMICmdArgValBase derived option objects found
291 // following
292 // *this long option argument. For example "list-thread-groups [
293 // --recurse 1 ]"
294 // where 1 is the list of expected option to follow.
295 // Type: Method.
296 // Args: None.
297 // Return: CMICmdArgValListBase::VecArgObjPtr_t & - List of options.
298 // Throws: None.
299 //--
300 const CMICmdArgValListBase::VecArgObjPtr_t &
GetExpectedOptions() const301 CMICmdArgValOptionLong::GetExpectedOptions() const {
302 return m_vecArgsExpected;
303 }
304