1 //===-- MICmdArgSet.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 "MICmdArgSet.h"
12 #include "MICmdArgValBase.h"
13 #include "MICmnLog.h"
14 #include "MICmnResources.h"
15
16 //++
17 //------------------------------------------------------------------------------------
18 // Details: CMICmdArgSet constructor.
19 // Type: Method.
20 // Args: None.
21 // Return: None.
22 // Throws: None.
23 //--
CMICmdArgSet()24 CMICmdArgSet::CMICmdArgSet()
25 : m_bIsArgsPresentButNotHandledByCmd(false), m_constStrCommaSpc(", ") {}
26
27 //++
28 //------------------------------------------------------------------------------------
29 // Details: CMICmdArgSet destructor.
30 // Type: Method.
31 // Args: None.
32 // Return: None.
33 // Throws: None.
34 //--
~CMICmdArgSet()35 CMICmdArgSet::~CMICmdArgSet() {
36 // Tidy up
37 Destroy();
38 }
39
40 //++
41 //------------------------------------------------------------------------------------
42 // Details: Release resources used by *this container object.
43 // Type: Method.
44 // Args: None.
45 // Return: None.
46 // Throws: None.
47 //--
Destroy()48 void CMICmdArgSet::Destroy() {
49 // Delete command argument objects
50 if (!m_setCmdArgs.empty()) {
51 SetCmdArgs_t::iterator it = m_setCmdArgs.begin();
52 while (it != m_setCmdArgs.end()) {
53 CMICmdArgValBase *pArg(*it);
54 delete pArg;
55
56 // Next
57 ++it;
58 }
59 m_setCmdArgs.clear();
60 }
61
62 m_setCmdArgsThatNotValid.clear();
63 m_setCmdArgsThatAreMissing.clear();
64 m_setCmdArgsNotHandledByCmd.clear();
65 m_setCmdArgsMissingInfo.clear();
66 m_bIsArgsPresentButNotHandledByCmd = false;
67 }
68
69 //++
70 //------------------------------------------------------------------------------------
71 // Details: Retrieve the state flag indicating that the command set up ready to
72 // parse
73 // command arguments or options found that one or more arguments was
74 // indeed
75 // present but not handled. This is given as a warning in the MI log
76 // file.
77 // Type: Method.
78 // Args: None.
79 // Return: bool - True = one or more args not handled, false = all args handled
80 // Throws: None.
81 //--
IsArgsPresentButNotHandledByCmd() const82 bool CMICmdArgSet::IsArgsPresentButNotHandledByCmd() const {
83 return m_bIsArgsPresentButNotHandledByCmd;
84 }
85
86 //++
87 //------------------------------------------------------------------------------------
88 // Details: Add the list of command's arguments to parse and validate another
89 // one.
90 // Type: Method.
91 // Args: vArg - (R) A command argument object.
92 // Return: None.
93 // Throws: None.
94 //--
Add(CMICmdArgValBase * vArg)95 void CMICmdArgSet::Add(CMICmdArgValBase *vArg) { m_setCmdArgs.push_back(vArg); }
96
97 //++
98 //------------------------------------------------------------------------------------
99 // Details: After validating an options line of text (the context) and there is
100 // a failure,
101 // it is likely a mandatory command argument that is required is
102 // missing. This
103 // function returns the argument that should be present.
104 // Type: Method.
105 // Args: None.
106 // Return: SetCmdArgs_t & - Set of argument objects.
107 // Throws: None.
108 //--
GetArgsThatAreMissing() const109 const CMICmdArgSet::SetCmdArgs_t &CMICmdArgSet::GetArgsThatAreMissing() const {
110 return m_setCmdArgsThatAreMissing;
111 }
112
113 //++
114 //------------------------------------------------------------------------------------
115 // Details: After validating an options line of text (the context) and there is
116 // a failure,
117 // it may be because one or more arguments were unable to extract a
118 // value. This
119 // function returns the argument that were found to be invalid.
120 // Type: Method.
121 // Args: None.
122 // Return: SetCmdArgs_t & - Set of argument objects.
123 // Throws: None.
124 //--
GetArgsThatInvalid() const125 const CMICmdArgSet::SetCmdArgs_t &CMICmdArgSet::GetArgsThatInvalid() const {
126 return m_setCmdArgsThatNotValid;
127 }
128
129 //++
130 //------------------------------------------------------------------------------------
131 // Details: The list of argument or option (objects) that were specified by the
132 // command
133 // and so recognised when parsed but were not handled. Ideally the
134 // command
135 // should handle all arguments and options presented to it. The command
136 // sends
137 // warning to the MI log file to say that these options were not
138 // handled.
139 // Used as one way to determine option that maybe should really be
140 // implemented
141 // and not just ignored.
142 // Type: Method.
143 // Args: None.
144 // Return: SetCmdArgs_t & - Set of argument objects.
145 // Throws: None.
146 //--
GetArgsNotHandledByCmd() const147 const CMICmdArgSet::SetCmdArgs_t &CMICmdArgSet::GetArgsNotHandledByCmd() const {
148 return m_setCmdArgsNotHandledByCmd;
149 }
150
151 //++
152 //------------------------------------------------------------------------------------
153 // Details: Given a set of command argument objects parse the context option
154 // string to
155 // find those argument and retrieve their value. If the function fails
156 // call
157 // GetArgsThatAreMissing() to see which commands that were mandatory
158 // were
159 // missing or failed to parse.
160 // Type: Method.
161 // Args: vStrMiCmd - (R) Command's name.
162 // vCmdArgsText - (RW) A command's options or argument.
163 // Return: MIstatus::success - Functional succeeded.
164 // MIstatus::failure - Functional failed.
165 // Throws: None.
166 //--
Validate(const CMIUtilString & vStrMiCmd,CMICmdArgContext & vwCmdArgsText)167 bool CMICmdArgSet::Validate(const CMIUtilString &vStrMiCmd,
168 CMICmdArgContext &vwCmdArgsText) {
169 m_cmdArgContext = vwCmdArgsText;
170
171 // Iterate all the arguments or options required by a command
172 SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
173 while (it != m_setCmdArgs.end()) {
174 CMICmdArgValBase *pArg = *it;
175
176 if (!pArg->Validate(vwCmdArgsText)) {
177 if (pArg->GetFound()) {
178 if (pArg->GetIsMissingOptions())
179 m_setCmdArgsMissingInfo.push_back(pArg);
180 else if (!pArg->GetValid())
181 m_setCmdArgsThatNotValid.push_back(pArg);
182 } else if (pArg->GetIsMandatory())
183 m_setCmdArgsThatAreMissing.push_back(pArg);
184 }
185
186 if (pArg->GetFound() && !pArg->GetIsHandledByCmd()) {
187 m_bIsArgsPresentButNotHandledByCmd = true;
188 m_setCmdArgsNotHandledByCmd.push_back(pArg);
189 }
190
191 // Next
192 ++it;
193 }
194
195 // report any issues with arguments/options
196 if (IsArgsPresentButNotHandledByCmd())
197 WarningArgsNotHandledbyCmdLogFile(vStrMiCmd);
198
199 return ValidationFormErrorMessages(vwCmdArgsText);
200 }
201
202 //++
203 //------------------------------------------------------------------------------------
204 // Details: Having validated the command's options text and failed for some
205 // reason form
206 // the error message made up with the faults found.
207 // Type: Method.
208 // vCmdArgsText - (RW) A command's options or argument.
209 // Return: MIstatus::success - Functional succeeded.
210 // MIstatus::failure - Functional failed.
211 // Throws: None.
212 //--
ValidationFormErrorMessages(const CMICmdArgContext & vwCmdArgsText)213 bool CMICmdArgSet::ValidationFormErrorMessages(
214 const CMICmdArgContext &vwCmdArgsText) {
215 CMIUtilString strListMissing;
216 CMIUtilString strListInvalid;
217 CMIUtilString strListMissingInfo;
218 const bool bArgsMissing = (m_setCmdArgsThatAreMissing.size() > 0);
219 const bool bArgsInvalid = (m_setCmdArgsThatNotValid.size() > 0);
220 const bool bArgsMissingInfo = (m_setCmdArgsMissingInfo.size() > 0);
221 if (!(bArgsMissing || bArgsInvalid || bArgsMissingInfo))
222 return MIstatus::success;
223 if (bArgsMissing) {
224 MIuint i = 0;
225 SetCmdArgs_t::const_iterator it = m_setCmdArgsThatAreMissing.begin();
226 while (it != m_setCmdArgsThatAreMissing.end()) {
227 if (i++ > 0)
228 strListMissing += m_constStrCommaSpc;
229
230 const CMICmdArgValBase *pArg(*it);
231 strListMissing += pArg->GetName();
232
233 // Next
234 ++it;
235 }
236 }
237 if (bArgsInvalid) {
238 MIuint i = 0;
239 SetCmdArgs_t::const_iterator it = m_setCmdArgsThatNotValid.begin();
240 while (it != m_setCmdArgsThatNotValid.end()) {
241 if (i++ > 0)
242 strListMissing += m_constStrCommaSpc;
243
244 const CMICmdArgValBase *pArg(*it);
245 strListInvalid += pArg->GetName();
246
247 // Next
248 ++it;
249 }
250 }
251 if (bArgsMissingInfo) {
252 MIuint i = 0;
253 SetCmdArgs_t::const_iterator it = m_setCmdArgsMissingInfo.begin();
254 while (it != m_setCmdArgsMissingInfo.end()) {
255 if (i++ > 0)
256 strListMissingInfo += m_constStrCommaSpc;
257
258 const CMICmdArgValBase *pArg(*it);
259 strListMissingInfo += pArg->GetName();
260
261 // Next
262 ++it;
263 }
264 }
265
266 bool bHaveOneError = false;
267 CMIUtilString strError = MIRSRC(IDS_CMD_ARGS_ERR_PREFIX_MSG);
268 if (bArgsMissing && bArgsInvalid) {
269 bHaveOneError = true;
270 strError +=
271 CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID),
272 strListMissing.c_str(), strListInvalid.c_str());
273 }
274 if (bArgsMissing) {
275 if (bHaveOneError)
276 strError += ". ";
277 bHaveOneError = true;
278 strError += CMIUtilString::Format(
279 MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY), strListMissing.c_str());
280 }
281 if (bArgsMissingInfo) {
282 if (bHaveOneError)
283 strError += ". ";
284 bHaveOneError = true;
285 strError +=
286 CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF),
287 strListMissingInfo.c_str());
288 }
289 if (bArgsInvalid) {
290 if (bHaveOneError)
291 strError += ". ";
292 bHaveOneError = true;
293 strError += CMIUtilString::Format(
294 MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_INVALID), strListInvalid.c_str());
295 }
296 if (!vwCmdArgsText.IsEmpty()) {
297 if (bHaveOneError)
298 strError += ". ";
299 bHaveOneError = true;
300 strError +=
301 CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN),
302 vwCmdArgsText.GetArgsLeftToParse().c_str());
303 }
304
305 if (bHaveOneError) {
306 SetErrorDescription(strError);
307 return MIstatus::failure;
308 }
309
310 return MIstatus::success;
311 }
312
313 //++
314 //------------------------------------------------------------------------------------
315 // Details: Ask if the command's argument options text had any arguments.
316 // Type: Method.
317 // Args: None.
318 // Return: bool - True = Has one or more arguments present, false = no
319 // arguments.
320 // Throws: None.
321 //--
IsArgContextEmpty() const322 bool CMICmdArgSet::IsArgContextEmpty() const {
323 return m_cmdArgContext.IsEmpty();
324 }
325
326 //++
327 //------------------------------------------------------------------------------------
328 // Details: Retrieve the number of arguments that are being used for the
329 // command.
330 // Type: Method.
331 // Args: None.
332 // Return: size_t - Argument count.
333 // Throws: None.
334 //--
GetCount() const335 size_t CMICmdArgSet::GetCount() const { return m_setCmdArgs.size(); }
336
337 //++
338 //------------------------------------------------------------------------------------
339 // Details: Given a set of command argument objects retrieve the argument with
340 // the
341 // specified name.
342 // Type: Method.
343 // Args: vpArg - (W) A pointer to a command's argument object.
344 // Return: True - Argument found.
345 // False - Argument not found.
346 // Throws: None.
347 //--
GetArg(const CMIUtilString & vArgName,CMICmdArgValBase * & vpArg) const348 bool CMICmdArgSet::GetArg(const CMIUtilString &vArgName,
349 CMICmdArgValBase *&vpArg) const {
350 bool bFound = false;
351 SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
352 while (it != m_setCmdArgs.end()) {
353 CMICmdArgValBase *pArg(*it);
354 if (pArg->GetName() == vArgName) {
355 bFound = true;
356 vpArg = pArg;
357 break;
358 }
359
360 // Next
361 ++it;
362 }
363
364 return bFound;
365 }
366
367 //++
368 //------------------------------------------------------------------------------------
369 // Details: Write a warning message to the MI Log file about the command's
370 // arguments or
371 // options that were found present but not handled.
372 // Type: Method.
373 // Args: vrCmdName - (R) The command's name.
374 // Return: None.
375 // Throws: None.
376 //--
WarningArgsNotHandledbyCmdLogFile(const CMIUtilString & vrCmdName)377 void CMICmdArgSet::WarningArgsNotHandledbyCmdLogFile(
378 const CMIUtilString &vrCmdName) {
379 #if MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED
380
381 CMIUtilString strArgsNotHandled;
382 const CMICmdArgSet::SetCmdArgs_t &rSetArgs = GetArgsNotHandledByCmd();
383 MIuint nCnt = 0;
384 CMICmdArgSet::SetCmdArgs_t::const_iterator it = rSetArgs.begin();
385 while (it != rSetArgs.end()) {
386 if (nCnt++ > 0)
387 strArgsNotHandled += m_constStrCommaSpc;
388 const CMICmdArgValBase *pArg = *it;
389 strArgsNotHandled += pArg->GetName();
390
391 // Next
392 ++it;
393 }
394
395 const CMIUtilString strWarningMsg(
396 CMIUtilString::Format(MIRSRC(IDS_CMD_WRN_ARGS_NOT_HANDLED),
397 vrCmdName.c_str(), strArgsNotHandled.c_str()));
398 m_pLog->WriteLog(strWarningMsg);
399
400 #endif // MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED
401 }
402