Coverage Report

Created: 2023-09-30 09:22

/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