command_line.h 33 KB

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