1 //===-- MICmdArgValString.cpp -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "MICmdArgValString.h"
12 #include "MICmdArgContext.h"
15 //------------------------------------------------------------------------------------
16 // Details: CMICmdArgValString constructor.
22 CMICmdArgValString::CMICmdArgValString()
23 : m_bHandleQuotedString(false), m_bAcceptNumbers(false),
24 m_bHandleDirPaths(false), m_bHandleAnything(false) {}
27 //------------------------------------------------------------------------------------
28 // Details: CMICmdArgValString constructor.
30 // Args: vbAnything - (R) True = Parse a string and accept anything, false =
31 // do not accept anything.
35 CMICmdArgValString::CMICmdArgValString(const bool vbAnything)
36 : m_bHandleQuotedString(vbAnything ? true : false), m_bAcceptNumbers(false),
37 m_bHandleDirPaths(false), m_bHandleAnything(vbAnything) {}
40 //------------------------------------------------------------------------------------
41 // Details: CMICmdArgValString constructor.
43 // Args: vbHandleQuotes - (R) True = Parse a string surrounded by quotes
44 // spaces are not delimiters, false = only text up to
45 // next delimiting space character.
46 // vbAcceptNumbers - (R) True = Parse a string and accept as a
47 // number if number, false = numbers not recognised
49 // vbHandleDirPaths - (R) True = Parse a string and accept as a file
50 // path if a path, false = file paths are not
51 // recognised as string types.
55 CMICmdArgValString::CMICmdArgValString(const bool vbHandleQuotes,
56 const bool vbAcceptNumbers,
57 const bool vbHandleDirPaths)
58 : m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
59 m_bHandleDirPaths(vbHandleDirPaths), m_bHandleAnything(false) {}
62 //------------------------------------------------------------------------------------
63 // Details: CMICmdArgValString constructor.
65 // Args: vrArgName - (R) Argument's name to search by.
66 // vbMandatory - (R) True = Yes must be present, false = optional
68 // vbHandleByCmd - (R) True = Command processes *this option, false =
70 // vbHandleQuotes - (R) True = Parse a string surrounded by quotes
71 // spaces are not delimiters, false = only text up to
72 // next delimiting space character. (Dflt = false)
73 // vbAcceptNumbers - (R) True = Parse a string and accept as a number
74 // if number, false = numbers not recognised as
75 // string types. (Dflt = false)
79 CMICmdArgValString::CMICmdArgValString(const CMIUtilString &vrArgName,
80 const bool vbMandatory,
81 const bool vbHandleByCmd,
82 const bool vbHandleQuotes /* = false */,
83 const bool vbAcceptNumbers /* = false */)
84 : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
85 m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
86 m_bHandleDirPaths(false), m_bHandleAnything(false) {}
89 //------------------------------------------------------------------------------------
90 // Details: CMICmdArgValString constructor.
92 // Args: vrArgName - (R) Argument's name to search by.
93 // vbMandatory - (R) True = Yes must be present, false = optional
95 // vbHandleByCmd - (R) True = Command processes *this option, false =
97 // vbHandleQuotes - (R) True = Parse a string surrounded by quotes
98 // spaces are not delimiters, false = only text up to
99 // next delimiting space character.
100 // vbAcceptNumbers - (R) True = Parse a string and accept as a number
101 // if number, false = numbers not recognised as
102 // vbHandleDirPaths - (R) True = Parse a string and accept as a file
103 // path if a path, false = file paths are not
108 CMICmdArgValString::CMICmdArgValString(const CMIUtilString &vrArgName,
109 const bool vbMandatory,
110 const bool vbHandleByCmd,
111 const bool vbHandleQuotes,
112 const bool vbAcceptNumbers,
113 const bool vbHandleDirPaths)
114 : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
115 m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
116 m_bHandleDirPaths(vbHandleDirPaths), m_bHandleAnything(false) {}
119 //------------------------------------------------------------------------------------
120 // Details: CMICmdArgValString destructor.
126 CMICmdArgValString::~CMICmdArgValString() {}
129 //------------------------------------------------------------------------------------
130 // Details: Parse the command's argument options string and try to extract the
132 // argument is looking for.
134 // Args: vrwArgContext - (RW) The command's argument options string.
135 // Return: MIstatus::success - Functional succeeded.
136 // MIstatus::failure - Functional failed.
139 bool CMICmdArgValString::Validate(CMICmdArgContext &vrwArgContext) {
140 if (vrwArgContext.IsEmpty())
141 return m_bMandatory ? MIstatus::failure : MIstatus::success;
143 if (m_bHandleQuotedString)
144 return ValidateQuotedText(vrwArgContext);
146 return ValidateSingleText(vrwArgContext);
150 //------------------------------------------------------------------------------------
151 // Details: Parse the command's argument options string and try to extract only
153 // word delimited by the next space.
155 // Args: vrwArgContext - (RW) The command's argument options string.
156 // Return: MIstatus::success - Functional succeeded.
157 // MIstatus::failure - Functional failed.
160 bool CMICmdArgValString::ValidateSingleText(CMICmdArgContext &vrwArgContext) {
161 const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
162 CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
163 while (it != vecOptions.end()) {
164 const CMIUtilString &rArg(*it);
165 if (IsStringArg(rArg)) {
168 if (vrwArgContext.RemoveArg(rArg)) {
170 m_argValue = rArg.StripSlashes();
171 return MIstatus::success;
173 return MIstatus::failure;
180 return MIstatus::failure;
184 //------------------------------------------------------------------------------------
185 // Details: Parse the command's argument options string and try to extract all
187 // between quotes then delimited by the next space.
189 // Args: vrwArgContext - (RW) The command's argument options string.
190 // Return: MIstatus::success - Functional succeeded.
191 // MIstatus::failure - Functional failed.
194 bool CMICmdArgValString::ValidateQuotedText(CMICmdArgContext &vrwArgContext) {
195 const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
196 if (vecOptions.size() == 0)
197 return MIstatus::failure;
199 const CMIUtilString &rArg(vecOptions[0]);
200 if (!IsStringArg(rArg))
201 return MIstatus::failure;
205 if (vrwArgContext.RemoveArg(rArg)) {
207 const char cQuote = '"';
208 m_argValue = rArg.Trim(cQuote).StripSlashes();
209 return MIstatus::success;
212 return MIstatus::failure;
216 //------------------------------------------------------------------------------------
217 // Details: Examine the string and determine if it is a valid string type
220 // Args: vrTxt - (R) Some text.
221 // Return: bool - True = yes valid arg, false = no.
224 bool CMICmdArgValString::IsStringArg(const CMIUtilString &vrTxt) const {
225 if (m_bHandleQuotedString)
226 return (IsStringArgQuotedText(vrTxt) ||
227 IsStringArgQuotedTextEmbedded(vrTxt) ||
228 IsStringArgQuotedQuotedTextEmbedded(vrTxt) ||
229 IsStringArgSingleText(
230 vrTxt)); // Still test for this as could just be one word still
232 return IsStringArgSingleText(vrTxt);
236 //------------------------------------------------------------------------------------
237 // Details: Examine the string and determine if it is a valid string type
239 // option value. If the string looks like a long option, short option,
241 // group ID or just a number it is rejected as a string type value.
243 // option to allow the string to accept a number as a string type.
245 // Args: vrTxt - (R) Some text.
246 // Return: bool - True = yes valid argument value, false = something else.
249 bool CMICmdArgValString::IsStringArgSingleText(
250 const CMIUtilString &vrTxt) const {
251 if (!m_bHandleDirPaths) {
252 // Look for directory file paths, if found reject
253 const bool bHavePosSlash = (vrTxt.find('/') != std::string::npos);
254 const bool bHaveBckSlash = (vrTxt.find('\\') != std::string::npos);
255 if (bHavePosSlash || bHaveBckSlash)
259 // Look for --someLongOption, if found reject
260 if (0 == vrTxt.find("--"))
263 // Look for -f type short options, if found reject
264 if ((0 == vrTxt.find('-')) && (vrTxt.length() == 2))
267 // Look for thread group i1 i2 i3...., if found reject
268 if ((vrTxt.find('i') == 0) && ::isdigit(vrTxt[1]))
271 // Look for numbers, if found reject
272 if (!m_bAcceptNumbers && vrTxt.IsNumber())
279 //------------------------------------------------------------------------------------
280 // Details: Examine the string and determine if it is a valid string type
282 // Take into account quotes surrounding the text. Note this function
284 // through to IsStringArgSingleText() should the criteria match fail.
286 // Args: vrTxt - (R) Some text.
287 // Return: bool - True = yes valid arg, false = no.
290 bool CMICmdArgValString::IsStringArgQuotedText(
291 const CMIUtilString &vrTxt) const {
292 // Accept anything as string word
293 if (m_bHandleAnything)
296 // CODETAG_QUOTEDTEXT_SIMILAR_CODE
297 const char cQuote = '"';
298 const size_t nPos = vrTxt.find(cQuote);
299 if (nPos == std::string::npos)
302 // Is one and only quote at end of the string
303 if (nPos == (vrTxt.length() - 1))
306 // Quote must be the first character in the string or be preceded by a space
307 // Also check for embedded string formating quote
308 const char cBckSlash = '\\';
309 const char cSpace = ' ';
310 if ((nPos > 1) && (vrTxt[nPos - 1] == cBckSlash) &&
311 (vrTxt[nPos - 2] != cSpace)) {
314 if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
317 // Need to find the other quote
318 const size_t nPos2 = vrTxt.rfind(cQuote);
319 if (nPos2 == std::string::npos)
322 // Make sure not same quote, need two quotes
324 return MIstatus::failure;
330 //------------------------------------------------------------------------------------
331 // Details: Examine the string and determine if it is a valid string type
333 // Take into account quotes surrounding the text. Take into account
335 // embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
337 // through to IsStringArgQuotedText() should the criteria match fail.
339 // Args: vrTxt - (R) Some text.
340 // Return: bool - True = yes valid arg, false = no.
343 bool CMICmdArgValString::IsStringArgQuotedTextEmbedded(
344 const CMIUtilString &vrTxt) const {
345 // CODETAG_QUOTEDTEXT_SIMILAR_CODE
346 const char cBckSlash = '\\';
347 const size_t nPos = vrTxt.find(cBckSlash);
348 if (nPos == std::string::npos)
351 // Slash must be the first character in the string or be preceded by a space
352 const char cSpace = ' ';
353 if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
356 // Need to find the other matching slash
357 const size_t nPos2 = vrTxt.rfind(cBckSlash);
358 if (nPos2 == std::string::npos)
361 // Make sure not same back slash, need two slashes
363 return MIstatus::failure;
369 //------------------------------------------------------------------------------------
370 // Details: Examine the string and determine if it is a valid string type
372 // Take into account quotes surrounding the text. Take into account
374 // embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
376 // through to IsStringArgQuotedTextEmbedded() should the criteria match
379 // Args: vrTxt - (R) Some text.
380 // Return: bool - True = yes valid arg, false = no.
383 bool CMICmdArgValString::IsStringArgQuotedQuotedTextEmbedded(
384 const CMIUtilString &vrTxt) const {
385 const size_t nPos = vrTxt.find("\"\\\"");
386 if (nPos == std::string::npos)
389 const size_t nPos2 = vrTxt.rfind("\\\"\"");
390 if (nPos2 == std::string::npos)
393 const size_t nLen = vrTxt.length();
394 if ((nLen > 5) && ((nPos + 2) == (nPos2 - 2)))