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