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 OptionArgElementOptionArgElement34 OptionArgElement(int defs_index, int pos, int arg_pos) 35 : 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 GetDefinitions()97 virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() { 98 return llvm::ArrayRef<OptionDefinition>(); 99 } 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 /// \btrue if we were in an option, \bfalse 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 GetRequiredOptions()202 OptionSetVector &GetRequiredOptions() { 203 BuildValidOptionSets(); 204 return m_required_options; 205 } 206 GetOptionalOptions()207 OptionSetVector &GetOptionalOptions() { 208 BuildValidOptionSets(); 209 return m_optional_options; 210 } 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 OptionParsingFinished(ExecutionContext * execution_context)225 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 Status error; 229 return error; 230 } 231 }; 232 233 class OptionGroup { 234 public: 235 OptionGroup() = default; 236 237 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 OptionParsingFinished(ExecutionContext * execution_context)247 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 Status error; 251 return error; 252 } 253 }; 254 255 class OptionGroupOptions : public Options { 256 public: OptionGroupOptions()257 OptionGroupOptions() 258 : Options(), m_option_defs(), m_option_infos(), m_did_finalize(false) {} 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 void Finalize(); 295 DidFinalize()296 bool DidFinalize() { return m_did_finalize; } 297 298 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 299 ExecutionContext *execution_context) override; 300 301 void OptionParsingStarting(ExecutionContext *execution_context) override; 302 303 Status OptionParsingFinished(ExecutionContext *execution_context) override; 304 GetDefinitions()305 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 306 assert(m_did_finalize); 307 return m_option_defs; 308 } 309 310 const OptionGroup *GetGroupWithOption(char short_opt); 311 312 struct OptionInfo { OptionInfoOptionInfo313 OptionInfo(OptionGroup *g, uint32_t i) : option_group(g), option_index(i) {} 314 OptionGroup *option_group; // The group that this option came from 315 uint32_t option_index; // The original option index from the OptionGroup 316 }; 317 typedef std::vector<OptionInfo> OptionInfos; 318 319 std::vector<OptionDefinition> m_option_defs; 320 OptionInfos m_option_infos; 321 bool m_did_finalize; 322 }; 323 324 } // namespace lldb_private 325 326 #endif // LLDB_INTERPRETER_OPTIONS_H 327