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       : 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   virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() {
99     return llvm::ArrayRef<OptionDefinition>();
100   }
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   OptionSetVector &GetRequiredOptions() {
204     BuildValidOptionSets();
205     return m_required_options;
206   }
207 
208   OptionSetVector &GetOptionalOptions() {
209     BuildValidOptionSets();
210     return m_optional_options;
211   }
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   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     Status error;
230     return error;
231   }
232 };
233 
234 class OptionGroup {
235 public:
236   OptionGroup() = default;
237 
238   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   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     Status error;
252     return error;
253   }
254 };
255 
256 class OptionGroupOptions : public Options {
257 public:
258   OptionGroupOptions() = default;
259 
260   ~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   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   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
321     assert(m_did_finalize);
322     return m_option_defs;
323   }
324 
325   const OptionGroup *GetGroupWithOption(char short_opt);
326 
327   struct OptionInfo {
328     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
342