/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Interpreter/Options.h
Line | Count | Source |
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 | 53 | : 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 | 761k | virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() { |
99 | 761k | return llvm::ArrayRef<OptionDefinition>(); |
100 | 761k | } |
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 | 509k | OptionSetVector &GetRequiredOptions() { |
204 | 509k | BuildValidOptionSets(); |
205 | 509k | return m_required_options; |
206 | 509k | } |
207 | | |
208 | 225k | OptionSetVector &GetOptionalOptions() { |
209 | 225k | BuildValidOptionSets(); |
210 | 225k | return m_optional_options; |
211 | 225k | } |
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 | 33.4k | 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 | 33.4k | Status error; |
230 | 33.4k | return error; |
231 | 33.4k | } |
232 | | }; |
233 | | |
234 | | class OptionGroup { |
235 | | public: |
236 | 617k | OptionGroup() = default; |
237 | | |
238 | 616k | 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 | 29.4k | 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 | 29.4k | Status error; |
252 | 29.4k | return error; |
253 | 29.4k | } |
254 | | }; |
255 | | |
256 | | class OptionGroupOptions : public Options { |
257 | | public: |
258 | 255k | OptionGroupOptions() = default; |
259 | | |
260 | 255k | ~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 | 18 | 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 | 114k | llvm::ArrayRef<OptionDefinition> GetDefinitions() override { |
321 | 114k | assert(m_did_finalize); |
322 | 114k | return m_option_defs; |
323 | 114k | } |
324 | | |
325 | | const OptionGroup *GetGroupWithOption(char short_opt); |
326 | | |
327 | | struct OptionInfo { |
328 | 2.24M | 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 |