1 //===-- Options.h -----------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_Options_h_
10 #define liblldb_Options_h_
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"
21 #include "llvm/ADT/ArrayRef.h"
23 namespace lldb_private {
27 typedef std::vector<std::tuple<std::string, int, std::string>> OptionArgVector;
28 typedef std::shared_ptr<OptionArgVector> OptionArgVectorSP;
30 struct OptionArgElement {
31 enum { eUnrecognizedArg = -1, eBareDash = -2, eBareDoubleDash = -3 };
33 OptionArgElement(int defs_index, int pos, int arg_pos)
34 : opt_defs_index(defs_index), opt_pos(pos), opt_arg_pos(arg_pos) {}
41 typedef std::vector<OptionArgElement> OptionElementVector;
43 static inline bool isprint8(int ch) {
49 /// \class Options Options.h "lldb/Interpreter/Options.h"
50 /// A command line option parsing protocol class.
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.
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);
68 void BuildGetoptTable();
70 void BuildValidOptionSets();
72 uint32_t NumCommandOptions();
74 /// Get the option definitions to use when parsing Args options.
76 /// \see Args::ParseOptions (Options&)
77 /// \see man getopt_long_only
78 Option *GetLongOptions();
80 // This gets passed the short option as an integer...
81 void OptionSeen(int short_option);
83 bool VerifyOptions(CommandReturnObject &result);
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);
90 void OutputFormattedUsageText(Stream &strm,
91 const OptionDefinition &option_def,
92 uint32_t output_max_columns);
94 void GenerateOptionUsage(Stream &strm, CommandObject *cmd,
95 uint32_t screen_width);
97 bool SupportsLongOption(const char *long_option);
99 // The following two pure virtual functions must be defined by every class
100 // that inherits from this class.
102 virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() {
103 return llvm::ArrayRef<OptionDefinition>();
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);
113 /// Parse the provided arguments.
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.
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.
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);
134 llvm::Expected<Args> ParseAlias(const Args &args,
135 OptionArgVector *option_arg_vector,
136 std::string &input_line);
138 OptionElementVector ParseForCompletion(const Args &args,
139 uint32_t cursor_index);
141 Status NotifyOptionParsingFinished(ExecutionContext *execution_context);
143 /// Set the value of an option.
145 /// \param[in] option_idx
146 /// The index into the "struct option" array that was returned
147 /// by Options::GetLongOptions().
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.
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.
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;
163 /// Handles the generic bits of figuring out whether we are in an option,
164 /// and if so completing it.
166 /// \param[in,out] request
167 /// The completion request that we need to act upon.
169 /// \param[in] interpreter
170 /// The interpreter that's doing the completing.
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.
177 /// \btrue if we were in an option, \bfalse otherwise.
178 bool HandleOptionCompletion(lldb_private::CompletionRequest &request,
179 OptionElementVector &option_map,
180 CommandInterpreter &interpreter);
182 /// Handles the generic bits of figuring out whether we are in an option,
183 /// and if so completing it.
185 /// \param[in,out] request
186 /// The completion request that we need to act upon.
188 /// \param[in] interpreter
189 /// The command interpreter doing the completion.
191 HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request,
192 OptionElementVector &opt_element_vector,
193 int opt_element_index,
194 CommandInterpreter &interpreter);
197 // This is a set of options expressed as indexes into the options table for
199 typedef std::set<int> OptionSet;
200 typedef std::vector<OptionSet> OptionSetVector;
202 std::vector<Option> m_getopt_table;
203 OptionSet m_seen_options;
204 OptionSetVector m_required_options;
205 OptionSetVector m_optional_options;
207 OptionSetVector &GetRequiredOptions() {
208 BuildValidOptionSets();
209 return m_required_options;
212 OptionSetVector &GetOptionalOptions() {
213 BuildValidOptionSets();
214 return m_optional_options;
217 bool IsASubset(const OptionSet &set_a, const OptionSet &set_b);
219 size_t OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b,
222 void OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b,
223 OptionSet &union_set);
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;
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
240 OptionGroup() = default;
242 virtual ~OptionGroup() = default;
244 virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() = 0;
246 virtual Status SetOptionValue(uint32_t option_idx,
247 llvm::StringRef option_value,
248 ExecutionContext *execution_context) = 0;
250 virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;
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
260 class OptionGroupOptions : public Options {
263 : Options(), m_option_defs(), m_option_infos(), m_did_finalize(false) {}
265 ~OptionGroupOptions() override = default;
267 /// Append options from a OptionGroup class.
269 /// Append all options from \a group using the exact same option groups that
270 /// each option is defined with.
273 /// A group of options to take option values from and copy their
274 /// definitions into this class.
275 void Append(OptionGroup *group);
277 /// Append options from a OptionGroup class.
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".
284 /// A group of options to take option values from and copy their
285 /// definitions into this class.
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.
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);
301 bool DidFinalize() { return m_did_finalize; }
303 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
304 ExecutionContext *execution_context) override;
306 void OptionParsingStarting(ExecutionContext *execution_context) override;
308 Status OptionParsingFinished(ExecutionContext *execution_context) override;
310 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
311 assert(m_did_finalize);
312 return m_option_defs;
315 const OptionGroup *GetGroupWithOption(char short_opt);
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
322 typedef std::vector<OptionInfo> OptionInfos;
324 std::vector<OptionDefinition> m_option_defs;
325 OptionInfos m_option_infos;
329 } // namespace lldb_private
331 #endif // liblldb_Options_h_