Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Interpreter/Options.h
Line
Count
Source
1
//===-- Options.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_INTERPRETER_OPTIONS_H
10
#define LLDB_INTERPRETER_OPTIONS_H
11
12
#include <set>
13
#include <vector>
14
15
#include "lldb/Utility/Args.h"
16
#include "lldb/Utility/CompletionRequest.h"
17
#include "lldb/Utility/OptionDefinition.h"
18
#include "lldb/Utility/Status.h"
19
#include "lldb/lldb-defines.h"
20
#include "lldb/lldb-private.h"
21
22
#include "llvm/ADT/ArrayRef.h"
23
#include "llvm/ADT/StringRef.h"
24
25
namespace lldb_private {
26
27
struct Option;
28
29
typedef std::vector<std::tuple<std::string, int, std::string>> OptionArgVector;
30
typedef std::shared_ptr<OptionArgVector> OptionArgVectorSP;
31
32
struct OptionArgElement {
33
  enum { eUnrecognizedArg = -1, eBareDash = -2, eBareDoubleDash = -3 };
34
35
  OptionArgElement(int defs_index, int pos, int arg_pos)
36
53
      : opt_defs_index(defs_index), opt_pos(pos), opt_arg_pos(arg_pos) {}
37
38
  int opt_defs_index;
39
  int opt_pos;
40
  int opt_arg_pos;
41
};
42
43
typedef std::vector<OptionArgElement> OptionElementVector;
44
45
/// \class Options Options.h "lldb/Interpreter/Options.h"
46
/// A command line option parsing protocol class.
47
///
48
/// Options is designed to be subclassed to contain all needed options for a
49
/// given command. The options can be parsed by calling the Parse function.
50
///
51
/// The options are specified using the format defined for the libc options
52
/// parsing function getopt_long_only: \code
53
///     #include <getopt.h>
54
///     int getopt_long_only(int argc, char * const *argv, const char
55
///     *optstring, const struct option *longopts, int *longindex);
56
/// \endcode
57
///
58
class Options {
59
public:
60
  Options();
61
62
  virtual ~Options();
63
64
  void BuildGetoptTable();
65
66
  void BuildValidOptionSets();
67
68
  uint32_t NumCommandOptions();
69
70
  /// Get the option definitions to use when parsing Args options.
71
  ///
72
  /// \see Args::ParseOptions (Options&)
73
  /// \see man getopt_long_only
74
  Option *GetLongOptions();
75
76
  // This gets passed the short option as an integer...
77
  void OptionSeen(int short_option);
78
79
  bool VerifyOptions(CommandReturnObject &result);
80
81
  // Verify that the options given are in the options table and can be used
82
  // together, but there may be some required options that are missing (used to
83
  // verify options that get folded into command aliases).
84
  bool VerifyPartialOptions(CommandReturnObject &result);
85
86
  void OutputFormattedUsageText(Stream &strm,
87
                                const OptionDefinition &option_def,
88
                                uint32_t output_max_columns);
89
90
  void GenerateOptionUsage(Stream &strm, CommandObject &cmd,
91
                           uint32_t screen_width);
92
93
  bool SupportsLongOption(const char *long_option);
94
95
  // The following two pure virtual functions must be defined by every class
96
  // that inherits from this class.
97
98
761k
  virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() {
99
761k
    return llvm::ArrayRef<OptionDefinition>();
100
761k
  }
101
102
  // Call this prior to parsing any options. This call will call the subclass
103
  // OptionParsingStarting() and will avoid the need for all
104
  // OptionParsingStarting() function instances from having to call the
105
  // Option::OptionParsingStarting() like they did before. This was error prone
106
  // and subclasses shouldn't have to do it.
107
  void NotifyOptionParsingStarting(ExecutionContext *execution_context);
108
109
  /// Parse the provided arguments.
110
  ///
111
  /// The parsed options are set via calls to SetOptionValue. In case of a
112
  /// successful parse, the function returns a copy of the input arguments
113
  /// with the parsed options removed. Otherwise, it returns an error.
114
  ///
115
  /// param[in] platform_sp
116
  ///   The platform used for option validation.  This is necessary
117
  ///   because an empty execution_context is not enough to get us
118
  ///   to a reasonable platform.  If the platform isn't given,
119
  ///   we'll try to get it from the execution context.  If we can't
120
  ///   get it from the execution context, we'll skip validation.
121
  ///
122
  /// param[in] require_validation
123
  ///   When true, it will fail option parsing if validation could
124
  ///   not occur due to not having a platform.
125
  llvm::Expected<Args> Parse(const Args &args,
126
                             ExecutionContext *execution_context,
127
                             lldb::PlatformSP platform_sp,
128
                             bool require_validation);
129
130
  llvm::Expected<Args> ParseAlias(const Args &args,
131
                                  OptionArgVector *option_arg_vector,
132
                                  std::string &input_line);
133
134
  OptionElementVector ParseForCompletion(const Args &args,
135
                                         uint32_t cursor_index);
136
137
  Status NotifyOptionParsingFinished(ExecutionContext *execution_context);
138
139
  /// Set the value of an option.
140
  ///
141
  /// \param[in] option_idx
142
  ///     The index into the "struct option" array that was returned
143
  ///     by Options::GetLongOptions().
144
  ///
145
  /// \param[in] option_arg
146
  ///     The argument value for the option that the user entered, or
147
  ///     nullptr if there is no argument for the current option.
148
  ///
149
  /// \param[in] execution_context
150
  ///     The execution context to use for evaluating the option.
151
  ///     May be nullptr if the option is to be evaluated outside any
152
  ///     particular context.
153
  ///
154
  /// \see Args::ParseOptions (Options&)
155
  /// \see man getopt_long_only
156
  virtual Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
157
                                ExecutionContext *execution_context) = 0;
158
159
  /// Handles the generic bits of figuring out whether we are in an option,
160
  /// and if so completing it.
161
  ///
162
  /// \param[in,out] request
163
  ///    The completion request that we need to act upon.
164
  ///
165
  /// \param[in] interpreter
166
  ///     The interpreter that's doing the completing.
167
  ///
168
  /// FIXME: This is the wrong return value, since we also need to
169
  /// make a distinction between total number of matches, and the window the
170
  /// user wants returned.
171
  ///
172
  /// \return
173
  ///     \b true if we were in an option, \b false otherwise.
174
  bool HandleOptionCompletion(lldb_private::CompletionRequest &request,
175
                              OptionElementVector &option_map,
176
                              CommandInterpreter &interpreter);
177
178
  /// Handles the generic bits of figuring out whether we are in an option,
179
  /// and if so completing it.
180
  ///
181
  /// \param[in,out] request
182
  ///    The completion request that we need to act upon.
183
  ///
184
  /// \param[in] interpreter
185
  ///    The command interpreter doing the completion.
186
  virtual void
187
  HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request,
188
                                 OptionElementVector &opt_element_vector,
189
                                 int opt_element_index,
190
                                 CommandInterpreter &interpreter);
191
192
protected:
193
  // This is a set of options expressed as indexes into the options table for
194
  // this Option.
195
  typedef std::set<int> OptionSet;
196
  typedef std::vector<OptionSet> OptionSetVector;
197
198
  std::vector<Option> m_getopt_table;
199
  OptionSet m_seen_options;
200
  OptionSetVector m_required_options;
201
  OptionSetVector m_optional_options;
202
203
509k
  OptionSetVector &GetRequiredOptions() {
204
509k
    BuildValidOptionSets();
205
509k
    return m_required_options;
206
509k
  }
207
208
225k
  OptionSetVector &GetOptionalOptions() {
209
225k
    BuildValidOptionSets();
210
225k
    return m_optional_options;
211
225k
  }
212
213
  bool IsASubset(const OptionSet &set_a, const OptionSet &set_b);
214
215
  size_t OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b,
216
                        OptionSet &diffs);
217
218
  void OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b,
219
                       OptionSet &union_set);
220
221
  // Subclasses must reset their option values prior to starting a new option
222
  // parse. Each subclass must override this function and revert all option
223
  // settings to default values.
224
  virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;
225
226
33.4k
  virtual Status OptionParsingFinished(ExecutionContext *execution_context) {
227
    // If subclasses need to know when the options are done being parsed they
228
    // can implement this function to do extra checking
229
33.4k
    Status error;
230
33.4k
    return error;
231
33.4k
  }
232
};
233
234
class OptionGroup {
235
public:
236
617k
  OptionGroup() = default;
237
238
616k
  virtual ~OptionGroup() = default;
239
240
  virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() = 0;
241
242
  virtual Status SetOptionValue(uint32_t option_idx,
243
                                llvm::StringRef option_value,
244
                                ExecutionContext *execution_context) = 0;
245
246
  virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;
247
248
29.4k
  virtual Status OptionParsingFinished(ExecutionContext *execution_context) {
249
    // If subclasses need to know when the options are done being parsed they
250
    // can implement this function to do extra checking
251
29.4k
    Status error;
252
29.4k
    return error;
253
29.4k
  }
254
};
255
256
class OptionGroupOptions : public Options {
257
public:
258
255k
  OptionGroupOptions() = default;
259
260
255k
  ~OptionGroupOptions() override = default;
261
262
  /// Append options from a OptionGroup class.
263
  ///
264
  /// Append all options from \a group using the exact same option groups that
265
  /// each option is defined with.
266
  ///
267
  /// \param[in] group
268
  ///     A group of options to take option values from and copy their
269
  ///     definitions into this class.
270
  void Append(OptionGroup *group);
271
272
  /// Append options from a OptionGroup class.
273
  ///
274
  /// Append options from \a group that have a usage mask that has any bits in
275
  /// "src_mask" set. After the option definition is copied into the options
276
  /// definitions in this class, set the usage_mask to "dst_mask".
277
  ///
278
  /// \param[in] group
279
  ///     A group of options to take option values from and copy their
280
  ///     definitions into this class.
281
  ///
282
  /// \param[in] src_mask
283
  ///     When copying options from \a group, you might only want some of
284
  ///     the options to be appended to this group. This mask allows you
285
  ///     to control which options from \a group get added. It also allows
286
  ///     you to specify the same options from \a group multiple times
287
  ///     for different option sets.
288
  ///
289
  /// \param[in] dst_mask
290
  ///     Set the usage mask for any copied options to \a dst_mask after
291
  ///     copying the option definition.
292
  void Append(OptionGroup *group, uint32_t src_mask, uint32_t dst_mask);
293
294
  /// Append selected options from a OptionGroup class.
295
  ///
296
  /// Append the subset of options from \a group, where the "long_option" value
297
  /// is _not_ in \a exclude_long_options.
298
  ///
299
  /// \param[in] group
300
  ///     A group of options to take option values from and copy their
301
  ///     definitions into this class.
302
  ///
303
  /// \param[in] exclude_long_options
304
  ///     A set of long option strings which indicate which option values values
305
  ///     to limit from \a group.
306
  void Append(OptionGroup *group,
307
              llvm::ArrayRef<llvm::StringRef> exclude_long_options);
308
309
  void Finalize();
310
311
18
  bool DidFinalize() { return m_did_finalize; }
312
313
  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
314
                        ExecutionContext *execution_context) override;
315
316
  void OptionParsingStarting(ExecutionContext *execution_context) override;
317
318
  Status OptionParsingFinished(ExecutionContext *execution_context) override;
319
320
114k
  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
321
114k
    assert(m_did_finalize);
322
114k
    return m_option_defs;
323
114k
  }
324
325
  const OptionGroup *GetGroupWithOption(char short_opt);
326
327
  struct OptionInfo {
328
2.24M
    OptionInfo(OptionGroup *g, uint32_t i) : option_group(g), option_index(i) {}
329
    OptionGroup *option_group; // The group that this option came from
330
    uint32_t option_index;     // The original option index from the OptionGroup
331
  };
332
  typedef std::vector<OptionInfo> OptionInfos;
333
334
  std::vector<OptionDefinition> m_option_defs;
335
  OptionInfos m_option_infos;
336
  bool m_did_finalize = false;
337
};
338
339
} // namespace lldb_private
340
341
#endif // LLDB_INTERPRETER_OPTIONS_H