]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/lldb-mi/MICmdArgValString.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / tools / lldb-mi / MICmdArgValString.cpp
1 //===-- 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
10 // In-house headers:
11 #include "MICmdArgValString.h"
12 #include "MICmdArgContext.h"
13
14 //++
15 //------------------------------------------------------------------------------------
16 // Details: CMICmdArgValString constructor.
17 // Type:    Method.
18 // Args:    None.
19 // Return:  None.
20 // Throws:  None.
21 //--
22 CMICmdArgValString::CMICmdArgValString()
23     : m_bHandleQuotedString(false), m_bAcceptNumbers(false),
24       m_bHandleDirPaths(false), m_bHandleAnything(false) {}
25
26 //++
27 //------------------------------------------------------------------------------------
28 // Details: CMICmdArgValString constructor.
29 // Type:    Method.
30 // Args:    vbAnything  - (R) True = Parse a string and accept anything, false =
31 // do not accept anything.
32 // Return:  None.
33 // Throws:  None.
34 //--
35 CMICmdArgValString::CMICmdArgValString(const bool vbAnything)
36     : m_bHandleQuotedString(vbAnything ? true : false), m_bAcceptNumbers(false),
37       m_bHandleDirPaths(false), m_bHandleAnything(vbAnything) {}
38
39 //++
40 //------------------------------------------------------------------------------------
41 // Details: CMICmdArgValString constructor.
42 // Type:    Method.
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
48 // as string types.
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.
52 // Return:  None.
53 // Throws:  None.
54 //--
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) {}
60
61 //++
62 //------------------------------------------------------------------------------------
63 // Details: CMICmdArgValString constructor.
64 // Type:    Method.
65 // Args:    vrArgName       - (R) Argument's name to search by.
66 //          vbMandatory     - (R) True = Yes must be present, false = optional
67 //          argument.
68 //          vbHandleByCmd   - (R) True = Command processes *this option, false =
69 //          not handled.
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)
76 // Return:  None.
77 // Throws:  None.
78 //--
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) {}
87
88 //++
89 //------------------------------------------------------------------------------------
90 // Details: CMICmdArgValString constructor.
91 // Type:    Method.
92 // Args:    vrArgName       - (R) Argument's name to search by.
93 //          vbMandatory     - (R) True = Yes must be present, false = optional
94 //          argument.
95 //          vbHandleByCmd   - (R) True = Command processes *this option, false =
96 //          not handled.
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
104 // string types.
105 // Return:  None.
106 // Throws:  None.
107 //--
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) {}
117
118 //++
119 //------------------------------------------------------------------------------------
120 // Details: CMICmdArgValString destructor.
121 // Type:    Overridden.
122 // Args:    None.
123 // Return:  None.
124 // Throws:  None.
125 //--
126 CMICmdArgValString::~CMICmdArgValString() {}
127
128 //++
129 //------------------------------------------------------------------------------------
130 // Details: Parse the command's argument options string and try to extract the
131 // value *this
132 //          argument is looking for.
133 // Type:    Overridden.
134 // Args:    vrwArgContext   - (RW) The command's argument options string.
135 // Return:  MIstatus::success - Functional succeeded.
136 //          MIstatus::failure - Functional failed.
137 // Throws:  None.
138 //--
139 bool CMICmdArgValString::Validate(CMICmdArgContext &vrwArgContext) {
140   if (vrwArgContext.IsEmpty())
141     return m_bMandatory ? MIstatus::failure : MIstatus::success;
142
143   if (m_bHandleQuotedString)
144     return ValidateQuotedText(vrwArgContext);
145
146   return ValidateSingleText(vrwArgContext);
147 }
148
149 //++
150 //------------------------------------------------------------------------------------
151 // Details: Parse the command's argument options string and try to extract only
152 // the next
153 //          word delimited by the next space.
154 // Type:    Method.
155 // Args:    vrwArgContext   - (RW) The command's argument options string.
156 // Return:  MIstatus::success - Functional succeeded.
157 //          MIstatus::failure - Functional failed.
158 // Throws:  None.
159 //--
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)) {
166       m_bFound = true;
167
168       if (vrwArgContext.RemoveArg(rArg)) {
169         m_bValid = true;
170         m_argValue = rArg.StripSlashes();
171         return MIstatus::success;
172       } else
173         return MIstatus::failure;
174     }
175
176     // Next
177     ++it;
178   }
179
180   return MIstatus::failure;
181 }
182
183 //++
184 //------------------------------------------------------------------------------------
185 // Details: Parse the command's argument options string and try to extract all
186 // the words
187 //          between quotes then delimited by the next space.
188 // Type:    Method.
189 // Args:    vrwArgContext   - (RW) The command's argument options string.
190 // Return:  MIstatus::success - Functional succeeded.
191 //          MIstatus::failure - Functional failed.
192 // Throws:  None.
193 //--
194 bool CMICmdArgValString::ValidateQuotedText(CMICmdArgContext &vrwArgContext) {
195   const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
196   if (vecOptions.size() == 0)
197     return MIstatus::failure;
198
199   const CMIUtilString &rArg(vecOptions[0]);
200   if (!IsStringArg(rArg))
201     return MIstatus::failure;
202
203   m_bFound = true;
204
205   if (vrwArgContext.RemoveArg(rArg)) {
206     m_bValid = true;
207     const char cQuote = '"';
208     m_argValue = rArg.Trim(cQuote).StripSlashes();
209     return MIstatus::success;
210   }
211
212   return MIstatus::failure;
213 }
214
215 //++
216 //------------------------------------------------------------------------------------
217 // Details: Examine the string and determine if it is a valid string type
218 // argument.
219 // Type:    Method.
220 // Args:    vrTxt   - (R) Some text.
221 // Return:  bool    - True = yes valid arg, false = no.
222 // Throws:  None.
223 //--
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
231
232   return IsStringArgSingleText(vrTxt);
233 }
234
235 //++
236 //------------------------------------------------------------------------------------
237 // Details: Examine the string and determine if it is a valid string type
238 // argument or
239 //          option value. If the string looks like a long option, short option,
240 //          a thread
241 //          group ID or just a number it is rejected as a string type value.
242 //          There is an
243 //          option to allow the string to accept a number as a string type.
244 // Type:    Method.
245 // Args:    vrTxt   - (R) Some text.
246 // Return:  bool    - True = yes valid argument value, false = something else.
247 // Throws:  None.
248 //--
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)
256       return false;
257   }
258
259   // Look for --someLongOption, if found reject
260   if (0 == vrTxt.find("--"))
261     return false;
262
263   // Look for -f type short options, if found reject
264   if ((0 == vrTxt.find('-')) && (vrTxt.length() == 2))
265     return false;
266
267   // Look for thread group i1 i2 i3...., if found reject
268   if ((vrTxt.find('i') == 0) && ::isdigit(vrTxt[1]))
269     return false;
270
271   // Look for numbers, if found reject
272   if (!m_bAcceptNumbers && vrTxt.IsNumber())
273     return false;
274
275   return true;
276 }
277
278 //++
279 //------------------------------------------------------------------------------------
280 // Details: Examine the string and determine if it is a valid string type
281 // argument.
282 //          Take into account quotes surrounding the text. Note this function
283 //          falls
284 //          through to IsStringArgSingleText() should the criteria match fail.
285 // Type:    Method.
286 // Args:    vrTxt   - (R) Some text.
287 // Return:  bool    - True = yes valid arg, false = no.
288 // Throws:  None.
289 //--
290 bool CMICmdArgValString::IsStringArgQuotedText(
291     const CMIUtilString &vrTxt) const {
292   // Accept anything as string word
293   if (m_bHandleAnything)
294     return true;
295
296   // CODETAG_QUOTEDTEXT_SIMILAR_CODE
297   const char cQuote = '"';
298   const size_t nPos = vrTxt.find(cQuote);
299   if (nPos == std::string::npos)
300     return false;
301
302   // Is one and only quote at end of the string
303   if (nPos == (vrTxt.length() - 1))
304     return false;
305
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)) {
312     return false;
313   }
314   if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
315     return false;
316
317   // Need to find the other quote
318   const size_t nPos2 = vrTxt.rfind(cQuote);
319   if (nPos2 == std::string::npos)
320     return false;
321
322   // Make sure not same quote, need two quotes
323   if (nPos == nPos2)
324     return MIstatus::failure;
325
326   return true;
327 }
328
329 //++
330 //------------------------------------------------------------------------------------
331 // Details: Examine the string and determine if it is a valid string type
332 // argument.
333 //          Take into account quotes surrounding the text. Take into account
334 //          string format
335 //          embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
336 //          function falls
337 //          through to IsStringArgQuotedText() 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.
342 //--
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)
349     return false;
350
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))
354     return false;
355
356   // Need to find the other matching slash
357   const size_t nPos2 = vrTxt.rfind(cBckSlash);
358   if (nPos2 == std::string::npos)
359     return false;
360
361   // Make sure not same back slash, need two slashes
362   if (nPos == nPos2)
363     return MIstatus::failure;
364
365   return false;
366 }
367
368 //++
369 //------------------------------------------------------------------------------------
370 // Details: Examine the string and determine if it is a valid string type
371 // argument.
372 //          Take into account quotes surrounding the text. Take into account
373 //          string format
374 //          embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
375 //          function falls
376 //          through to IsStringArgQuotedTextEmbedded() should the criteria match
377 //          fail.
378 // Type:    Method.
379 // Args:    vrTxt   - (R) Some text.
380 // Return:  bool    - True = yes valid arg, false = no.
381 // Throws:  None.
382 //--
383 bool CMICmdArgValString::IsStringArgQuotedQuotedTextEmbedded(
384     const CMIUtilString &vrTxt) const {
385   const size_t nPos = vrTxt.find("\"\\\"");
386   if (nPos == std::string::npos)
387     return false;
388
389   const size_t nPos2 = vrTxt.rfind("\\\"\"");
390   if (nPos2 == std::string::npos)
391     return false;
392
393   const size_t nLen = vrTxt.length();
394   if ((nLen > 5) && ((nPos + 2) == (nPos2 - 2)))
395     return false;
396
397   return true;
398 }