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