Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:50

0001 //===-- Options.h -----------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_INTERPRETER_OPTIONS_H
0010 #define LLDB_INTERPRETER_OPTIONS_H
0011 
0012 #include <set>
0013 #include <vector>
0014 
0015 #include "lldb/Utility/Args.h"
0016 #include "lldb/Utility/CompletionRequest.h"
0017 #include "lldb/Utility/OptionDefinition.h"
0018 #include "lldb/Utility/Status.h"
0019 #include "lldb/lldb-defines.h"
0020 #include "lldb/lldb-private.h"
0021 
0022 #include "llvm/ADT/ArrayRef.h"
0023 #include "llvm/ADT/StringRef.h"
0024 
0025 namespace lldb_private {
0026 
0027 struct Option;
0028 
0029 typedef std::vector<std::tuple<std::string, int, std::string>> OptionArgVector;
0030 typedef std::shared_ptr<OptionArgVector> OptionArgVectorSP;
0031 
0032 struct OptionArgElement {
0033   enum { eUnrecognizedArg = -1, eBareDash = -2, eBareDoubleDash = -3 };
0034 
0035   OptionArgElement(int defs_index, int pos, int arg_pos)
0036       : opt_defs_index(defs_index), opt_pos(pos), opt_arg_pos(arg_pos) {}
0037 
0038   int opt_defs_index;
0039   int opt_pos;
0040   int opt_arg_pos;
0041 };
0042 
0043 typedef std::vector<OptionArgElement> OptionElementVector;
0044 
0045 /// \class Options Options.h "lldb/Interpreter/Options.h"
0046 /// A command line option parsing protocol class.
0047 ///
0048 /// Options is designed to be subclassed to contain all needed options for a
0049 /// given command. The options can be parsed by calling the Parse function.
0050 ///
0051 /// The options are specified using the format defined for the libc options
0052 /// parsing function getopt_long_only: \code
0053 ///     #include <getopt.h>
0054 ///     int getopt_long_only(int argc, char * const *argv, const char
0055 ///     *optstring, const struct option *longopts, int *longindex);
0056 /// \endcode
0057 ///
0058 class Options {
0059 public:
0060   Options();
0061 
0062   virtual ~Options();
0063 
0064   void BuildGetoptTable();
0065 
0066   void BuildValidOptionSets();
0067 
0068   uint32_t NumCommandOptions();
0069 
0070   /// Get the option definitions to use when parsing Args options.
0071   ///
0072   /// \see Args::ParseOptions (Options&)
0073   /// \see man getopt_long_only
0074   Option *GetLongOptions();
0075 
0076   // This gets passed the short option as an integer...
0077   void OptionSeen(int short_option);
0078 
0079   bool VerifyOptions(CommandReturnObject &result);
0080 
0081   // Verify that the options given are in the options table and can be used
0082   // together, but there may be some required options that are missing (used to
0083   // verify options that get folded into command aliases).
0084   bool VerifyPartialOptions(CommandReturnObject &result);
0085 
0086   void OutputFormattedUsageText(Stream &strm,
0087                                 const OptionDefinition &option_def,
0088                                 uint32_t output_max_columns);
0089 
0090   void GenerateOptionUsage(Stream &strm, CommandObject &cmd,
0091                            uint32_t screen_width);
0092 
0093   bool SupportsLongOption(const char *long_option);
0094 
0095   // The following two pure virtual functions must be defined by every class
0096   // that inherits from this class.
0097 
0098   virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() {
0099     return llvm::ArrayRef<OptionDefinition>();
0100   }
0101 
0102   // Call this prior to parsing any options. This call will call the subclass
0103   // OptionParsingStarting() and will avoid the need for all
0104   // OptionParsingStarting() function instances from having to call the
0105   // Option::OptionParsingStarting() like they did before. This was error prone
0106   // and subclasses shouldn't have to do it.
0107   void NotifyOptionParsingStarting(ExecutionContext *execution_context);
0108 
0109   /// Parse the provided arguments.
0110   ///
0111   /// The parsed options are set via calls to SetOptionValue. In case of a
0112   /// successful parse, the function returns a copy of the input arguments
0113   /// with the parsed options removed. Otherwise, it returns an error.
0114   ///
0115   /// param[in] platform_sp
0116   ///   The platform used for option validation.  This is necessary
0117   ///   because an empty execution_context is not enough to get us
0118   ///   to a reasonable platform.  If the platform isn't given,
0119   ///   we'll try to get it from the execution context.  If we can't
0120   ///   get it from the execution context, we'll skip validation.
0121   ///
0122   /// param[in] require_validation
0123   ///   When true, it will fail option parsing if validation could
0124   ///   not occur due to not having a platform.
0125   llvm::Expected<Args> Parse(const Args &args,
0126                              ExecutionContext *execution_context,
0127                              lldb::PlatformSP platform_sp,
0128                              bool require_validation);
0129 
0130   llvm::Expected<Args> ParseAlias(const Args &args,
0131                                   OptionArgVector *option_arg_vector,
0132                                   std::string &input_line);
0133 
0134   OptionElementVector ParseForCompletion(const Args &args,
0135                                          uint32_t cursor_index);
0136 
0137   Status NotifyOptionParsingFinished(ExecutionContext *execution_context);
0138 
0139   /// Set the value of an option.
0140   ///
0141   /// \param[in] option_idx
0142   ///     The index into the "struct option" array that was returned
0143   ///     by Options::GetLongOptions().
0144   ///
0145   /// \param[in] option_arg
0146   ///     The argument value for the option that the user entered, or
0147   ///     nullptr if there is no argument for the current option.
0148   ///
0149   /// \param[in] execution_context
0150   ///     The execution context to use for evaluating the option.
0151   ///     May be nullptr if the option is to be evaluated outside any
0152   ///     particular context.
0153   ///
0154   /// \see Args::ParseOptions (Options&)
0155   /// \see man getopt_long_only
0156   virtual Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
0157                                 ExecutionContext *execution_context) = 0;
0158 
0159   /// Handles the generic bits of figuring out whether we are in an option,
0160   /// and if so completing it.
0161   ///
0162   /// \param[in,out] request
0163   ///    The completion request that we need to act upon.
0164   ///
0165   /// \param[in] interpreter
0166   ///     The interpreter that's doing the completing.
0167   ///
0168   /// FIXME: This is the wrong return value, since we also need to
0169   /// make a distinction between total number of matches, and the window the
0170   /// user wants returned.
0171   ///
0172   /// \return
0173   ///     \b true if we were in an option, \b false otherwise.
0174   bool HandleOptionCompletion(lldb_private::CompletionRequest &request,
0175                               OptionElementVector &option_map,
0176                               CommandInterpreter &interpreter);
0177 
0178   /// Handles the generic bits of figuring out whether we are in an option,
0179   /// and if so completing it.
0180   ///
0181   /// \param[in,out] request
0182   ///    The completion request that we need to act upon.
0183   ///
0184   /// \param[in] interpreter
0185   ///    The command interpreter doing the completion.
0186   virtual void
0187   HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request,
0188                                  OptionElementVector &opt_element_vector,
0189                                  int opt_element_index,
0190                                  CommandInterpreter &interpreter);
0191 
0192 protected:
0193   // This is a set of options expressed as indexes into the options table for
0194   // this Option.
0195   typedef std::set<int> OptionSet;
0196   typedef std::vector<OptionSet> OptionSetVector;
0197 
0198   std::vector<Option> m_getopt_table;
0199   OptionSet m_seen_options;
0200   OptionSetVector m_required_options;
0201   OptionSetVector m_optional_options;
0202 
0203   OptionSetVector &GetRequiredOptions() {
0204     BuildValidOptionSets();
0205     return m_required_options;
0206   }
0207 
0208   OptionSetVector &GetOptionalOptions() {
0209     BuildValidOptionSets();
0210     return m_optional_options;
0211   }
0212 
0213   bool IsASubset(const OptionSet &set_a, const OptionSet &set_b);
0214 
0215   size_t OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b,
0216                         OptionSet &diffs);
0217 
0218   void OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b,
0219                        OptionSet &union_set);
0220 
0221   // Subclasses must reset their option values prior to starting a new option
0222   // parse. Each subclass must override this function and revert all option
0223   // settings to default values.
0224   virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;
0225 
0226   virtual Status OptionParsingFinished(ExecutionContext *execution_context) {
0227     // If subclasses need to know when the options are done being parsed they
0228     // can implement this function to do extra checking
0229     Status error;
0230     return error;
0231   }
0232 };
0233 
0234 class OptionGroup {
0235 public:
0236   OptionGroup() = default;
0237 
0238   virtual ~OptionGroup() = default;
0239 
0240   virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() = 0;
0241 
0242   virtual Status SetOptionValue(uint32_t option_idx,
0243                                 llvm::StringRef option_value,
0244                                 ExecutionContext *execution_context) = 0;
0245 
0246   virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;
0247 
0248   virtual Status OptionParsingFinished(ExecutionContext *execution_context) {
0249     // If subclasses need to know when the options are done being parsed they
0250     // can implement this function to do extra checking
0251     Status error;
0252     return error;
0253   }
0254 };
0255 
0256 class OptionGroupOptions : public Options {
0257 public:
0258   OptionGroupOptions() = default;
0259 
0260   ~OptionGroupOptions() override = default;
0261 
0262   /// Append options from a OptionGroup class.
0263   ///
0264   /// Append all options from \a group using the exact same option groups that
0265   /// each option is defined with.
0266   ///
0267   /// \param[in] group
0268   ///     A group of options to take option values from and copy their
0269   ///     definitions into this class.
0270   void Append(OptionGroup *group);
0271 
0272   /// Append options from a OptionGroup class.
0273   ///
0274   /// Append options from \a group that have a usage mask that has any bits in
0275   /// "src_mask" set. After the option definition is copied into the options
0276   /// definitions in this class, set the usage_mask to "dst_mask".
0277   ///
0278   /// \param[in] group
0279   ///     A group of options to take option values from and copy their
0280   ///     definitions into this class.
0281   ///
0282   /// \param[in] src_mask
0283   ///     When copying options from \a group, you might only want some of
0284   ///     the options to be appended to this group. This mask allows you
0285   ///     to control which options from \a group get added. It also allows
0286   ///     you to specify the same options from \a group multiple times
0287   ///     for different option sets.
0288   ///
0289   /// \param[in] dst_mask
0290   ///     Set the usage mask for any copied options to \a dst_mask after
0291   ///     copying the option definition.
0292   void Append(OptionGroup *group, uint32_t src_mask, uint32_t dst_mask);
0293 
0294   /// Append selected options from a OptionGroup class.
0295   ///
0296   /// Append the subset of options from \a group, where the "long_option" value
0297   /// is _not_ in \a exclude_long_options.
0298   ///
0299   /// \param[in] group
0300   ///     A group of options to take option values from and copy their
0301   ///     definitions into this class.
0302   ///
0303   /// \param[in] exclude_long_options
0304   ///     A set of long option strings which indicate which option values values
0305   ///     to limit from \a group.
0306   void Append(OptionGroup *group,
0307               llvm::ArrayRef<llvm::StringRef> exclude_long_options);
0308 
0309   void Finalize();
0310 
0311   bool DidFinalize() { return m_did_finalize; }
0312 
0313   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
0314                         ExecutionContext *execution_context) override;
0315 
0316   void OptionParsingStarting(ExecutionContext *execution_context) override;
0317 
0318   Status OptionParsingFinished(ExecutionContext *execution_context) override;
0319 
0320   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
0321     assert(m_did_finalize);
0322     return m_option_defs;
0323   }
0324 
0325   const OptionGroup *GetGroupWithOption(char short_opt);
0326 
0327   struct OptionInfo {
0328     OptionInfo(OptionGroup *g, uint32_t i) : option_group(g), option_index(i) {}
0329     OptionGroup *option_group; // The group that this option came from
0330     uint32_t option_index;     // The original option index from the OptionGroup
0331   };
0332   typedef std::vector<OptionInfo> OptionInfos;
0333 
0334   std::vector<OptionDefinition> m_option_defs;
0335   OptionInfos m_option_infos;
0336   bool m_did_finalize = false;
0337 };
0338 
0339 /// Creates an error that represents the failure to parse an command line option
0340 /// argument. This creates an error containing all information needed to show
0341 /// the developer what went wrong when parsing their command. It is recommended
0342 /// to use this instead of writing an error by hand.
0343 ///
0344 /// \param[in] option_arg
0345 ///   The argument that was attempted to be parsed.
0346 ///
0347 /// \param[in] short_option
0348 ///   The short form of the option. For example, if the flag is -f, the short
0349 ///   option is "f".
0350 ///
0351 /// \param[in] long_option
0352 ///   The long form of the option. This field is optional. If the flag is
0353 ///   --force, then the long option is "force".
0354 ///
0355 /// \param[in] additional_context
0356 ///   This is extra context that will get included in the error. This field is
0357 ///   optional.
0358 ///
0359 /// \return
0360 ///   An llvm::Error that contains a standardized format for what went wrong
0361 ///   when parsing and why.
0362 llvm::Error CreateOptionParsingError(llvm::StringRef option_arg,
0363                                      const char short_option,
0364                                      llvm::StringRef long_option = {},
0365                                      llvm::StringRef additional_context = {});
0366 
0367 static constexpr llvm::StringLiteral g_bool_parsing_error_message =
0368     "Failed to parse as boolean";
0369 static constexpr llvm::StringLiteral g_int_parsing_error_message =
0370     "Failed to parse as integer";
0371 static constexpr llvm::StringLiteral g_language_parsing_error_message =
0372     "Unknown language";
0373 
0374 } // namespace lldb_private
0375 
0376 #endif // LLDB_INTERPRETER_OPTIONS_H