xref: /freebsd-src/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
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 
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 
30 struct 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 
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:
269   OptionGroupOptions()
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;
333   bool m_did_finalize;
334 };
335 
336 } // namespace lldb_private
337 
338 #endif // liblldb_Options_h_
339