command_line.h 33 KB

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