LLDB  mainline
Options.h
Go to the documentation of this file.
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"
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 
23 namespace lldb_private {
24 
25 struct Option;
26 
27 typedef std::vector<std::tuple<std::string, int, std::string>> OptionArgVector;
28 typedef std::shared_ptr<OptionArgVector> OptionArgVectorSP;
29 
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 
37  int opt_pos;
39 };
40 
41 typedef std::vector<OptionArgElement> OptionElementVector;
42 
43 static 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 ///
62 class Options {
63 public:
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  ///
191  /// FIXME: This is the wrong return value, since we also need to
192  /// make a distinction between total number of matches, and the window the
193  /// user wants returned.
194  ///
195  /// \return
196  /// \btrue if we were in an option, \bfalse otherwise.
197  virtual bool
198  HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request,
199  OptionElementVector &opt_element_vector,
200  int opt_element_index,
201  CommandInterpreter &interpreter);
202 
203 protected:
204  // This is a set of options expressed as indexes into the options table for
205  // this Option.
206  typedef std::set<int> OptionSet;
207  typedef std::vector<OptionSet> OptionSetVector;
208 
209  std::vector<Option> m_getopt_table;
210  OptionSet m_seen_options;
211  OptionSetVector m_required_options;
212  OptionSetVector m_optional_options;
213 
214  OptionSetVector &GetRequiredOptions() {
215  BuildValidOptionSets();
216  return m_required_options;
217  }
218 
219  OptionSetVector &GetOptionalOptions() {
220  BuildValidOptionSets();
221  return m_optional_options;
222  }
223 
224  bool IsASubset(const OptionSet &set_a, const OptionSet &set_b);
225 
226  size_t OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b,
227  OptionSet &diffs);
228 
229  void OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b,
230  OptionSet &union_set);
231 
232  // Subclasses must reset their option values prior to starting a new option
233  // parse. Each subclass must override this function and revert all option
234  // settings to default values.
235  virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;
236 
237  virtual Status OptionParsingFinished(ExecutionContext *execution_context) {
238  // If subclasses need to know when the options are done being parsed they
239  // can implement this function to do extra checking
240  Status error;
241  return error;
242  }
243 };
244 
245 class OptionGroup {
246 public:
247  OptionGroup() = default;
248 
249  virtual ~OptionGroup() = default;
250 
251  virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() = 0;
252 
253  virtual Status SetOptionValue(uint32_t option_idx,
254  llvm::StringRef option_value,
255  ExecutionContext *execution_context) = 0;
256 
257  virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;
258 
259  virtual Status OptionParsingFinished(ExecutionContext *execution_context) {
260  // If subclasses need to know when the options are done being parsed they
261  // can implement this function to do extra checking
262  Status error;
263  return error;
264  }
265 };
266 
267 class OptionGroupOptions : public Options {
268 public:
270  : Options(), m_option_defs(), m_option_infos(), m_did_finalize(false) {}
271 
272  ~OptionGroupOptions() override = default;
273 
274  /// Append options from a OptionGroup class.
275  ///
276  /// Append all options from \a group using the exact same option groups that
277  /// each option is defined with.
278  ///
279  /// \param[in] group
280  /// A group of options to take option values from and copy their
281  /// definitions into this class.
282  void Append(OptionGroup *group);
283 
284  /// Append options from a OptionGroup class.
285  ///
286  /// Append options from \a group that have a usage mask that has any bits in
287  /// "src_mask" set. After the option definition is copied into the options
288  /// definitions in this class, set the usage_mask to "dst_mask".
289  ///
290  /// \param[in] group
291  /// A group of options to take option values from and copy their
292  /// definitions into this class.
293  ///
294  /// \param[in] src_mask
295  /// When copying options from \a group, you might only want some of
296  /// the options to be appended to this group. This mask allows you
297  /// to control which options from \a group get added. It also allows
298  /// you to specify the same options from \a group multiple times
299  /// for different option sets.
300  ///
301  /// \param[in] dst_mask
302  /// Set the usage mask for any copied options to \a dst_mask after
303  /// copying the option definition.
304  void Append(OptionGroup *group, uint32_t src_mask, uint32_t dst_mask);
305 
306  void Finalize();
307 
308  bool DidFinalize() { return m_did_finalize; }
309 
310  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
311  ExecutionContext *execution_context) override;
312 
313  void OptionParsingStarting(ExecutionContext *execution_context) override;
314 
315  Status OptionParsingFinished(ExecutionContext *execution_context) override;
316 
317  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
318  assert(m_did_finalize);
319  return m_option_defs;
320  }
321 
322  const OptionGroup *GetGroupWithOption(char short_opt);
323 
324  struct OptionInfo {
325  OptionInfo(OptionGroup *g, uint32_t i) : option_group(g), option_index(i) {}
326  OptionGroup *option_group; // The group that this option came from
327  uint32_t option_index; // The original option index from the OptionGroup
328  };
329  typedef std::vector<OptionInfo> OptionInfos;
330 
331  std::vector<OptionDefinition> m_option_defs;
332  OptionInfos m_option_infos;
334 };
335 
336 } // namespace lldb_private
337 
338 #endif // liblldb_Options_h_
OptionSetVector & GetRequiredOptions()
Definition: Options.h:214
A command line argument class.
Definition: Args.h:32
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
static bool isprint(char32_t codepoint)
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
OptionSet m_seen_options
Definition: Options.h:210
std::vector< OptionInfo > OptionInfos
Definition: Options.h:329
OptionSetVector & GetOptionalOptions()
Definition: Options.h:219
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
std::vector< OptionSet > OptionSetVector
Definition: Options.h:207
OptionSetVector m_required_options
Definition: Options.h:211
std::vector< Option > m_getopt_table
Definition: Options.h:209
"lldb/Utility/ArgCompletionRequest.h"
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:41
virtual llvm::ArrayRef< OptionDefinition > GetDefinitions()
Definition: Options.h:102
Node * Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc)
Parse the given postfix expression.
std::vector< std::tuple< std::string, int, std::string > > OptionArgVector
Definition: Options.h:25
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: Options.h:317
virtual Status OptionParsingFinished(ExecutionContext *execution_context)
Definition: Options.h:237
virtual Status OptionParsingFinished(ExecutionContext *execution_context)
Definition: Options.h:259
std::set< int > OptionSet
Definition: Options.h:206
A command line option parsing protocol class.
Definition: Options.h:62
OptionSetVector m_optional_options
Definition: Options.h:212
static bool isprint8(int ch)
Definition: Options.h:43
std::shared_ptr< OptionArgVector > OptionArgVectorSP
Definition: Options.h:28
OptionArgElement(int defs_index, int pos, int arg_pos)
Definition: Options.h:33
OptionInfo(OptionGroup *g, uint32_t i)
Definition: Options.h:325
std::vector< OptionDefinition > m_option_defs
Definition: Options.h:331
An error handling class.
Definition: Status.h:44