1 //===-- MICmdArgValString.cpp -----------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "MICmdArgValString.h"
11 #include "MICmdArgContext.h"
14 // Details: CMICmdArgValString constructor.
20 CMICmdArgValString::CMICmdArgValString()
21 : m_bHandleQuotedString(false), m_bAcceptNumbers(false),
22 m_bHandleDirPaths(false), m_bHandleAnything(false) {}
25 // Details: CMICmdArgValString constructor.
27 // Args: vbAnything - (R) True = Parse a string and accept anything, false =
28 // do not accept anything.
32 CMICmdArgValString::CMICmdArgValString(const bool vbAnything)
33 : m_bHandleQuotedString(vbAnything), m_bAcceptNumbers(false),
34 m_bHandleDirPaths(false), m_bHandleAnything(vbAnything) {}
37 // Details: CMICmdArgValString constructor.
39 // Args: vbHandleQuotes - (R) True = Parse a string surrounded by quotes
40 // spaces are not delimiters, false = only text up to
41 // next delimiting space character.
42 // vbAcceptNumbers - (R) True = Parse a string and accept as a
43 // number if number, false = numbers not recognised
45 // vbHandleDirPaths - (R) True = Parse a string and accept as a file
46 // path if a path, false = file paths are not
47 // recognised as string types.
51 CMICmdArgValString::CMICmdArgValString(const bool vbHandleQuotes,
52 const bool vbAcceptNumbers,
53 const bool vbHandleDirPaths)
54 : m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
55 m_bHandleDirPaths(vbHandleDirPaths), m_bHandleAnything(false) {}
58 // Details: CMICmdArgValString constructor.
60 // Args: vrArgName - (R) Argument's name to search by.
61 // vbMandatory - (R) True = Yes must be present, false = optional
63 // vbHandleByCmd - (R) True = Command processes *this option, false =
65 // vbHandleQuotes - (R) True = Parse a string surrounded by quotes
66 // spaces are not delimiters, false = only text up to
67 // next delimiting space character. (Dflt = false)
68 // vbAcceptNumbers - (R) True = Parse a string and accept as a number
69 // if number, false = numbers not recognised as
70 // string types. (Dflt = false)
74 CMICmdArgValString::CMICmdArgValString(const CMIUtilString &vrArgName,
75 const bool vbMandatory,
76 const bool vbHandleByCmd,
77 const bool vbHandleQuotes /* = false */,
78 const bool vbAcceptNumbers /* = false */)
79 : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
80 m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
81 m_bHandleDirPaths(false), m_bHandleAnything(false) {}
84 // Details: CMICmdArgValString constructor.
86 // Args: vrArgName - (R) Argument's name to search by.
87 // vbMandatory - (R) True = Yes must be present, false = optional
89 // vbHandleByCmd - (R) True = Command processes *this option, false =
91 // vbHandleQuotes - (R) True = Parse a string surrounded by quotes
92 // spaces are not delimiters, false = only text up to
93 // next delimiting space character.
94 // vbAcceptNumbers - (R) True = Parse a string and accept as a number
95 // if number, false = numbers not recognised as
96 // vbHandleDirPaths - (R) True = Parse a string and accept as a file
97 // path if a path, false = file paths are not
102 CMICmdArgValString::CMICmdArgValString(const CMIUtilString &vrArgName,
103 const bool vbMandatory,
104 const bool vbHandleByCmd,
105 const bool vbHandleQuotes,
106 const bool vbAcceptNumbers,
107 const bool vbHandleDirPaths)
108 : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
109 m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
110 m_bHandleDirPaths(vbHandleDirPaths), m_bHandleAnything(false) {}
113 // Details: CMICmdArgValString destructor.
119 CMICmdArgValString::~CMICmdArgValString() {}
122 // Details: Parse the command's argument options string and try to extract the
124 // argument is looking for.
126 // Args: vrwArgContext - (RW) The command's argument options string.
127 // Return: MIstatus::success - Functional succeeded.
128 // MIstatus::failure - Functional failed.
131 bool CMICmdArgValString::Validate(CMICmdArgContext &vrwArgContext) {
132 if (vrwArgContext.IsEmpty())
133 return m_bMandatory ? MIstatus::failure : MIstatus::success;
135 if (m_bHandleQuotedString)
136 return ValidateQuotedText(vrwArgContext);
138 return ValidateSingleText(vrwArgContext);
142 // Details: Parse the command's argument options string and try to extract only
144 // word delimited by the next space.
146 // Args: vrwArgContext - (RW) The command's argument options string.
147 // Return: MIstatus::success - Functional succeeded.
148 // MIstatus::failure - Functional failed.
151 bool CMICmdArgValString::ValidateSingleText(CMICmdArgContext &vrwArgContext) {
152 const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
153 CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
154 while (it != vecOptions.end()) {
155 const CMIUtilString &rArg(*it);
156 if (IsStringArg(rArg)) {
159 if (vrwArgContext.RemoveArg(rArg)) {
161 m_argValue = rArg.StripSlashes();
162 return MIstatus::success;
164 return MIstatus::failure;
171 return MIstatus::failure;
175 // Details: Parse the command's argument options string and try to extract all
177 // between quotes then delimited by the next space.
179 // Args: vrwArgContext - (RW) The command's argument options string.
180 // Return: MIstatus::success - Functional succeeded.
181 // MIstatus::failure - Functional failed.
184 bool CMICmdArgValString::ValidateQuotedText(CMICmdArgContext &vrwArgContext) {
185 const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
186 if (vecOptions.size() == 0)
187 return MIstatus::failure;
189 const CMIUtilString &rArg(vecOptions[0]);
190 if (!IsStringArg(rArg))
191 return MIstatus::failure;
195 if (vrwArgContext.RemoveArg(rArg)) {
197 const char cQuote = '"';
198 m_argValue = rArg.Trim(cQuote).StripSlashes();
199 return MIstatus::success;
202 return MIstatus::failure;
206 // Details: Examine the string and determine if it is a valid string type
209 // Args: vrTxt - (R) Some text.
210 // Return: bool - True = yes valid arg, false = no.
213 bool CMICmdArgValString::IsStringArg(const CMIUtilString &vrTxt) const {
214 if (m_bHandleQuotedString)
215 return (IsStringArgQuotedText(vrTxt) ||
216 IsStringArgQuotedTextEmbedded(vrTxt) ||
217 IsStringArgQuotedQuotedTextEmbedded(vrTxt) ||
218 IsStringArgSingleText(
219 vrTxt)); // Still test for this as could just be one word still
221 return IsStringArgSingleText(vrTxt);
225 // Details: Examine the string and determine if it is a valid string type
227 // option value. If the string looks like a long option, short option,
229 // group ID or just a number it is rejected as a string type value.
231 // option to allow the string to accept a number as a string type.
233 // Args: vrTxt - (R) Some text.
234 // Return: bool - True = yes valid argument value, false = something else.
237 bool CMICmdArgValString::IsStringArgSingleText(
238 const CMIUtilString &vrTxt) const {
239 if (!m_bHandleDirPaths) {
240 // Look for directory file paths, if found reject
241 const bool bHavePosSlash = (vrTxt.find('/') != std::string::npos);
242 const bool bHaveBckSlash = (vrTxt.find('\\') != std::string::npos);
243 if (bHavePosSlash || bHaveBckSlash)
247 // Look for --someLongOption, if found reject
248 if (0 == vrTxt.find("--"))
251 // Look for -f type short options, if found reject
252 if ((0 == vrTxt.find('-')) && (vrTxt.length() == 2))
255 // Look for thread group i1 i2 i3...., if found reject
256 if ((vrTxt.find('i') == 0) && ::isdigit(vrTxt[1]))
259 // Look for numbers, if found reject
260 if (!m_bAcceptNumbers && vrTxt.IsNumber())
267 // Details: Examine the string and determine if it is a valid string type
269 // Take into account quotes surrounding the text. Note this function
271 // through to IsStringArgSingleText() should the criteria match fail.
273 // Args: vrTxt - (R) Some text.
274 // Return: bool - True = yes valid arg, false = no.
277 bool CMICmdArgValString::IsStringArgQuotedText(
278 const CMIUtilString &vrTxt) const {
279 // Accept anything as string word
280 if (m_bHandleAnything)
283 // CODETAG_QUOTEDTEXT_SIMILAR_CODE
284 const char cQuote = '"';
285 const size_t nPos = vrTxt.find(cQuote);
286 if (nPos == std::string::npos)
289 // Is one and only quote at end of the string
290 if (nPos == (vrTxt.length() - 1))
293 // Quote must be the first character in the string or be preceded by a space
294 // Also check for embedded string formating quote
295 const char cBckSlash = '\\';
296 const char cSpace = ' ';
297 if ((nPos > 1) && (vrTxt[nPos - 1] == cBckSlash) &&
298 (vrTxt[nPos - 2] != cSpace)) {
301 if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
304 // Need to find the other quote
305 const size_t nPos2 = vrTxt.rfind(cQuote);
306 if (nPos2 == std::string::npos)
309 // Make sure not same quote, need two quotes
311 return MIstatus::failure;
317 // Details: Examine the string and determine if it is a valid string type
319 // Take into account quotes surrounding the text. Take into account
321 // embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
323 // through to IsStringArgQuotedText() should the criteria match fail.
325 // Args: vrTxt - (R) Some text.
326 // Return: bool - True = yes valid arg, false = no.
329 bool CMICmdArgValString::IsStringArgQuotedTextEmbedded(
330 const CMIUtilString &vrTxt) const {
331 // CODETAG_QUOTEDTEXT_SIMILAR_CODE
332 const char cBckSlash = '\\';
333 const size_t nPos = vrTxt.find(cBckSlash);
334 if (nPos == std::string::npos)
337 // Slash must be the first character in the string or be preceded by a space
338 const char cSpace = ' ';
339 if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
342 // Need to find the other matching slash
343 const size_t nPos2 = vrTxt.rfind(cBckSlash);
344 if (nPos2 == std::string::npos)
347 // Make sure not same back slash, need two slashes
349 return MIstatus::failure;
355 // Details: Examine the string and determine if it is a valid string type
357 // Take into account quotes surrounding the text. Take into account
359 // embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
361 // through to IsStringArgQuotedTextEmbedded() should the criteria match
364 // Args: vrTxt - (R) Some text.
365 // Return: bool - True = yes valid arg, false = no.
368 bool CMICmdArgValString::IsStringArgQuotedQuotedTextEmbedded(
369 const CMIUtilString &vrTxt) const {
370 const size_t nPos = vrTxt.find("\"\\\"");
371 if (nPos == std::string::npos)
374 const size_t nPos2 = vrTxt.rfind("\\\"\"");
375 if (nPos2 == std::string::npos)
378 const size_t nLen = vrTxt.length();
379 return !((nLen > 5) && ((nPos + 2) == (nPos2 - 2)));