Skip to content

Commit c58b619

Browse files
committed
Print the help when --help or -h is unexpectedly encountered.
Most binaries used on Linux support the '--help' argument, this is a convention specified by the [GNU project][1], as well as in the [clig][2]. Currently, adding `--help` after a failing command gives an error, following by an note at the end on how to get the help. Actually getting the help usually involves pressing the up arrow, removing the erroneous `--help` at the end, moving the cursor to after `picotool` to insert `help` and then succesfully printing out the help. This commit adds a new error type to the parser to distinguish between parse errors, and errors that can be identified as an attempt to obtain the help. This help error is raised only if an unexpected argument called `--help` is encountered, or an unexpected option `-h`. In the `main.cpp` this specific error is now caught and handled on appropriately, still relying on the outer catch problematic parse errors, like using command names that don't exist. [1]: https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html [2]: https://clig.dev/#help
1 parent de8ae5a commit c58b619

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

cli.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ namespace cli {
6161
private:
6262
string _what;
6363
};
64+
/// A parse error that can be identified as a user trying to obtain the help.
65+
struct help_error: parse_error {
66+
using parse_error::parse_error;
67+
};
6468

6569
struct group;
6670
template<typename T>
@@ -1023,6 +1027,13 @@ namespace cli {
10231027
}
10241028
}
10251029
if (!ms.remaining_args.empty()) {
1030+
// Check if any argument can be identified as the user searching for the help.
1031+
for (const auto &remaining : ms.remaining_args) {
1032+
if (remaining == "-h" || remaining == "--help") {
1033+
throw help_error("unexpected argument: "+remaining);
1034+
}
1035+
}
1036+
10261037
if (ms.remaining_args[0].find('-')==0) {
10271038
throw parse_error("unexpected option: "+ms.remaining_args[0]);
10281039
} else {

main.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,8 +1618,17 @@ int parse(const int argc, char **argv) {
16181618
no_global_header = true;
16191619
throw cli::parse_error("unknown command '" + args[0] + "'");
16201620
}
1621-
cli::match(settings, selected_cmd->get_cli(), args);
1622-
} catch (std::exception &e) {
1621+
1622+
// If a parse error occurs, and it is a cry for help, print the help instead.
1623+
try {
1624+
cli::match(settings, selected_cmd->get_cli(), args);
1625+
} catch (const cli::help_error &e) {
1626+
fos << "ERROR: " << e.what() << ", this looks like you want the help:\n";
1627+
help_mode = true;
1628+
usage();
1629+
return 1;
1630+
}
1631+
} catch (const std::exception &e) {
16231632
fos.wrap_hard();
16241633
fos << "ERROR: " << e.what() << "\n\n";
16251634
usage();

0 commit comments

Comments
 (0)