command_line.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_COMMON_COMMAND_LINE_H_
  5. #define CARBON_COMMON_COMMAND_LINE_H_
  6. #include <initializer_list>
  7. #include <memory>
  8. #include <tuple>
  9. #include <type_traits>
  10. #include <utility>
  11. #include "common/check.h"
  12. #include "common/ostream.h"
  13. #include "llvm/ADT/ArrayRef.h"
  14. #include "llvm/ADT/DenseMap.h"
  15. #include "llvm/ADT/DenseSet.h"
  16. #include "llvm/ADT/PointerIntPair.h"
  17. #include "llvm/ADT/STLForwardCompat.h"
  18. #include "llvm/ADT/Sequence.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/ADT/StringExtras.h"
  21. #include "llvm/ADT/StringRef.h"
  22. #include "llvm/Support/Allocator.h"
  23. // # Command-line argument parsing library.
  24. //
  25. // This is a collection of tools to describe both simple and reasonably complex
  26. // command line interfaces, and parse arguments based on those descriptions. It
  27. // optimizes for command line tools that will parse arguments exactly once per
  28. // execution, and specifically tools that make heavy use of subcommand-style
  29. // command line interfaces.
  30. //
  31. // ## Terminology used by this library
  32. //
  33. // _Argument_ or _arg_: One of the parsed components of the command line.
  34. //
  35. // _Option_: A _named_ argument starting with `--` to configure some aspect of
  36. // the tool. These often have both long spellings that start with `--` and
  37. // short, single character spellings that start with `-` and can be bundled with
  38. // other single character options.
  39. //
  40. // _Flag_: A boolean or binary option. These can only be enabled or disabled.
  41. //
  42. // _Positional argument_: An argument that is not named but is identified based
  43. // on the order in which it is encountered in the command line, with options
  44. // removed. Only a leaf command can contain positional arguments.
  45. //
  46. // _Value_: The value parameter provided to an argument. For options, this is
  47. // provided after an `=` and the option name. For positional arguments, the
  48. // value is the only thing provided. The string of the value is parsed according
  49. // to the kind of argument with fairly simple rules. See the argument builders
  50. // for more details.
  51. //
  52. // _Command_: The container of options, subcommands, and positional arguments to
  53. // parse and an action to take when successful.
  54. //
  55. // _Leaf command_: A command that doesn't contain subcommands. This is the only
  56. // kind of command that can contain positional arguments.
  57. //
  58. // _Subcommand_: A command nested within another command and identified by a
  59. // specific name that ends the parsing of arguments based on the parent and
  60. // switches to parse based on the specific subcommand's options and positional
  61. // arguments. A command with subcommands cannot parse positional arguments.
  62. //
  63. // _Action_: An open-ended callback, typically reflecting a specific subcommand
  64. // being parsed. Can either directly perform the operation or simply mark which
  65. // operation was selected.
  66. //
  67. // _Meta action_: An action fully handled by argument parsing such as displaying
  68. // help, version information, or completion.
  69. //
  70. // Example command to illustrate the different components:
  71. //
  72. // git --no-pager clone --shared --filter=blob:none my-repo my-directory
  73. //
  74. // This command breaks down as:
  75. // - `git`: The top-level command.
  76. // - `--no-pager`: A negated flag on the top-level command (`git`).
  77. // - `clone`: A subcommand.
  78. // - `--shared`: A positive flag for the subcommand (`clone`).
  79. // - `--filter=blob:none`: An option named `filter` with a value `blob:none`.
  80. // - `my-repo`: The first positional argument to the subcommand.
  81. // - `my-directory`: the second positional argument to the subcommand.
  82. //
  83. // **Note:** while the example uses a `git` command to be relatively familiar
  84. // and well documented, this library does not support the same flag syntaxes as
  85. // `git` or use anything similar for its subcommand dispatch. This example is
  86. // just to help clarify the terminology used, and carefully chosen to only use a
  87. // syntax that overlaps with this library's parsed syntax.
  88. //
  89. // ## Options and flags
  90. //
  91. // The option syntax and behavior supported by this library is designed to be
  92. // strict and relatively simple while still supporting a wide range of expected
  93. // use cases:
  94. //
  95. // - All options must have a unique long name that is accessed with a `--`
  96. // prefix. The name must consist of characters in the set [-a-zA-Z0-9], and it
  97. // must not start with a `-` or `no-`.
  98. //
  99. // - Values are always attached using an `=` after the name. Only a few simple
  100. // value formats are supported:
  101. // - Arbitrary strings
  102. // - Integers as parsed by `llvm::StringRef` and whose value fits in an
  103. // `int`.
  104. // - One of a fixed set of strings
  105. //
  106. // - Options may be parsed multiple times, and the behavior can be configured:
  107. // - Each time, they can set a new value, overwriting any previous.
  108. // - They can append the value to a container.
  109. // - TODO: They can increment a count.
  110. //
  111. // - Options may have a default value that will be synthesized even if they do
  112. // not occur in the parsed command line.
  113. //
  114. // - Flags (boolean options) have some special rules.
  115. // - They may be spelled normally, and default to setting that flag to `true`.
  116. // - They may also accept a value of either exactly `true` or `false` and that
  117. // is the value.
  118. // - They may be spelled with a `no-` prefix, such as `--no-verbose`, and that
  119. // is exactly equivalent to `--verbose=false`.
  120. // - For flags with a default `true` value, they are rendered in help using
  121. // the `no-` prefix.
  122. //
  123. // - Options may additionally have a short name of a single character [a-zA-Z].
  124. // - There is no distinction between the behavior of long and short names.
  125. // - The short name can only specify the positive or `true` value for flags.
  126. // There is no negative form of short names.
  127. // - Short names are parsed after a single `-`, such as `-v`.
  128. // - Any number of short names for boolean flags or options with default
  129. // values may be grouped after `-`, such as `-xyz`: this is three options,
  130. // `x`, `y`, and `z`.
  131. // - Short options may include a value after an `=`, but not when grouped with
  132. // other short options.
  133. //
  134. // - Options are parsed from any argument until either a subcommand switches to
  135. // that subcommand's options or a `--` argument ends all option parsing to
  136. // allow arguments that would be ambiguous with the option syntax.
  137. //
  138. // ## Subcommands
  139. //
  140. // Subcommands can be nested to any depth, and each subcommand gets its own
  141. // option space.
  142. //
  143. // ## Positional arguments
  144. //
  145. // Leaf commands (and subcommands) can accept positional arguments. These work
  146. // similar to options but consist *only* of the value. They have names, but the
  147. // name is only used in documentation and error messages. Except for the special
  148. // case of the exact argument `-`, positional argument values cannot start with
  149. // a `-` character until after option parsing is ended with a `--` argument.
  150. //
  151. // Singular positional arguments store the single value in that position.
  152. // Appending positional arguments append all of the values in sequence.
  153. //
  154. // Multiple positional arguments to a single command are parsed in sequence. For
  155. // appending positional arguments, the sequence of values appended is ended with
  156. // a `--` argument. For example, a command that takes two sequences of
  157. // positional arguments might look like:
  158. //
  159. // my-diff-tool a.txt b.txt c.txt -- new-a.txt new-b.txt new-c.txt
  160. //
  161. // The `--` used in this way *both* ends option parsing and the positional
  162. // argument sequence. Note that if there are no positional arguments prior to
  163. // the first `--`, then it will just end option parsing. To pass an empty
  164. // sequence of positional arguments two `--` arguments would be required. Once
  165. // option parsing is ended, even a single positional argument can be skipped
  166. // using a `--` argument without a positional argument.
  167. //
  168. // ## Help text blocks and rendering
  169. //
  170. // At many points in this library, a block of text is specified as a string.
  171. // These should be written using multi-line raw string literals that start on
  172. // their own line such as:
  173. //
  174. // ```cpp
  175. // ...
  176. // .help = R"""(
  177. // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
  178. // tempor incididunt ut labore et dolore magna aliqua.
  179. // )""",
  180. // ```
  181. //
  182. // The code using these blocks will remove leading and trailing newlines. TODO:
  183. // It should also reflow all of the text in a way that tries to be roughly
  184. // similar to how Markdown would be reflowed when rendered:
  185. //
  186. // - Blank lines will be preserved.
  187. // - (TODO) A best effort to detect lists and other common Markdown constructs
  188. // and preserve the newlines between those.
  189. // - (TODO) Fenced regions will be preserved exactly.
  190. //
  191. // The remaining blocks will have all newlines removed when there is no column
  192. // width information on the output stream, or will be re-flowed to the output
  193. // stream's column width when available.
  194. //
  195. // ## The `Args` class
  196. //
  197. // The `Args` class is not a meaningful type, it serves two purposes: to give a
  198. // structured name prefix to the inner types, and to allow marking many
  199. // components `private` and using `friend` to grant access to implementation
  200. // details.
  201. //
  202. // ## Roadmap / TODOs / planned future work
  203. //
  204. // - Detect column width when the stream is a terminal and re-flow text.
  205. // - Implement short help display mode (and enable that by default).
  206. // - Add help text to one-of values and render it when present.
  207. // - Add formatting when the stream supports it (colors, bold, etc).
  208. // - Improve error messages when parsing fails.
  209. // - Reliably display the most appropriate usage string.
  210. // - Suggest typo corrections?
  211. // - Print snippet or otherwise render the failure better?
  212. // - Add support for responding to shell autocomplete queries.
  213. // - Finish adding support for setting and printing version information.
  214. // - Add short option counting support (`-vvv` -> `--verbose=3`).
  215. //
  216. namespace Carbon::CommandLine {
  217. // Forward declare some implementation detail classes and classes that are
  218. // friended.
  219. struct Arg;
  220. struct Command;
  221. class MetaPrinter;
  222. class Parser;
  223. class CommandBuilder;
  224. // The result of parsing arguments can be a parse error, a successfully parsed
  225. // command line, or a meta-success due to triggering a meta-action during the
  226. // parse such as rendering help text.
  227. enum class ParseResult {
  228. // Signifies an error parsing arguments. It will have been diagnosed using
  229. // the streams provided to the parser, and no useful parsed arguments are
  230. // available.
  231. Error,
  232. // Signifies that program arguments were successfully parsed and can be
  233. // used.
  234. Success,
  235. // Signifies a successful meta operation such as displaying help text
  236. // was performed. No parsed arguments are available, and the side-effects
  237. // have been directly provided via the streams provided to the parser.
  238. MetaSuccess,
  239. };
  240. auto operator<<(llvm::raw_ostream& output, ParseResult result)
  241. -> llvm::raw_ostream&;
  242. // Actions are stored in data structures so we use an owning closure to model
  243. // them.
  244. using ActionT = std::function<void()>;
  245. // The core argument info used to render help and other descriptive
  246. // information. This is used for both options and positional arguments.
  247. // Commands use an extended version below.
  248. struct ArgInfo {
  249. // The name of the argument. For options, this is the long name parsed after
  250. // `--`. Option names must also be unique. Conventionally, these are spelled
  251. // in lower case with a single dash separating words as that tends to be
  252. // especially easy to type and reasonably easy to read.
  253. //
  254. // For positional arguments this is only used for help text, and is often
  255. // spelled with `ALL-CAPS` to make it clear that it is a placeholder name
  256. // and does not appear in the actual command line.
  257. llvm::StringRef name;
  258. // Optional short name for options. This must consist of a single character
  259. // in the set [a-zA-Z].
  260. llvm::StringRef short_name = "";
  261. // For options, it is sometimes useful to render a distinct value
  262. // placeholder name to help clarify what the value should contain. These are
  263. // often in `ALL-CAPS` to make it clear they are placeholders. For example,
  264. // an `output` option might set this to `FILE` so it renders as
  265. // `--output=FILE`.
  266. llvm::StringRef value_name = "";
  267. // A long-form help string that will be rendered for this argument in
  268. // command help strings. It supports multiple lines and is rendered as a
  269. // text block described in the `Args` top-level comment.
  270. llvm::StringRef help = "";
  271. // A short help string for the argument. This should be as short as
  272. // possible, and always fit easily on a single line. Ideally, it can fit in
  273. // a narrow column of a single line and is in the range of 40 columns wide.
  274. //
  275. // If not provided, the first paragraph (up to a blank line) from `help`
  276. // will be used.
  277. llvm::StringRef help_short = "";
  278. };
  279. // The kinds of arguments that can be parsed.
  280. enum class ArgKind {
  281. Invalid,
  282. Flag,
  283. Integer,
  284. String,
  285. OneOf,
  286. MetaActionOnly,
  287. };
  288. auto operator<<(llvm::raw_ostream& output, ArgKind kind) -> llvm::raw_ostream&;
  289. // A builder used to configure an argument for parsing.
  290. class ArgBuilder {
  291. public:
  292. // When marked as required, if an argument is not provided explicitly in the
  293. // command line the parse will produce an error.
  294. void Required(bool is_required);
  295. // An argument can be hidden from the help output.
  296. void HelpHidden(bool is_help_hidden);
  297. // Sets a meta-action to run when this argument is parsed. This is used to
  298. // set up arguments like `--help` or `--version` that can be entirely
  299. // handled during parsing and rather than produce parsed information about
  300. // the command line, override that for some custom behavior.
  301. template <typename T>
  302. void MetaAction(T action);
  303. protected:
  304. friend CommandBuilder;
  305. explicit ArgBuilder(Arg& arg);
  306. Arg& arg_;
  307. };
  308. // Customized argument builder when the value is a boolean flag.
  309. class FlagBuilder : public ArgBuilder {
  310. public:
  311. // Flags can be defaulted to true. However, flags always have *some*
  312. // default, this merely customizes which value is default. If uncustomized,
  313. // the default of a flag is false.
  314. void Default(bool flag_value);
  315. // Configures the argument to store a parsed value in the provided storage.
  316. //
  317. // This must be called on the builder.
  318. void Set(bool* flag);
  319. private:
  320. using ArgBuilder::ArgBuilder;
  321. };
  322. // Customized argument builder when the value is an integer.
  323. class IntegerArgBuilder : public ArgBuilder {
  324. public:
  325. // Sets a default for the argument with the provided value. There is no
  326. // default for integer arguments unless this is called.
  327. //
  328. // For arguments that are `Set` below, this value will be stored even if the
  329. // argument is never explicitly provided. For arguments that are `Append`ed
  330. // below, this value will be used whenever the argument occurs without an
  331. // explicit value, but unless the argument is parsed nothing will be
  332. // appended.
  333. void Default(int integer_value);
  334. // Configures the argument to store a parsed value in the provided storage.
  335. // Each time the argument is parsed, it will write a new value to this
  336. // storage.
  337. //
  338. // Exactly one of this method or `Append` below must be configured for the
  339. // argument.
  340. void Set(int* integer);
  341. // Configures the argument to append a parsed value to the provided
  342. // container. Each time the argument is parsed, a new value will be
  343. // appended.
  344. //
  345. // Exactly one of this method or `Set` above must be configured for the
  346. // argument.
  347. void Append(llvm::SmallVectorImpl<int>* sequence);
  348. private:
  349. using ArgBuilder::ArgBuilder;
  350. };
  351. // Customized argument builder when the value is a string.
  352. class StringArgBuilder : public ArgBuilder {
  353. public:
  354. // Sets a default for the argument with the provided value. There is no
  355. // default for string arguments unless this is called.
  356. //
  357. // For arguments that are `Set` below, this value will be stored even if the
  358. // argument is never explicitly provided. For arguments that are `Append`ed
  359. // below, this value will be used whenever the argument occurs without an
  360. // explicit value, but unless the argument is parsed nothing will be
  361. // appended.
  362. void Default(llvm::StringRef string_value);
  363. // Configures the argument to store a parsed value in the provided storage.
  364. // Each time the argument is parsed, it will write a new value to this
  365. // storage.
  366. //
  367. // Exactly one of this method or `Append` below must be configured for the
  368. // argument.
  369. void Set(llvm::StringRef* string);
  370. // Configures the argument to append a parsed value to the provided
  371. // container. Each time the argument is parsed, a new value will be
  372. // appended.
  373. //
  374. // Exactly one of this method or `Set` above must be configured for the
  375. // argument.
  376. void Append(llvm::SmallVectorImpl<llvm::StringRef>* sequence);
  377. private:
  378. using ArgBuilder::ArgBuilder;
  379. };
  380. // Customized argument builder when the value is required to be one of a fixed
  381. // set of possible strings, and each one maps to a specific value of some
  382. // type, often an enumerator.
  383. class OneOfArgBuilder : public ArgBuilder {
  384. public:
  385. // A tiny helper / builder type for describing one of the possible values
  386. // that a particular argument accepts.
  387. //
  388. // Beyond carrying the string, type, and value for this candidate, it also
  389. // allows marking the candidate as the default.
  390. template <typename T>
  391. class OneOfValueT {
  392. public:
  393. // Configure whether a candidate is the default. If not called, it is not
  394. // the default. This can only be used when setting, not when appending.
  395. auto Default(bool is_default) && -> OneOfValueT;
  396. private:
  397. friend OneOfArgBuilder;
  398. explicit OneOfValueT(llvm::StringRef str, T value);
  399. llvm::StringRef str;
  400. T value;
  401. bool is_default = false;
  402. };
  403. // A helper function to create an object that models one of the candidate
  404. // values for this argument. It takes the string used to select this value
  405. // on the command line, deduces the type of the value, and accepts the value
  406. // itself that should be used when this candidate is parsed.
  407. template <typename T>
  408. static auto OneOfValue(llvm::StringRef string, T value) -> OneOfValueT<T>;
  409. // Configures the argument to store a parsed value in the provided storage.
  410. // Each time the argument is parsed, it will write a new value to this
  411. // storage.
  412. //
  413. // Exactly one of this method or `AppendOneOf` below must be configured for
  414. // the argument.
  415. //
  416. // For one-of arguments, this method also provides an array of possible
  417. // values that may be used:
  418. //
  419. // ```cpp
  420. // arg_b.SetOneOf(
  421. // {
  422. // arg_b.OneOfValue("x", 1),
  423. // arg_b.OneOfValue("y", 2),
  424. // arg_b.OneOfValue("z", 3).Default(true),
  425. // },
  426. // &value);
  427. // ```
  428. //
  429. // The only value strings that will be parsed are those described in the
  430. // array, and the value stored in the storage for a particular parsed value
  431. // string is the one associated with it. There must be a single homogeneous
  432. // type for the all of the candidate values and that type must be storable
  433. // into the result storage pointee type. At most one of the array can also
  434. // be marked as a default value, which will make specifying a value
  435. // optional, and also will cause that value to be stored into the result
  436. // even if the argument is not parsed explicitly.
  437. template <typename T, typename U, size_t N>
  438. void SetOneOf(const OneOfValueT<U> (&values)[N], T* result);
  439. // Configures the argument to append a parsed value to the provided
  440. // container. Each time the argument is parsed, a new value will be
  441. // appended.
  442. //
  443. // Exactly one of this method or `SetOneOf` above must be configured for the
  444. // argument.
  445. //
  446. // Similar to `SetOneOf`, this must also describe the candidate value
  447. // strings that can be parsed and the consequent values that are used for
  448. // those strings:
  449. //
  450. // ```cpp
  451. // arg_b.AppendOneOf(
  452. // {
  453. // arg_b.OneOfValue("x", 1),
  454. // arg_b.OneOfValue("y", 2),
  455. // arg_b.OneOfValue("z", 3),
  456. // },
  457. // &values);
  458. // ```
  459. //
  460. // Instead of storing, these values are appended.
  461. //
  462. // However, appending one-of arguments cannot use a default. The values must
  463. // always be explicitly parsed.
  464. template <typename T, typename U, size_t N>
  465. void AppendOneOf(const OneOfValueT<U> (&values)[N],
  466. llvm::SmallVectorImpl<T>* sequence);
  467. private:
  468. using ArgBuilder::ArgBuilder;
  469. template <typename U, size_t N, typename MatchT, size_t... Indices>
  470. void OneOfImpl(const OneOfValueT<U> (&input_values)[N], MatchT match,
  471. std::index_sequence<Indices...> /*indices*/);
  472. };
  473. // The extended info for a command, including for a subcommand.
  474. //
  475. // This provides the primary descriptive information for commands used by help
  476. // and other diagnostic messages. For subcommands, it also provides the name
  477. // used to access the subcommand.
  478. struct CommandInfo {
  479. // The name of the command. For subcommands, this is also the argument
  480. // spelling that accesses this subcommand. It must consist of characters in
  481. // the set [-a-zA-Z0-9], and must not start with a `-`.
  482. llvm::StringRef name;
  483. // An optional version string that will be rendered as part of version meta
  484. // action by the library. While this library does not impose a machine
  485. // parsable structure, users will expect this to be extractable and parsable
  486. // in practice.
  487. //
  488. // Subcommands with an empty version will inherit the first non-empty parent
  489. // version.
  490. //
  491. // Whether a (possibly inherited) version string is non-empty determines
  492. // whether this library provides the version-printing meta actions via a
  493. // `--version` flag or, if there are subcommands, a `version` subcommand.
  494. llvm::StringRef version = "";
  495. // Optional build information to include when printing the version.
  496. llvm::StringRef build_info = "";
  497. // An optional long-form help string for the command.
  498. //
  499. // When accessing a command's dedicated help output, this will form the main
  500. // prose output at the beginning of the help message. When listing
  501. // subcommands, the subcommand's `help` string will be used to describe it
  502. // in the list.
  503. //
  504. // The help meta actions are available regardless of whether this is
  505. // provided in order to mechanically describe other aspects of the command.
  506. //
  507. // This field supports multiple lines and uses the text block handling
  508. // described in the top-level `Args` comment.
  509. llvm::StringRef help = "";
  510. // An optional short help string for the command.
  511. //
  512. // This should be very short, at most one line and ideally fitting within a
  513. // narrow column of a line. If left blank, the first paragraph of text (up
  514. // to the first blank line) in the `help` string will be used.
  515. llvm::StringRef help_short = "";
  516. // An optional custom block of text to describe the usage of the command.
  517. //
  518. // The usage should just be a series of lines with possible invocations of
  519. // the command summarized as briefly as possible. Ideally, each variation on
  520. // a single line. The goal is to show the *structure* of different command
  521. // invocations, not to be comprehensive.
  522. //
  523. // When omitted, the library will generate these based on the parsing logic.
  524. // The generated usage is expected to be suitable for the vast majority of
  525. // users, but can be customized in cases where necessary.
  526. llvm::StringRef usage = "";
  527. // An optional epilogue multi-line block of text appended to the help display
  528. // for this command. It is only used for this command's dedicated help, but
  529. // can contain extra, custom guidance that is especially useful to have at
  530. // the very end of the output.
  531. llvm::StringRef help_epilogue = "";
  532. };
  533. // Commands are classified based on the action they result in when run.
  534. //
  535. // Commands that require a subcommand have no action and are just a means to
  536. // reach the subcommand actions.
  537. //
  538. // Commands with _meta_ actions are also a separate kind from those with
  539. // normal actions.
  540. enum class CommandKind {
  541. Invalid,
  542. RequiresSubcommand,
  543. Action,
  544. MetaAction,
  545. };
  546. auto operator<<(llvm::raw_ostream& output, CommandKind kind)
  547. -> llvm::raw_ostream&;
  548. // Builder used to configure a command to parse.
  549. //
  550. // An instance of this is used to configure the top-level command, and a fresh
  551. // instance is provided for configuring each subcommand as well.
  552. class CommandBuilder {
  553. public:
  554. using Kind = CommandKind;
  555. void AddFlag(const ArgInfo& info,
  556. llvm::function_ref<void(FlagBuilder&)> build);
  557. void AddIntegerOption(const ArgInfo& info,
  558. llvm::function_ref<void(IntegerArgBuilder&)> build);
  559. void AddStringOption(const ArgInfo& info,
  560. llvm::function_ref<void(StringArgBuilder&)> build);
  561. void AddOneOfOption(const ArgInfo& info,
  562. llvm::function_ref<void(OneOfArgBuilder&)> build);
  563. void AddMetaActionOption(const ArgInfo& info,
  564. llvm::function_ref<void(ArgBuilder&)> build);
  565. void AddIntegerPositionalArg(
  566. const ArgInfo& info, llvm::function_ref<void(IntegerArgBuilder&)> build);
  567. void AddStringPositionalArg(
  568. const ArgInfo& info, llvm::function_ref<void(StringArgBuilder&)> build);
  569. void AddOneOfPositionalArg(const ArgInfo& info,
  570. llvm::function_ref<void(OneOfArgBuilder&)> build);
  571. void AddSubcommand(const CommandInfo& info,
  572. llvm::function_ref<void(CommandBuilder&)> build);
  573. // Subcommands can be hidden from the help listing of their parents with
  574. // this setting. Hiding a subcommand doesn't disable its own help, it just
  575. // removes it from the listing.
  576. void HelpHidden(bool is_help_hidden);
  577. // Exactly one of these three should be called to select and configure the
  578. // kind of the built command.
  579. void RequiresSubcommand();
  580. void Do(ActionT action);
  581. void Meta(ActionT meta_action);
  582. private:
  583. friend Parser;
  584. explicit CommandBuilder(Command& command, MetaPrinter& meta_printer);
  585. auto AddArgImpl(const ArgInfo& info, ArgKind kind) -> Arg&;
  586. void AddPositionalArgImpl(const ArgInfo& info, ArgKind kind,
  587. llvm::function_ref<void(Arg&)> build);
  588. void Finalize();
  589. Command& command_;
  590. MetaPrinter& meta_printer_;
  591. llvm::SmallDenseSet<llvm::StringRef> arg_names_;
  592. llvm::SmallDenseSet<llvm::StringRef> subcommand_names_;
  593. };
  594. // Builds a description of a command and then parses the provided arguments
  595. // for that command.
  596. //
  597. // This is the main entry point to both build up the description of the
  598. // command whose arguments are being parsed and to do the parsing. Everything
  599. // is done in a single invocation as the common case is to build a command
  600. // description, parse the arguments once, and then run with that
  601. // configuration.
  602. //
  603. // The `out` stream is treated like `stdout` would be for a Unix-style command
  604. // line tool, and `errors` like `stderr`: any errors or diagnostic information
  605. // are printed to `errors`, but meta-actions like printing a command's help go
  606. // to `out`.
  607. auto Parse(llvm::ArrayRef<llvm::StringRef> unparsed_args,
  608. llvm::raw_ostream& out, llvm::raw_ostream& errors,
  609. const CommandInfo& command_info,
  610. llvm::function_ref<void(CommandBuilder&)> build) -> ParseResult;
  611. // Implementation details only below.
  612. // The internal representation of a parsable argument description.
  613. struct Arg {
  614. using Kind = ArgKind;
  615. using ValueActionT =
  616. std::function<bool(const Arg& arg, llvm::StringRef value_string)>;
  617. using DefaultActionT = std::function<void(const Arg& arg)>;
  618. explicit Arg(const ArgInfo& info);
  619. ~Arg();
  620. ArgInfo info;
  621. Kind kind = Kind::Invalid;
  622. bool has_default = false;
  623. bool is_required = false;
  624. bool is_append = false;
  625. bool is_help_hidden = false;
  626. // Meta action storage, only populated if this argument causes a meta action.
  627. ActionT meta_action;
  628. // Storage options depending on the kind.
  629. union {
  630. // Singular argument storage pointers.
  631. bool* flag_storage;
  632. int* integer_storage;
  633. llvm::StringRef* string_storage;
  634. // Appending argument storage pointers.
  635. llvm::SmallVectorImpl<int>* integer_sequence;
  636. llvm::SmallVectorImpl<llvm::StringRef>* string_sequence;
  637. // One-of information.
  638. struct {
  639. llvm::OwningArrayRef<llvm::StringRef> value_strings;
  640. ValueActionT value_action;
  641. };
  642. };
  643. // Default values depending on the kind.
  644. union {
  645. bool default_flag;
  646. int default_integer;
  647. llvm::StringRef default_string;
  648. struct {
  649. DefaultActionT default_action;
  650. int default_value_index;
  651. };
  652. };
  653. };
  654. // The internal representation of a parsable command description, including its
  655. // options, positional arguments, and subcommands.
  656. struct Command {
  657. using Kind = CommandBuilder::Kind;
  658. explicit Command(const CommandInfo& info, Command* parent = nullptr);
  659. CommandInfo info;
  660. Command* parent;
  661. ActionT action;
  662. Kind kind = Kind::Invalid;
  663. bool is_help_hidden = false;
  664. llvm::SmallVector<std::unique_ptr<Arg>> options;
  665. llvm::SmallVector<std::unique_ptr<Arg>> positional_args;
  666. llvm::SmallVector<std::unique_ptr<Command>> subcommands;
  667. };
  668. template <typename T>
  669. void ArgBuilder::MetaAction(T action) {
  670. CARBON_CHECK(!arg_.meta_action) << "Cannot set a meta action twice!";
  671. arg_.meta_action = std::move(action);
  672. }
  673. template <typename T>
  674. auto OneOfArgBuilder::OneOfValueT<T>::Default(
  675. bool is_default) && -> OneOfValueT {
  676. OneOfValueT result = std::move(*this);
  677. result.is_default = is_default;
  678. return result;
  679. }
  680. template <typename T>
  681. OneOfArgBuilder::OneOfValueT<T>::OneOfValueT(llvm::StringRef str, T value)
  682. : str(str), value(std::move(value)) {}
  683. template <typename T>
  684. auto OneOfArgBuilder::OneOfValue(llvm::StringRef str, T value)
  685. -> OneOfValueT<T> {
  686. return OneOfValueT<T>(str, value);
  687. }
  688. template <typename T, typename U, size_t N>
  689. void OneOfArgBuilder::SetOneOf(const OneOfValueT<U> (&values)[N], T* result) {
  690. static_assert(N > 0, "Must include at least one value.");
  691. arg_.is_append = false;
  692. OneOfImpl(
  693. values, [result](T value) { *result = value; },
  694. std::make_index_sequence<N>{});
  695. }
  696. template <typename T, typename U, size_t N>
  697. void OneOfArgBuilder::AppendOneOf(const OneOfValueT<U> (&values)[N],
  698. llvm::SmallVectorImpl<T>* sequence) {
  699. static_assert(N > 0, "Must include at least one value.");
  700. arg_.is_append = true;
  701. OneOfImpl(
  702. values, [sequence](T value) { sequence->push_back(value); },
  703. std::make_index_sequence<N>{});
  704. }
  705. // An implementation tool for the one-of value candidate handling. Delegating to
  706. // this allows us to deduce a pack of indices from the array of candidates, and
  707. // then use that variadic pack to operate on the array in the variadic space.
  708. // This includes packaging the components up separately into our storage
  709. // representation, as well as processing the array to find and register any
  710. // default.
  711. //
  712. // The representation is especially tricky because we want all of the actual
  713. // values and even the *type* of values to be erased. We do that by building
  714. // lambdas that do the type-aware operations and storing those into type-erased
  715. // function objects.
  716. template <typename U, size_t N, typename MatchT, size_t... Indices>
  717. void OneOfArgBuilder::OneOfImpl(const OneOfValueT<U> (&input_values)[N],
  718. MatchT match,
  719. std::index_sequence<Indices...> /*indices*/) {
  720. std::array<llvm::StringRef, N> value_strings = {input_values[Indices].str...};
  721. std::array<U, N> values = {input_values[Indices].value...};
  722. // Directly copy the value strings into a heap-allocated array in the
  723. // argument.
  724. new (&arg_.value_strings)
  725. llvm::OwningArrayRef<llvm::StringRef>(value_strings);
  726. // And build a type-erased action that maps a specific value string to a value
  727. // by index.
  728. new (&arg_.value_action) Arg::ValueActionT(
  729. [values, match](const Arg& arg, llvm::StringRef value_string) -> bool {
  730. for (int i : llvm::seq<int>(0, N)) {
  731. if (value_string == arg.value_strings[i]) {
  732. match(values[i]);
  733. return true;
  734. }
  735. }
  736. return false;
  737. });
  738. // Fold over all the input values to see if there is a default.
  739. if ((input_values[Indices].is_default || ...)) {
  740. CARBON_CHECK(!arg_.is_append) << "Can't append default.";
  741. CARBON_CHECK((input_values[Indices].is_default + ... + 0) == 1)
  742. << "Cannot default more than one value.";
  743. arg_.has_default = true;
  744. // First build a lambda that configures the default using an index. We'll
  745. // call this below, this lambda isn't the one that is stored.
  746. auto set_default = [&](size_t index, const auto& default_value) {
  747. // Now that we have the desired default index, build a lambda and store it
  748. // as the default action. This lambda is stored and so it captures the
  749. // necessary information explicitly and by value.
  750. new (&arg_.default_action)
  751. Arg::DefaultActionT([value = default_value.value,
  752. match](const Arg& /*arg*/) { match(value); });
  753. // Also store the index itself for use when printing help.
  754. arg_.default_value_index = index;
  755. };
  756. // Now we fold across the inputs and in the one case that is the default, we
  757. // call the lambda. This is just a somewhat awkward way to write a loop with
  758. // a condition in it over a pack.
  759. ((input_values[Indices].is_default
  760. ? set_default(Indices, input_values[Indices])
  761. : static_cast<void>(0)),
  762. ...);
  763. }
  764. }
  765. } // namespace Carbon::CommandLine
  766. #endif // CARBON_COMMON_COMMAND_LINE_H_