blob: bea5935523271a27b94ab7aa11d8d001a5195911 [file] [log] [blame]
Deepak Panickal6f9c4682014-05-16 10:51:01 +00001//===-- MICmdArgValString.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
Deepak Panickal6f9c4682014-05-16 10:51:01 +000010// In-house headers:
11#include "MICmdArgValString.h"
12#include "MICmdArgContext.h"
13
14//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000015// Details: CMICmdArgValString constructor.
16// Type: Method.
17// Args: None.
18// Return: None.
19// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000020//--
Bruce Mitchenere2453af2015-08-04 10:24:20 +000021CMICmdArgValString::CMICmdArgValString()
Zachary Turner1d6af022014-11-17 18:06:21 +000022 : m_bHandleQuotedString(false)
23 , m_bAcceptNumbers(false)
24 , m_bHandleDirPaths(false)
25 , m_bHandleAnything(false)
Deepak Panickalf92dc582014-08-14 16:40:15 +000026{
27}
28
29//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000030// Details: CMICmdArgValString constructor.
31// Type: Method.
32// Args: vbAnything - (R) True = Parse a string and accept anything, false = do not accept anything.
33// Return: None.
34// Throws: None.
Deepak Panickalf92dc582014-08-14 16:40:15 +000035//--
Zachary Turner1d6af022014-11-17 18:06:21 +000036CMICmdArgValString::CMICmdArgValString(const bool vbAnything)
Ilia K69b95f42015-02-26 18:21:22 +000037 : m_bHandleQuotedString(vbAnything ? true : false)
Zachary Turner1d6af022014-11-17 18:06:21 +000038 , m_bAcceptNumbers(false)
39 , m_bHandleDirPaths(false)
40 , m_bHandleAnything(vbAnything)
Deepak Panickal877569c2014-06-24 16:35:50 +000041{
42}
43
44//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000045// Details: CMICmdArgValString constructor.
46// Type: Method.
Bruce Mitchenerd0ee89d2015-07-03 14:09:56 +000047// Args: vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimiters, false = only text up to
Zachary Turner1d6af022014-11-17 18:06:21 +000048// next delimiting space character.
49// vbAcceptNumbers - (R) True = Parse a string and accept as a number if number, false = numbers not recognised
50// as string types.
51// vbHandleDirPaths - (R) True = Parse a string and accept as a file path if a path, false = file paths are not
52// recognised as string types.
53// Return: None.
54// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +000055//--
Zachary Turner1d6af022014-11-17 18:06:21 +000056CMICmdArgValString::CMICmdArgValString(const bool vbHandleQuotes, const bool vbAcceptNumbers, const bool vbHandleDirPaths)
57 : m_bHandleQuotedString(vbHandleQuotes)
58 , m_bAcceptNumbers(vbAcceptNumbers)
59 , m_bHandleDirPaths(vbHandleDirPaths)
60 , m_bHandleAnything(false)
Deepak Panickal6f9c4682014-05-16 10:51:01 +000061{
62}
63
64//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000065// Details: CMICmdArgValString constructor.
66// Type: Method.
67// Args: vrArgName - (R) Argument's name to search by.
68// vbMandatory - (R) True = Yes must be present, false = optional argument.
69// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
Bruce Mitchenerd0ee89d2015-07-03 14:09:56 +000070// vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimiters, false = only text up to
Zachary Turner1d6af022014-11-17 18:06:21 +000071// next delimiting space character. (Dflt = false)
72// vbAcceptNumbers - (R) True = Parse a string and accept as a number if number, false = numbers not recognised as
73// string types. (Dflt = false)
74// Return: None.
75// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000076//--
Zachary Turner1d6af022014-11-17 18:06:21 +000077CMICmdArgValString::CMICmdArgValString(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd,
78 const bool vbHandleQuotes /* = false */, const bool vbAcceptNumbers /* = false */)
79 : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd)
80 , m_bHandleQuotedString(vbHandleQuotes)
81 , m_bAcceptNumbers(vbAcceptNumbers)
82 , m_bHandleDirPaths(false)
83 , m_bHandleAnything(false)
Deepak Panickal6f9c4682014-05-16 10:51:01 +000084{
85}
86
87//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000088// Details: CMICmdArgValString destructor.
89// Type: Overridden.
90// Args: None.
91// Return: None.
92// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000093//--
Bruce Mitchenere2453af2015-08-04 10:24:20 +000094CMICmdArgValString::~CMICmdArgValString()
Deepak Panickal6f9c4682014-05-16 10:51:01 +000095{
96}
97
98//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000099// Details: Parse the command's argument options string and try to extract the value *this
100// argument is looking for.
101// Type: Overridden.
102// Args: vrwArgContext - (RW) The command's argument options string.
103// Return: MIstatus::success - Functional succeeded.
104// MIstatus::failure - Functional failed.
105// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000106//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000107bool
108CMICmdArgValString::Validate(CMICmdArgContext &vrwArgContext)
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000109{
Zachary Turner1d6af022014-11-17 18:06:21 +0000110 if (vrwArgContext.IsEmpty())
Bruce Mitchener1425b472015-06-08 11:15:09 +0000111 return m_bMandatory ? MIstatus::failure : MIstatus::success;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000112
Zachary Turner1d6af022014-11-17 18:06:21 +0000113 if (m_bHandleQuotedString)
Ilia K69b95f42015-02-26 18:21:22 +0000114 return ValidateQuotedText(vrwArgContext);
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000115
Zachary Turner1d6af022014-11-17 18:06:21 +0000116 return ValidateSingleText(vrwArgContext);
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000117}
118
119//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000120// Details: Parse the command's argument options string and try to extract only the next
121// word delimited by the next space.
122// Type: Method.
123// Args: vrwArgContext - (RW) The command's argument options string.
124// Return: MIstatus::success - Functional succeeded.
125// MIstatus::failure - Functional failed.
126// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000127//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000128bool
129CMICmdArgValString::ValidateSingleText(CMICmdArgContext &vrwArgContext)
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000130{
Zachary Turner1d6af022014-11-17 18:06:21 +0000131 const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
132 CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
133 while (it != vecOptions.end())
134 {
135 const CMIUtilString &rArg(*it);
136 if (IsStringArg(rArg))
137 {
138 m_bFound = true;
139
140 if (vrwArgContext.RemoveArg(rArg))
141 {
142 m_bValid = true;
Ilia K69b95f42015-02-26 18:21:22 +0000143 m_argValue = rArg.StripSlashes();
Zachary Turner1d6af022014-11-17 18:06:21 +0000144 return MIstatus::success;
145 }
146 else
147 return MIstatus::failure;
148 }
149
150 // Next
151 ++it;
152 }
153
154 return MIstatus::failure;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000155}
156
157//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000158// Details: Parse the command's argument options string and try to extract all the words
Ilia K69b95f42015-02-26 18:21:22 +0000159// between quotes then delimited by the next space.
Zachary Turner1d6af022014-11-17 18:06:21 +0000160// Type: Method.
161// Args: vrwArgContext - (RW) The command's argument options string.
162// Return: MIstatus::success - Functional succeeded.
163// MIstatus::failure - Functional failed.
164// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000165//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000166bool
167CMICmdArgValString::ValidateQuotedText(CMICmdArgContext &vrwArgContext)
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000168{
Ilia K69b95f42015-02-26 18:21:22 +0000169 const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
170 if (vecOptions.size() == 0)
Zachary Turner1d6af022014-11-17 18:06:21 +0000171 return MIstatus::failure;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000172
Ilia K69b95f42015-02-26 18:21:22 +0000173 const CMIUtilString &rArg(vecOptions[0]);
174 if (!IsStringArg(rArg))
Zachary Turner1d6af022014-11-17 18:06:21 +0000175 return MIstatus::failure;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000176
Ilia K69b95f42015-02-26 18:21:22 +0000177 m_bFound = true;
Deepak Panickald2499282014-08-08 16:47:42 +0000178
Ilia K69b95f42015-02-26 18:21:22 +0000179 if (vrwArgContext.RemoveArg(rArg))
Zachary Turner1d6af022014-11-17 18:06:21 +0000180 {
Zachary Turner1d6af022014-11-17 18:06:21 +0000181 m_bValid = true;
Bruce Mitchener3b25b472015-07-03 13:45:34 +0000182 const char cQuote = '"';
Ilia K69b95f42015-02-26 18:21:22 +0000183 m_argValue = rArg.Trim(cQuote).StripSlashes();
Zachary Turner1d6af022014-11-17 18:06:21 +0000184 return MIstatus::success;
185 }
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000186
Zachary Turner1d6af022014-11-17 18:06:21 +0000187 return MIstatus::failure;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000188}
189
190//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000191// Details: Examine the string and determine if it is a valid string type argument.
192// Type: Method.
193// Args: vrTxt - (R) Some text.
194// Return: bool - True = yes valid arg, false = no.
195// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000196//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000197bool
198CMICmdArgValString::IsStringArg(const CMIUtilString &vrTxt) const
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000199{
Zachary Turner1d6af022014-11-17 18:06:21 +0000200 if (m_bHandleQuotedString)
201 return (IsStringArgQuotedText(vrTxt) || IsStringArgQuotedTextEmbedded(vrTxt) || IsStringArgQuotedQuotedTextEmbedded(vrTxt) ||
202 IsStringArgSingleText(vrTxt)); // Still test for this as could just be one word still
203
204 return IsStringArgSingleText(vrTxt);
Deepak Panickal877569c2014-06-24 16:35:50 +0000205}
206
207//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000208// Details: Examine the string and determine if it is a valid string type argument or
209// option value. If the string looks like a long option, short option, a thread
210// group ID or just a number it is rejected as a string type value. There is an
211// option to allow the string to accept a number as a string type.
212// Type: Method.
213// Args: vrTxt - (R) Some text.
214// Return: bool - True = yes valid argument value, false = something else.
215// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000216//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000217bool
218CMICmdArgValString::IsStringArgSingleText(const CMIUtilString &vrTxt) const
Deepak Panickal877569c2014-06-24 16:35:50 +0000219{
Zachary Turner1d6af022014-11-17 18:06:21 +0000220 if (!m_bHandleDirPaths)
221 {
222 // Look for directory file paths, if found reject
Bruce Mitchenere8433cc2015-09-01 23:57:17 +0000223 const bool bHavePosSlash = (vrTxt.find('/') != std::string::npos);
224 const bool bHaveBckSlash = (vrTxt.find('\\') != std::string::npos);
Zachary Turner1d6af022014-11-17 18:06:21 +0000225 if (bHavePosSlash || bHaveBckSlash)
226 return false;
227 }
Deepak Panickal877569c2014-06-24 16:35:50 +0000228
Zachary Turner1d6af022014-11-17 18:06:21 +0000229 // Look for --someLongOption, if found reject
230 if (0 == vrTxt.find("--"))
231 return false;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000232
Zachary Turner1d6af022014-11-17 18:06:21 +0000233 // Look for -f type short options, if found reject
Bruce Mitchener0b6ba7c2015-07-04 05:16:58 +0000234 if ((0 == vrTxt.find('-')) && (vrTxt.length() == 2))
Zachary Turner1d6af022014-11-17 18:06:21 +0000235 return false;
236
237 // Look for thread group i1 i2 i3...., if found reject
Bruce Mitchener0b6ba7c2015-07-04 05:16:58 +0000238 if ((vrTxt.find('i') == 0) && ::isdigit(vrTxt[1]))
Zachary Turner1d6af022014-11-17 18:06:21 +0000239 return false;
240
241 // Look for numbers, if found reject
242 if (!m_bAcceptNumbers && vrTxt.IsNumber())
243 return false;
244
245 return true;
Deepak Panickal877569c2014-06-24 16:35:50 +0000246}
247
248//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000249// Details: Examine the string and determine if it is a valid string type argument.
250// Take into account quotes surrounding the text. Note this function falls
251// through to IsStringArgSingleText() should the criteria match fail.
252// Type: Method.
253// Args: vrTxt - (R) Some text.
254// Return: bool - True = yes valid arg, false = no.
255// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000256//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000257bool
258CMICmdArgValString::IsStringArgQuotedText(const CMIUtilString &vrTxt) const
Deepak Panickal877569c2014-06-24 16:35:50 +0000259{
Ilia K69b95f42015-02-26 18:21:22 +0000260 // Accept anything as string word
261 if (m_bHandleAnything)
262 return true;
263
Zachary Turner1d6af022014-11-17 18:06:21 +0000264 // CODETAG_QUOTEDTEXT_SIMILAR_CODE
Bruce Mitchener3b25b472015-07-03 13:45:34 +0000265 const char cQuote = '"';
Bruce Mitchenere86c6fa2015-07-03 15:40:44 +0000266 const size_t nPos = vrTxt.find(cQuote);
267 if (nPos == std::string::npos)
Zachary Turner1d6af022014-11-17 18:06:21 +0000268 return false;
Deepak Panickal877569c2014-06-24 16:35:50 +0000269
Zachary Turner1d6af022014-11-17 18:06:21 +0000270 // Is one and only quote at end of the string
Bruce Mitchenere86c6fa2015-07-03 15:40:44 +0000271 if (nPos == (vrTxt.length() - 1))
Zachary Turner1d6af022014-11-17 18:06:21 +0000272 return false;
Deepak Panickal877569c2014-06-24 16:35:50 +0000273
Bruce Mitchener58ef3912015-06-18 05:27:05 +0000274 // Quote must be the first character in the string or be preceded by a space
Zachary Turner1d6af022014-11-17 18:06:21 +0000275 // Also check for embedded string formating quote
Bruce Mitchener3b25b472015-07-03 13:45:34 +0000276 const char cBckSlash = '\\';
277 const char cSpace = ' ';
Zachary Turner1d6af022014-11-17 18:06:21 +0000278 if ((nPos > 1) && (vrTxt[nPos - 1] == cBckSlash) && (vrTxt[nPos - 2] != cSpace))
279 {
280 return false;
281 }
282 if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
283 return false;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000284
Zachary Turner1d6af022014-11-17 18:06:21 +0000285 // Need to find the other quote
Bruce Mitchenere86c6fa2015-07-03 15:40:44 +0000286 const size_t nPos2 = vrTxt.rfind(cQuote);
287 if (nPos2 == std::string::npos)
Zachary Turner1d6af022014-11-17 18:06:21 +0000288 return false;
Deepak Panickald2499282014-08-08 16:47:42 +0000289
Zachary Turner1d6af022014-11-17 18:06:21 +0000290 // Make sure not same quote, need two quotes
291 if (nPos == nPos2)
292 return MIstatus::failure;
293
294 return true;
Deepak Panickald2499282014-08-08 16:47:42 +0000295}
296
297//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000298// Details: Examine the string and determine if it is a valid string type argument.
299// Take into account quotes surrounding the text. Take into account string format
300// embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this function falls
301// through to IsStringArgQuotedText() should the criteria match fail.
302// Type: Method.
303// Args: vrTxt - (R) Some text.
304// Return: bool - True = yes valid arg, false = no.
305// Throws: None.
Deepak Panickald2499282014-08-08 16:47:42 +0000306//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000307bool
308CMICmdArgValString::IsStringArgQuotedTextEmbedded(const CMIUtilString &vrTxt) const
Deepak Panickald2499282014-08-08 16:47:42 +0000309{
Zachary Turner1d6af022014-11-17 18:06:21 +0000310 // CODETAG_QUOTEDTEXT_SIMILAR_CODE
Bruce Mitchener3b25b472015-07-03 13:45:34 +0000311 const char cBckSlash = '\\';
Bruce Mitchenere86c6fa2015-07-03 15:40:44 +0000312 const size_t nPos = vrTxt.find(cBckSlash);
313 if (nPos == std::string::npos)
Zachary Turner1d6af022014-11-17 18:06:21 +0000314 return false;
Deepak Panickald2499282014-08-08 16:47:42 +0000315
Bruce Mitchener58ef3912015-06-18 05:27:05 +0000316 // Slash must be the first character in the string or be preceded by a space
Bruce Mitchener3b25b472015-07-03 13:45:34 +0000317 const char cSpace = ' ';
Zachary Turner1d6af022014-11-17 18:06:21 +0000318 if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
319 return false;
Deepak Panickald2499282014-08-08 16:47:42 +0000320
Zachary Turner1d6af022014-11-17 18:06:21 +0000321 // Need to find the other matching slash
Bruce Mitchenere86c6fa2015-07-03 15:40:44 +0000322 const size_t nPos2 = vrTxt.rfind(cBckSlash);
323 if (nPos2 == std::string::npos)
Zachary Turner1d6af022014-11-17 18:06:21 +0000324 return false;
Deepak Panickald2499282014-08-08 16:47:42 +0000325
Bruce Mitchenerd0ee89d2015-07-03 14:09:56 +0000326 // Make sure not same back slash, need two slashes
Zachary Turner1d6af022014-11-17 18:06:21 +0000327 if (nPos == nPos2)
328 return MIstatus::failure;
Deepak Panickald2499282014-08-08 16:47:42 +0000329
Zachary Turner1d6af022014-11-17 18:06:21 +0000330 return false;
Deepak Panickald2499282014-08-08 16:47:42 +0000331}
332
333//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000334// Details: Examine the string and determine if it is a valid string type argument.
335// Take into account quotes surrounding the text. Take into account string format
336// embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this function falls
337// through to IsStringArgQuotedTextEmbedded() should the criteria match fail.
338// Type: Method.
339// Args: vrTxt - (R) Some text.
340// Return: bool - True = yes valid arg, false = no.
341// Throws: None.
Deepak Panickald2499282014-08-08 16:47:42 +0000342//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000343bool
344CMICmdArgValString::IsStringArgQuotedQuotedTextEmbedded(const CMIUtilString &vrTxt) const
Deepak Panickald2499282014-08-08 16:47:42 +0000345{
Bruce Mitchenere86c6fa2015-07-03 15:40:44 +0000346 const size_t nPos = vrTxt.find("\"\\\"");
347 if (nPos == std::string::npos)
Zachary Turner1d6af022014-11-17 18:06:21 +0000348 return false;
Deepak Panickald2499282014-08-08 16:47:42 +0000349
Bruce Mitchenere86c6fa2015-07-03 15:40:44 +0000350 const size_t nPos2 = vrTxt.rfind("\\\"\"");
351 if (nPos2 == std::string::npos)
Zachary Turner1d6af022014-11-17 18:06:21 +0000352 return false;
Deepak Panickald2499282014-08-08 16:47:42 +0000353
Bruce Mitchenere86c6fa2015-07-03 15:40:44 +0000354 const size_t nLen = vrTxt.length();
Zachary Turner1d6af022014-11-17 18:06:21 +0000355 if ((nLen > 5) && ((nPos + 2) == (nPos2 - 2)))
356 return false;
357
358 return true;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000359}