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