Options.h 11 KB

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