/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Interpreter/Options.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
24 | | namespace lldb_private { |
25 | | |
26 | | struct Option; |
27 | | |
28 | | typedef std::vector<std::tuple<std::string, int, std::string>> OptionArgVector; |
29 | | typedef std::shared_ptr<OptionArgVector> OptionArgVectorSP; |
30 | | |
31 | | struct OptionArgElement { |
32 | | enum { eUnrecognizedArg = -1, eBareDash = -2, eBareDoubleDash = -3 }; |
33 | | |
34 | | OptionArgElement(int defs_index, int pos, int arg_pos) |
35 | 52 | : opt_defs_index(defs_index), opt_pos(pos), opt_arg_pos(arg_pos) {} |
36 | | |
37 | | int opt_defs_index; |
38 | | int opt_pos; |
39 | | int opt_arg_pos; |
40 | | }; |
41 | | |
42 | | typedef std::vector<OptionArgElement> OptionElementVector; |
43 | | |
44 | | /// \class Options Options.h "lldb/Interpreter/Options.h" |
45 | | /// A command line option parsing protocol class. |
46 | | /// |
47 | | /// Options is designed to be subclassed to contain all needed options for a |
48 | | /// given command. The options can be parsed by calling the Parse function. |
49 | | /// |
50 | | /// The options are specified using the format defined for the libc options |
51 | | /// parsing function getopt_long_only: \code |
52 | | /// #include <getopt.h> |
53 | | /// int getopt_long_only(int argc, char * const *argv, const char |
54 | | /// *optstring, const struct option *longopts, int *longindex); |
55 | | /// \endcode |
56 | | /// |
57 | | class Options { |
58 | | public: |
59 | | Options(); |
60 | | |
61 | | virtual ~Options(); |
62 | | |
63 | | void BuildGetoptTable(); |
64 | | |
65 | | void BuildValidOptionSets(); |
66 | | |
67 | | uint32_t NumCommandOptions(); |
68 | | |
69 | | /// Get the option definitions to use when parsing Args options. |
70 | | /// |
71 | | /// \see Args::ParseOptions (Options&) |
72 | | /// \see man getopt_long_only |
73 | | Option *GetLongOptions(); |
74 | | |
75 | | // This gets passed the short option as an integer... |
76 | | void OptionSeen(int short_option); |
77 | | |
78 | | bool VerifyOptions(CommandReturnObject &result); |
79 | | |
80 | | // Verify that the options given are in the options table and can be used |
81 | | // together, but there may be some required options that are missing (used to |
82 | | // verify options that get folded into command aliases). |
83 | | bool VerifyPartialOptions(CommandReturnObject &result); |
84 | | |
85 | | void OutputFormattedUsageText(Stream &strm, |
86 | | const OptionDefinition &option_def, |
87 | | uint32_t output_max_columns); |
88 | | |
89 | | void GenerateOptionUsage(Stream &strm, CommandObject &cmd, |
90 | | uint32_t screen_width); |
91 | | |
92 | | bool SupportsLongOption(const char *long_option); |
93 | | |
94 | | // The following two pure virtual functions must be defined by every class |
95 | | // that inherits from this class. |
96 | | |
97 | 798k | virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() { |
98 | 798k | return llvm::ArrayRef<OptionDefinition>(); |
99 | 798k | } |
100 | | |
101 | | // Call this prior to parsing any options. This call will call the subclass |
102 | | // OptionParsingStarting() and will avoid the need for all |
103 | | // OptionParsingStarting() function instances from having to call the |
104 | | // Option::OptionParsingStarting() like they did before. This was error prone |
105 | | // and subclasses shouldn't have to do it. |
106 | | void NotifyOptionParsingStarting(ExecutionContext *execution_context); |
107 | | |
108 | | /// Parse the provided arguments. |
109 | | /// |
110 | | /// The parsed options are set via calls to SetOptionValue. In case of a |
111 | | /// successful parse, the function returns a copy of the input arguments |
112 | | /// with the parsed options removed. Otherwise, it returns an error. |
113 | | /// |
114 | | /// param[in] platform_sp |
115 | | /// The platform used for option validation. This is necessary |
116 | | /// because an empty execution_context is not enough to get us |
117 | | /// to a reasonable platform. If the platform isn't given, |
118 | | /// we'll try to get it from the execution context. If we can't |
119 | | /// get it from the execution context, we'll skip validation. |
120 | | /// |
121 | | /// param[in] require_validation |
122 | | /// When true, it will fail option parsing if validation could |
123 | | /// not occur due to not having a platform. |
124 | | llvm::Expected<Args> Parse(const Args &args, |
125 | | ExecutionContext *execution_context, |
126 | | lldb::PlatformSP platform_sp, |
127 | | bool require_validation); |
128 | | |
129 | | llvm::Expected<Args> ParseAlias(const Args &args, |
130 | | OptionArgVector *option_arg_vector, |
131 | | std::string &input_line); |
132 | | |
133 | | OptionElementVector ParseForCompletion(const Args &args, |
134 | | uint32_t cursor_index); |
135 | | |
136 | | Status NotifyOptionParsingFinished(ExecutionContext *execution_context); |
137 | | |
138 | | /// Set the value of an option. |
139 | | /// |
140 | | /// \param[in] option_idx |
141 | | /// The index into the "struct option" array that was returned |
142 | | /// by Options::GetLongOptions(). |
143 | | /// |
144 | | /// \param[in] option_arg |
145 | | /// The argument value for the option that the user entered, or |
146 | | /// nullptr if there is no argument for the current option. |
147 | | /// |
148 | | /// \param[in] execution_context |
149 | | /// The execution context to use for evaluating the option. |
150 | | /// May be nullptr if the option is to be evaluated outside any |
151 | | /// particular context. |
152 | | /// |
153 | | /// \see Args::ParseOptions (Options&) |
154 | | /// \see man getopt_long_only |
155 | | virtual Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, |
156 | | ExecutionContext *execution_context) = 0; |
157 | | |
158 | | /// Handles the generic bits of figuring out whether we are in an option, |
159 | | /// and if so completing it. |
160 | | /// |
161 | | /// \param[in,out] request |
162 | | /// The completion request that we need to act upon. |
163 | | /// |
164 | | /// \param[in] interpreter |
165 | | /// The interpreter that's doing the completing. |
166 | | /// |
167 | | /// FIXME: This is the wrong return value, since we also need to |
168 | | /// make a distinction between total number of matches, and the window the |
169 | | /// user wants returned. |
170 | | /// |
171 | | /// \return |
172 | | /// \b true if we were in an option, \b false otherwise. |
173 | | bool HandleOptionCompletion(lldb_private::CompletionRequest &request, |
174 | | OptionElementVector &option_map, |
175 | | CommandInterpreter &interpreter); |
176 | | |
177 | | /// Handles the generic bits of figuring out whether we are in an option, |
178 | | /// and if so completing it. |
179 | | /// |
180 | | /// \param[in,out] request |
181 | | /// The completion request that we need to act upon. |
182 | | /// |
183 | | /// \param[in] interpreter |
184 | | /// The command interpreter doing the completion. |
185 | | virtual void |
186 | | HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request, |
187 | | OptionElementVector &opt_element_vector, |
188 | | int opt_element_index, |
189 | | CommandInterpreter &interpreter); |
190 | | |
191 | | protected: |
192 | | // This is a set of options expressed as indexes into the options table for |
193 | | // this Option. |
194 | | typedef std::set<int> OptionSet; |
195 | | typedef std::vector<OptionSet> OptionSetVector; |
196 | | |
197 | | std::vector<Option> m_getopt_table; |
198 | | OptionSet m_seen_options; |
199 | | OptionSetVector m_required_options; |
200 | | OptionSetVector m_optional_options; |
201 | | |
202 | 545k | OptionSetVector &GetRequiredOptions() { |
203 | 545k | BuildValidOptionSets(); |
204 | 545k | return m_required_options; |
205 | 545k | } |
206 | | |
207 | 239k | OptionSetVector &GetOptionalOptions() { |
208 | 239k | BuildValidOptionSets(); |
209 | 239k | return m_optional_options; |
210 | 239k | } |
211 | | |
212 | | bool IsASubset(const OptionSet &set_a, const OptionSet &set_b); |
213 | | |
214 | | size_t OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b, |
215 | | OptionSet &diffs); |
216 | | |
217 | | void OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b, |
218 | | OptionSet &union_set); |
219 | | |
220 | | // Subclasses must reset their option values prior to starting a new option |
221 | | // parse. Each subclass must override this function and revert all option |
222 | | // settings to default values. |
223 | | virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0; |
224 | | |
225 | 40.4k | virtual Status OptionParsingFinished(ExecutionContext *execution_context) { |
226 | | // If subclasses need to know when the options are done being parsed they |
227 | | // can implement this function to do extra checking |
228 | 40.4k | Status error; |
229 | 40.4k | return error; |
230 | 40.4k | } |
231 | | }; |
232 | | |
233 | | class OptionGroup { |
234 | | public: |
235 | 561k | OptionGroup() = default; |
236 | | |
237 | 560k | virtual ~OptionGroup() = default; |
238 | | |
239 | | virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() = 0; |
240 | | |
241 | | virtual Status SetOptionValue(uint32_t option_idx, |
242 | | llvm::StringRef option_value, |
243 | | ExecutionContext *execution_context) = 0; |
244 | | |
245 | | virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0; |
246 | | |
247 | 39.3k | virtual Status OptionParsingFinished(ExecutionContext *execution_context) { |
248 | | // If subclasses need to know when the options are done being parsed they |
249 | | // can implement this function to do extra checking |
250 | 39.3k | Status error; |
251 | 39.3k | return error; |
252 | 39.3k | } |
253 | | }; |
254 | | |
255 | | class OptionGroupOptions : public Options { |
256 | | public: |
257 | 243k | OptionGroupOptions() = default; |
258 | | |
259 | 243k | ~OptionGroupOptions() override = default; |
260 | | |
261 | | /// Append options from a OptionGroup class. |
262 | | /// |
263 | | /// Append all options from \a group using the exact same option groups that |
264 | | /// each option is defined with. |
265 | | /// |
266 | | /// \param[in] group |
267 | | /// A group of options to take option values from and copy their |
268 | | /// definitions into this class. |
269 | | void Append(OptionGroup *group); |
270 | | |
271 | | /// Append options from a OptionGroup class. |
272 | | /// |
273 | | /// Append options from \a group that have a usage mask that has any bits in |
274 | | /// "src_mask" set. After the option definition is copied into the options |
275 | | /// definitions in this class, set the usage_mask to "dst_mask". |
276 | | /// |
277 | | /// \param[in] group |
278 | | /// A group of options to take option values from and copy their |
279 | | /// definitions into this class. |
280 | | /// |
281 | | /// \param[in] src_mask |
282 | | /// When copying options from \a group, you might only want some of |
283 | | /// the options to be appended to this group. This mask allows you |
284 | | /// to control which options from \a group get added. It also allows |
285 | | /// you to specify the same options from \a group multiple times |
286 | | /// for different option sets. |
287 | | /// |
288 | | /// \param[in] dst_mask |
289 | | /// Set the usage mask for any copied options to \a dst_mask after |
290 | | /// copying the option definition. |
291 | | void Append(OptionGroup *group, uint32_t src_mask, uint32_t dst_mask); |
292 | | |
293 | | void Finalize(); |
294 | | |
295 | 18 | bool DidFinalize() { return m_did_finalize; } |
296 | | |
297 | | Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, |
298 | | ExecutionContext *execution_context) override; |
299 | | |
300 | | void OptionParsingStarting(ExecutionContext *execution_context) override; |
301 | | |
302 | | Status OptionParsingFinished(ExecutionContext *execution_context) override; |
303 | | |
304 | 98.9k | llvm::ArrayRef<OptionDefinition> GetDefinitions() override { |
305 | 98.9k | assert(m_did_finalize); |
306 | 0 | return m_option_defs; |
307 | 98.9k | } |
308 | | |
309 | | const OptionGroup *GetGroupWithOption(char short_opt); |
310 | | |
311 | | struct OptionInfo { |
312 | 1.99M | OptionInfo(OptionGroup *g, uint32_t i) : option_group(g), option_index(i) {} |
313 | | OptionGroup *option_group; // The group that this option came from |
314 | | uint32_t option_index; // The original option index from the OptionGroup |
315 | | }; |
316 | | typedef std::vector<OptionInfo> OptionInfos; |
317 | | |
318 | | std::vector<OptionDefinition> m_option_defs; |
319 | | OptionInfos m_option_infos; |
320 | | bool m_did_finalize = false; |
321 | | }; |
322 | | |
323 | | } // namespace lldb_private |
324 | | |
325 | | #endif // LLDB_INTERPRETER_OPTIONS_H |