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 OptionArgElementOptionArgElement35 OptionArgElement(int defs_index, int pos, int arg_pos) 36 : 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 GetDefinitions()98 virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() { 99 return llvm::ArrayRef<OptionDefinition>(); 100 } 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 GetRequiredOptions()203 OptionSetVector &GetRequiredOptions() { 204 BuildValidOptionSets(); 205 return m_required_options; 206 } 207 GetOptionalOptions()208 OptionSetVector &GetOptionalOptions() { 209 BuildValidOptionSets(); 210 return m_optional_options; 211 } 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 OptionParsingFinished(ExecutionContext * execution_context)226 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 Status error; 230 return error; 231 } 232 }; 233 234 class OptionGroup { 235 public: 236 OptionGroup() = default; 237 238 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 OptionParsingFinished(ExecutionContext * execution_context)248 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 Status error; 252 return error; 253 } 254 }; 255 256 class OptionGroupOptions : public Options { 257 public: 258 OptionGroupOptions() = default; 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 /// 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 DidFinalize()311 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 GetDefinitions()320 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 321 assert(m_did_finalize); 322 return m_option_defs; 323 } 324 325 const OptionGroup *GetGroupWithOption(char short_opt); 326 327 struct OptionInfo { OptionInfoOptionInfo328 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 /// Creates an error that represents the failure to parse an command line option 340 /// argument. This creates an error containing all information needed to show 341 /// the developer what went wrong when parsing their command. It is recommended 342 /// to use this instead of writing an error by hand. 343 /// 344 /// \param[in] option_arg 345 /// The argument that was attempted to be parsed. 346 /// 347 /// \param[in] short_option 348 /// The short form of the option. For example, if the flag is -f, the short 349 /// option is "f". 350 /// 351 /// \param[in] long_option 352 /// The long form of the option. This field is optional. If the flag is 353 /// --force, then the long option is "force". 354 /// 355 /// \param[in] additional_context 356 /// This is extra context that will get included in the error. This field is 357 /// optional. 358 /// 359 /// \return 360 /// An llvm::Error that contains a standardized format for what went wrong 361 /// when parsing and why. 362 llvm::Error CreateOptionParsingError(llvm::StringRef option_arg, 363 const char short_option, 364 llvm::StringRef long_option = {}, 365 llvm::StringRef additional_context = {}); 366 367 static constexpr llvm::StringLiteral g_bool_parsing_error_message = 368 "Failed to parse as boolean"; 369 static constexpr llvm::StringLiteral g_int_parsing_error_message = 370 "Failed to parse as integer"; 371 static constexpr llvm::StringLiteral g_language_parsing_error_message = 372 "Unknown language"; 373 374 } // namespace lldb_private 375 376 #endif // LLDB_INTERPRETER_OPTIONS_H 377