]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdArgValString.cpp
Merge lldb trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdArgValString.cpp
1 //===-- MICmdArgValString.cpp -----------------------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8
9 // In-house headers:
10 #include "MICmdArgValString.h"
11 #include "MICmdArgContext.h"
12
13 //++
14 // Details: CMICmdArgValString constructor.
15 // Type:    Method.
16 // Args:    None.
17 // Return:  None.
18 // Throws:  None.
19 //--
20 CMICmdArgValString::CMICmdArgValString()
21     : m_bHandleQuotedString(false), m_bAcceptNumbers(false),
22       m_bHandleDirPaths(false), m_bHandleAnything(false) {}
23
24 //++
25 // Details: CMICmdArgValString constructor.
26 // Type:    Method.
27 // Args:    vbAnything  - (R) True = Parse a string and accept anything, false =
28 // do not accept anything.
29 // Return:  None.
30 // Throws:  None.
31 //--
32 CMICmdArgValString::CMICmdArgValString(const bool vbAnything)
33     : m_bHandleQuotedString(vbAnything), m_bAcceptNumbers(false),
34       m_bHandleDirPaths(false), m_bHandleAnything(vbAnything) {}
35
36 //++
37 // Details: CMICmdArgValString constructor.
38 // Type:    Method.
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
44 // as string types.
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.
48 // Return:  None.
49 // Throws:  None.
50 //--
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) {}
56
57 //++
58 // Details: CMICmdArgValString constructor.
59 // Type:    Method.
60 // Args:    vrArgName       - (R) Argument's name to search by.
61 //          vbMandatory     - (R) True = Yes must be present, false = optional
62 //          argument.
63 //          vbHandleByCmd   - (R) True = Command processes *this option, false =
64 //          not handled.
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)
71 // Return:  None.
72 // Throws:  None.
73 //--
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) {}
82
83 //++
84 // Details: CMICmdArgValString constructor.
85 // Type:    Method.
86 // Args:    vrArgName       - (R) Argument's name to search by.
87 //          vbMandatory     - (R) True = Yes must be present, false = optional
88 //          argument.
89 //          vbHandleByCmd   - (R) True = Command processes *this option, false =
90 //          not handled.
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
98 // string types.
99 // Return:  None.
100 // Throws:  None.
101 //--
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) {}
111
112 //++
113 // Details: CMICmdArgValString destructor.
114 // Type:    Overridden.
115 // Args:    None.
116 // Return:  None.
117 // Throws:  None.
118 //--
119 CMICmdArgValString::~CMICmdArgValString() {}
120
121 //++
122 // Details: Parse the command's argument options string and try to extract the
123 // value *this
124 //          argument is looking for.
125 // Type:    Overridden.
126 // Args:    vrwArgContext   - (RW) The command's argument options string.
127 // Return:  MIstatus::success - Functional succeeded.
128 //          MIstatus::failure - Functional failed.
129 // Throws:  None.
130 //--
131 bool CMICmdArgValString::Validate(CMICmdArgContext &vrwArgContext) {
132   if (vrwArgContext.IsEmpty())
133     return m_bMandatory ? MIstatus::failure : MIstatus::success;
134
135   if (m_bHandleQuotedString)
136     return ValidateQuotedText(vrwArgContext);
137
138   return ValidateSingleText(vrwArgContext);
139 }
140
141 //++
142 // Details: Parse the command's argument options string and try to extract only
143 // the next
144 //          word delimited by the next space.
145 // Type:    Method.
146 // Args:    vrwArgContext   - (RW) The command's argument options string.
147 // Return:  MIstatus::success - Functional succeeded.
148 //          MIstatus::failure - Functional failed.
149 // Throws:  None.
150 //--
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)) {
157       m_bFound = true;
158
159       if (vrwArgContext.RemoveArg(rArg)) {
160         m_bValid = true;
161         m_argValue = rArg.StripSlashes();
162         return MIstatus::success;
163       } else
164         return MIstatus::failure;
165     }
166
167     // Next
168     ++it;
169   }
170
171   return MIstatus::failure;
172 }
173
174 //++
175 // Details: Parse the command's argument options string and try to extract all
176 // the words
177 //          between quotes then delimited by the next space.
178 // Type:    Method.
179 // Args:    vrwArgContext   - (RW) The command's argument options string.
180 // Return:  MIstatus::success - Functional succeeded.
181 //          MIstatus::failure - Functional failed.
182 // Throws:  None.
183 //--
184 bool CMICmdArgValString::ValidateQuotedText(CMICmdArgContext &vrwArgContext) {
185   const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
186   if (vecOptions.size() == 0)
187     return MIstatus::failure;
188
189   const CMIUtilString &rArg(vecOptions[0]);
190   if (!IsStringArg(rArg))
191     return MIstatus::failure;
192
193   m_bFound = true;
194
195   if (vrwArgContext.RemoveArg(rArg)) {
196     m_bValid = true;
197     const char cQuote = '"';
198     m_argValue = rArg.Trim(cQuote).StripSlashes();
199     return MIstatus::success;
200   }
201
202   return MIstatus::failure;
203 }
204
205 //++
206 // Details: Examine the string and determine if it is a valid string type
207 // argument.
208 // Type:    Method.
209 // Args:    vrTxt   - (R) Some text.
210 // Return:  bool    - True = yes valid arg, false = no.
211 // Throws:  None.
212 //--
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
220
221   return IsStringArgSingleText(vrTxt);
222 }
223
224 //++
225 // Details: Examine the string and determine if it is a valid string type
226 // argument or
227 //          option value. If the string looks like a long option, short option,
228 //          a thread
229 //          group ID or just a number it is rejected as a string type value.
230 //          There is an
231 //          option to allow the string to accept a number as a string type.
232 // Type:    Method.
233 // Args:    vrTxt   - (R) Some text.
234 // Return:  bool    - True = yes valid argument value, false = something else.
235 // Throws:  None.
236 //--
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)
244       return false;
245   }
246
247   // Look for --someLongOption, if found reject
248   if (0 == vrTxt.find("--"))
249     return false;
250
251   // Look for -f type short options, if found reject
252   if ((0 == vrTxt.find('-')) && (vrTxt.length() == 2))
253     return false;
254
255   // Look for thread group i1 i2 i3...., if found reject
256   if ((vrTxt.find('i') == 0) && ::isdigit(vrTxt[1]))
257     return false;
258
259   // Look for numbers, if found reject
260   if (!m_bAcceptNumbers && vrTxt.IsNumber())
261     return false;
262
263   return true;
264 }
265
266 //++
267 // Details: Examine the string and determine if it is a valid string type
268 // argument.
269 //          Take into account quotes surrounding the text. Note this function
270 //          falls
271 //          through to IsStringArgSingleText() should the criteria match fail.
272 // Type:    Method.
273 // Args:    vrTxt   - (R) Some text.
274 // Return:  bool    - True = yes valid arg, false = no.
275 // Throws:  None.
276 //--
277 bool CMICmdArgValString::IsStringArgQuotedText(
278     const CMIUtilString &vrTxt) const {
279   // Accept anything as string word
280   if (m_bHandleAnything)
281     return true;
282
283   // CODETAG_QUOTEDTEXT_SIMILAR_CODE
284   const char cQuote = '"';
285   const size_t nPos = vrTxt.find(cQuote);
286   if (nPos == std::string::npos)
287     return false;
288
289   // Is one and only quote at end of the string
290   if (nPos == (vrTxt.length() - 1))
291     return false;
292
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)) {
299     return false;
300   }
301   if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
302     return false;
303
304   // Need to find the other quote
305   const size_t nPos2 = vrTxt.rfind(cQuote);
306   if (nPos2 == std::string::npos)
307     return false;
308
309   // Make sure not same quote, need two quotes
310   if (nPos == nPos2)
311     return MIstatus::failure;
312
313   return true;
314 }
315
316 //++
317 // Details: Examine the string and determine if it is a valid string type
318 // argument.
319 //          Take into account quotes surrounding the text. Take into account
320 //          string format
321 //          embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
322 //          function falls
323 //          through to IsStringArgQuotedText() should the criteria match fail.
324 // Type:    Method.
325 // Args:    vrTxt   - (R) Some text.
326 // Return:  bool    - True = yes valid arg, false = no.
327 // Throws:  None.
328 //--
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)
335     return false;
336
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))
340     return false;
341
342   // Need to find the other matching slash
343   const size_t nPos2 = vrTxt.rfind(cBckSlash);
344   if (nPos2 == std::string::npos)
345     return false;
346
347   // Make sure not same back slash, need two slashes
348   if (nPos == nPos2)
349     return MIstatus::failure;
350
351   return false;
352 }
353
354 //++
355 // Details: Examine the string and determine if it is a valid string type
356 // argument.
357 //          Take into account quotes surrounding the text. Take into account
358 //          string format
359 //          embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
360 //          function falls
361 //          through to IsStringArgQuotedTextEmbedded() should the criteria match
362 //          fail.
363 // Type:    Method.
364 // Args:    vrTxt   - (R) Some text.
365 // Return:  bool    - True = yes valid arg, false = no.
366 // Throws:  None.
367 //--
368 bool CMICmdArgValString::IsStringArgQuotedQuotedTextEmbedded(
369     const CMIUtilString &vrTxt) const {
370   const size_t nPos = vrTxt.find("\"\\\"");
371   if (nPos == std::string::npos)
372     return false;
373
374   const size_t nPos2 = vrTxt.rfind("\\\"\"");
375   if (nPos2 == std::string::npos)
376     return false;
377
378   const size_t nLen = vrTxt.length();
379   return !((nLen > 5) && ((nPos + 2) == (nPos2 - 2)));
380 }