/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Utility/Args.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- Args.h --------------------------------------------------*- 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 | | #ifndef LLDB_UTILITY_ARGS_H |
10 | | #define LLDB_UTILITY_ARGS_H |
11 | | |
12 | | #include "lldb/Utility/Environment.h" |
13 | | #include "lldb/lldb-private-types.h" |
14 | | #include "lldb/lldb-types.h" |
15 | | #include "llvm/ADT/ArrayRef.h" |
16 | | #include "llvm/ADT/StringRef.h" |
17 | | #include "llvm/Support/YAMLTraits.h" |
18 | | #include <string> |
19 | | #include <utility> |
20 | | #include <vector> |
21 | | |
22 | | namespace lldb_private { |
23 | | |
24 | | /// \class Args Args.h "lldb/Utility/Args.h" |
25 | | /// A command line argument class. |
26 | | /// |
27 | | /// The Args class is designed to be fed a command line. The command line is |
28 | | /// copied into an internal buffer and then split up into arguments. Arguments |
29 | | /// are space delimited if there are no quotes (single, double, or backtick |
30 | | /// quotes) surrounding the argument. Spaces can be escaped using a \ |
31 | | /// character to avoid having to surround an argument that contains a space |
32 | | /// with quotes. |
33 | | class Args { |
34 | | public: |
35 | | struct ArgEntry { |
36 | | private: |
37 | | friend class Args; |
38 | | |
39 | | std::unique_ptr<char[]> ptr; |
40 | | char quote = '\0'; |
41 | | |
42 | 2.57M | char *data() { return ptr.get(); } |
43 | | |
44 | | public: |
45 | 14 | ArgEntry() = default; |
46 | | ArgEntry(llvm::StringRef str, char quote); |
47 | | |
48 | 880k | llvm::StringRef ref() const { return c_str(); } |
49 | 1.31M | const char *c_str() const { return ptr.get(); } |
50 | | |
51 | | /// Returns true if this argument was quoted in any way. |
52 | 1.75k | bool IsQuoted() const { return quote != '\0'; } |
53 | 217k | char GetQuoteChar() const { return quote; } |
54 | | }; |
55 | | |
56 | | /// Construct with an option command string. |
57 | | /// |
58 | | /// \param[in] command |
59 | | /// A NULL terminated command that will be copied and split up |
60 | | /// into arguments. |
61 | | /// |
62 | | /// \see Args::SetCommandString(llvm::StringRef) |
63 | | Args(llvm::StringRef command = llvm::StringRef()); |
64 | | |
65 | | Args(const Args &rhs); |
66 | | explicit Args(const StringList &list); |
67 | | explicit Args(llvm::ArrayRef<llvm::StringRef> args); |
68 | | |
69 | | Args &operator=(const Args &rhs); |
70 | | |
71 | | /// Destructor. |
72 | | ~Args(); |
73 | | |
74 | 4 | explicit Args(const Environment &env) : Args() { |
75 | 4 | SetArguments(const_cast<const char **>(env.getEnvp().get())); |
76 | 4 | } |
77 | | |
78 | 9.78k | explicit operator Environment() const { return GetConstArgumentVector(); } |
79 | | |
80 | | /// Dump all entries to the stream \a s using label \a label_name. |
81 | | /// |
82 | | /// If label_name is nullptr, the dump operation is skipped. |
83 | | /// |
84 | | /// \param[in] s |
85 | | /// The stream to which to dump all arguments in the argument |
86 | | /// vector. |
87 | | /// \param[in] label_name |
88 | | /// The label_name to use as the label printed for each |
89 | | /// entry of the args like so: |
90 | | /// {label_name}[{index}]={value} |
91 | | void Dump(Stream &s, const char *label_name = "argv") const; |
92 | | |
93 | | /// Sets the command string contained by this object. |
94 | | /// |
95 | | /// The command string will be copied and split up into arguments that can |
96 | | /// be accessed via the accessor functions. |
97 | | /// |
98 | | /// \param[in] command |
99 | | /// A command StringRef that will be copied and split up |
100 | | /// into arguments. |
101 | | /// |
102 | | /// \see Args::GetArgumentCount() const |
103 | | /// \see Args::GetArgumentAtIndex (size_t) const @see |
104 | | /// Args::GetArgumentVector () \see Args::Shift () \see Args::Unshift (const |
105 | | /// char *) |
106 | | void SetCommandString(llvm::StringRef command); |
107 | | |
108 | | bool GetCommandString(std::string &command) const; |
109 | | |
110 | | bool GetQuotedCommandString(std::string &command) const; |
111 | | |
112 | | /// Gets the number of arguments left in this command object. |
113 | | /// |
114 | | /// \return |
115 | | /// The number or arguments in this object. |
116 | 660k | size_t GetArgumentCount() const { return m_entries.size(); } |
117 | | |
118 | 22.2k | bool empty() const { return GetArgumentCount() == 0; } |
119 | | |
120 | | /// Gets the NULL terminated C string argument pointer for the argument at |
121 | | /// index \a idx. |
122 | | /// |
123 | | /// \return |
124 | | /// The NULL terminated C string argument pointer if \a idx is a |
125 | | /// valid argument index, NULL otherwise. |
126 | | const char *GetArgumentAtIndex(size_t idx) const; |
127 | | |
128 | 77.2k | llvm::ArrayRef<ArgEntry> entries() const { return m_entries; } |
129 | | |
130 | | using const_iterator = std::vector<ArgEntry>::const_iterator; |
131 | | |
132 | 297k | const_iterator begin() const { return m_entries.begin(); } |
133 | 358k | const_iterator end() const { return m_entries.end(); } |
134 | | |
135 | 230 | size_t size() const { return GetArgumentCount(); } |
136 | 155k | const ArgEntry &operator[](size_t n) const { return m_entries[n]; } |
137 | | |
138 | | /// Gets the argument vector. |
139 | | /// |
140 | | /// The value returned by this function can be used by any function that |
141 | | /// takes and vector. The return value is just like \a argv in the standard |
142 | | /// C entry point function: |
143 | | /// \code |
144 | | /// int main (int argc, const char **argv); |
145 | | /// \endcode |
146 | | /// |
147 | | /// \return |
148 | | /// An array of NULL terminated C string argument pointers that |
149 | | /// also has a terminating NULL C string pointer |
150 | | char **GetArgumentVector(); |
151 | | |
152 | | /// Gets the argument vector. |
153 | | /// |
154 | | /// The value returned by this function can be used by any function that |
155 | | /// takes and vector. The return value is just like \a argv in the standard |
156 | | /// C entry point function: |
157 | | /// \code |
158 | | /// int main (int argc, const char **argv); |
159 | | /// \endcode |
160 | | /// |
161 | | /// \return |
162 | | /// An array of NULL terminate C string argument pointers that |
163 | | /// also has a terminating NULL C string pointer |
164 | | const char **GetConstArgumentVector() const; |
165 | | |
166 | | /// Gets the argument as an ArrayRef. Note that the return value does *not* |
167 | | /// have a nullptr const char * at the end, as the size of the list is |
168 | | /// embedded in the ArrayRef object. |
169 | 257 | llvm::ArrayRef<const char *> GetArgumentArrayRef() const { |
170 | 257 | return llvm::ArrayRef(m_argv).drop_back(); |
171 | 257 | } |
172 | | |
173 | | /// Appends a new argument to the end of the list argument list. |
174 | | /// |
175 | | /// \param[in] arg_str |
176 | | /// The new argument. |
177 | | /// |
178 | | /// \param[in] quote_char |
179 | | /// If the argument was originally quoted, put in the quote char here. |
180 | | void AppendArgument(llvm::StringRef arg_str, char quote_char = '\0'); |
181 | | |
182 | | void AppendArguments(const Args &rhs); |
183 | | |
184 | | void AppendArguments(const char **argv); |
185 | | |
186 | | /// Insert the argument value at index \a idx to \a arg_str. |
187 | | /// |
188 | | /// \param[in] idx |
189 | | /// The index of where to insert the argument. |
190 | | /// |
191 | | /// \param[in] arg_str |
192 | | /// The new argument. |
193 | | /// |
194 | | /// \param[in] quote_char |
195 | | /// If the argument was originally quoted, put in the quote char here. |
196 | | void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, |
197 | | char quote_char = '\0'); |
198 | | |
199 | | /// Replaces the argument value at index \a idx to \a arg_str if \a idx is |
200 | | /// a valid argument index. |
201 | | /// |
202 | | /// \param[in] idx |
203 | | /// The index of the argument that will have its value replaced. |
204 | | /// |
205 | | /// \param[in] arg_str |
206 | | /// The new argument. |
207 | | /// |
208 | | /// \param[in] quote_char |
209 | | /// If the argument was originally quoted, put in the quote char here. |
210 | | void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, |
211 | | char quote_char = '\0'); |
212 | | |
213 | | /// Deletes the argument value at index |
214 | | /// if \a idx is a valid argument index. |
215 | | /// |
216 | | /// \param[in] idx |
217 | | /// The index of the argument that will have its value replaced. |
218 | | /// |
219 | | void DeleteArgumentAtIndex(size_t idx); |
220 | | |
221 | | /// Sets the argument vector value, optionally copying all arguments into an |
222 | | /// internal buffer. |
223 | | /// |
224 | | /// Sets the arguments to match those found in \a argv. All argument strings |
225 | | /// will be copied into an internal buffers. |
226 | | // |
227 | | // FIXME: Handle the quote character somehow. |
228 | | void SetArguments(size_t argc, const char **argv); |
229 | | |
230 | | void SetArguments(const char **argv); |
231 | | |
232 | | /// Shifts the first argument C string value of the array off the argument |
233 | | /// array. |
234 | | /// |
235 | | /// The string value will be freed, so a copy of the string should be made |
236 | | /// by calling Args::GetArgumentAtIndex (size_t) const first and copying the |
237 | | /// returned value before calling Args::Shift(). |
238 | | /// |
239 | | /// \see Args::GetArgumentAtIndex (size_t) const |
240 | | void Shift(); |
241 | | |
242 | | /// Inserts a class owned copy of \a arg_str at the beginning of the |
243 | | /// argument vector. |
244 | | /// |
245 | | /// A copy \a arg_str will be made. |
246 | | /// |
247 | | /// \param[in] arg_str |
248 | | /// The argument to push on the front of the argument stack. |
249 | | /// |
250 | | /// \param[in] quote_char |
251 | | /// If the argument was originally quoted, put in the quote char here. |
252 | | void Unshift(llvm::StringRef arg_str, char quote_char = '\0'); |
253 | | |
254 | | /// Clear the arguments. |
255 | | /// |
256 | | /// For re-setting or blanking out the list of arguments. |
257 | | void Clear(); |
258 | | |
259 | | static lldb::Encoding |
260 | | StringToEncoding(llvm::StringRef s, |
261 | | lldb::Encoding fail_value = lldb::eEncodingInvalid); |
262 | | |
263 | | static uint32_t StringToGenericRegister(llvm::StringRef s); |
264 | | |
265 | | static std::string GetShellSafeArgument(const FileSpec &shell, |
266 | | llvm::StringRef unsafe_arg); |
267 | | |
268 | | /// EncodeEscapeSequences will change the textual representation of common |
269 | | /// escape sequences like "\n" (two characters) into a single '\n'. It does |
270 | | /// this for all of the supported escaped sequences and for the \0ooo (octal) |
271 | | /// and \xXX (hex). The resulting "dst" string will contain the character |
272 | | /// versions of all supported escape sequences. The common supported escape |
273 | | /// sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\". |
274 | | static void EncodeEscapeSequences(const char *src, std::string &dst); |
275 | | |
276 | | /// ExpandEscapeSequences will change a string of possibly non-printable |
277 | | /// characters and expand them into text. So '\n' will turn into two |
278 | | /// characters like "\n" which is suitable for human reading. When a character |
279 | | /// is not printable and isn't one of the common in escape sequences listed in |
280 | | /// the help for EncodeEscapeSequences, then it will be encoded as octal. |
281 | | /// Printable characters are left alone. |
282 | | static void ExpandEscapedCharacters(const char *src, std::string &dst); |
283 | | |
284 | | static std::string EscapeLLDBCommandArgument(const std::string &arg, |
285 | | char quote_char); |
286 | | |
287 | | private: |
288 | | std::vector<ArgEntry> m_entries; |
289 | | /// The arguments as C strings with a trailing nullptr element. |
290 | | /// |
291 | | /// These strings are owned by the ArgEntry object in m_entries with the |
292 | | /// same index. |
293 | | std::vector<char *> m_argv; |
294 | | }; |
295 | | |
296 | | /// \class OptionsWithRaw Args.h "lldb/Utility/Args.h" |
297 | | /// A pair of an option list with a 'raw' string as a suffix. |
298 | | /// |
299 | | /// This class works similar to Args, but handles the case where we have a |
300 | | /// trailing string that shouldn't be interpreted as a list of arguments but |
301 | | /// preserved as is. It is also only useful for handling command line options |
302 | | /// (e.g. '-foo bar -i0') that start with a dash. |
303 | | /// |
304 | | /// The leading option list is optional. If the first non-space character |
305 | | /// in the string starts with a dash, and the string contains an argument |
306 | | /// that is an unquoted double dash (' -- '), then everything up to the double |
307 | | /// dash is parsed as a list of arguments. Everything after the double dash |
308 | | /// is interpreted as the raw suffix string. Note that the space behind the |
309 | | /// double dash is not part of the raw suffix. |
310 | | /// |
311 | | /// All strings not matching the above format as considered to be just a raw |
312 | | /// string without any options. |
313 | | /// |
314 | | /// \see Args |
315 | | class OptionsWithRaw { |
316 | | public: |
317 | | /// Parse the given string as a list of optional arguments with a raw suffix. |
318 | | /// |
319 | | /// See the class description for a description of the input format. |
320 | | /// |
321 | | /// \param[in] argument_string |
322 | | /// The string that should be parsed. |
323 | | explicit OptionsWithRaw(llvm::StringRef argument_string); |
324 | | |
325 | | /// Returns true if there are any arguments before the raw suffix. |
326 | 4.07k | bool HasArgs() const { return m_has_args; } |
327 | | |
328 | | /// Returns the list of arguments. |
329 | | /// |
330 | | /// You can only call this method if HasArgs returns true. |
331 | 569 | Args &GetArgs() { |
332 | 569 | assert(m_has_args); |
333 | 569 | return m_args; |
334 | 569 | } |
335 | | |
336 | | /// Returns the list of arguments. |
337 | | /// |
338 | | /// You can only call this method if HasArgs returns true. |
339 | 0 | const Args &GetArgs() const { |
340 | 0 | assert(m_has_args); |
341 | 0 | return m_args; |
342 | 0 | } |
343 | | |
344 | | /// Returns the part of the input string that was used for parsing the |
345 | | /// argument list. This string also includes the double dash that is used |
346 | | /// for separating the argument list from the suffix. |
347 | | /// |
348 | | /// You can only call this method if HasArgs returns true. |
349 | 17 | llvm::StringRef GetArgStringWithDelimiter() const { |
350 | 17 | assert(m_has_args); |
351 | 17 | return m_arg_string_with_delimiter; |
352 | 17 | } |
353 | | |
354 | | /// Returns the part of the input string that was used for parsing the |
355 | | /// argument list. |
356 | | /// |
357 | | /// You can only call this method if HasArgs returns true. |
358 | 17 | llvm::StringRef GetArgString() const { |
359 | 17 | assert(m_has_args); |
360 | 17 | return m_arg_string; |
361 | 17 | } |
362 | | |
363 | | /// Returns the raw suffix part of the parsed string. |
364 | 4.00k | const std::string &GetRawPart() const { return m_suffix; } |
365 | | |
366 | | private: |
367 | | void SetFromString(llvm::StringRef arg_string); |
368 | | |
369 | | /// Keeps track if we have parsed and stored any arguments. |
370 | | bool m_has_args = false; |
371 | | Args m_args; |
372 | | llvm::StringRef m_arg_string; |
373 | | llvm::StringRef m_arg_string_with_delimiter; |
374 | | |
375 | | // FIXME: This should be a StringRef, but some of the calling code expect a |
376 | | // C string here so only a real std::string is possible. |
377 | | std::string m_suffix; |
378 | | }; |
379 | | |
380 | | } // namespace lldb_private |
381 | | |
382 | | #endif // LLDB_UTILITY_ARGS_H |