Repository: bitcoin/bitcoin
File: src/bitcoin.cpp (C++)

Code before:

static constexpr auto HELP_SHORT = R"(
Run '%s help' to see additional commands (e.g. for testing and debugging).
)";

struct CommandLine {
    bool use_multiprocess{false};
    bool show_version{false};
    bool show_help{false};
    std::string_view command;
    std::vector<const char*> args;
};

CommandLine ParseCommandLine(int argc, char* argv[]);
static void ExecCommand(const std::vector<const char*>& args, std::string_view argv0);

int main(int argc, char* argv[])
{
    try {
        CommandLine cmd{ParseCommandLine(argc, argv)};
        if (cmd.show_version) {
            tfm::format(std::cout, "%s version %s\n%s", CLIENT_NAME, FormatFullVersion(), FormatParagraph(LicenseInfo()));
            return EXIT_SUCCESS;
        }

        std::string exe_name{fs::PathToString(fs::PathFromString(argv[0]).filename())};
        std::vector<const char*> args;
        if (cmd.show_help || cmd.command.empty()) {
            tfm::format(std::cout, HELP_USAGE, exe_name);
            if (cmd.show_help) {
                tfm::format(std::cout, HELP_EXTRA);
                return EXIT_SUCCESS;
            } else {
                tfm::format(std::cout, HELP_SHORT, exe_name);
                return EXIT_FAILURE;
            }
        } else if (cmd.command == "gui") {
            args.emplace_back(cmd.use_multiprocess ? "bitcoin-gui" : "bitcoin-qt");
        } else if (cmd.command == "node") {
            args.emplace_back(cmd.use_multiprocess ? "bitcoin-node" : "bitcoind");
        } else if (cmd.command == "rpc") {
            args.emplace_back("bitcoin-cli");
            // Since "bitcoin rpc" is a new interface that doesn't need to be
            // backward compatible, enable -named by default so it is convenient
            // for callers to use a mix of named and unnamed parameters. Callers
            // can override this by specifying -nonamed, but should not need to
            // unless they are passing string values containing '=' characters
            // as unnamed parameters.
            args.emplace_back("-named");
        } else if (cmd.command == "wallet") {
            args.emplace_back("bitcoin-wallet");

Review comment (suggestion):
In 03f585d58ccf4d5c02d621c5b6046d45807b3201 _bitcoin wrapper: improve help output_: this is a nice improvement.

Before:

```
bitcoin --help
Usage: bitcoin [OPTIONS] COMMAND..

which bitcoin
/usr/local/bin/bitcoin

/usr/local/bin/bitcoin --help
Usage: /usr/local/bin/bitcoin [OPTIONS] COMMAND...
```

After:

```
/usr/local/bin/bitcoin --help
Usage: bitcoin [OPTIONS] COMMAND..
```

Only tested on macOS

Code after:

static constexpr auto HELP_SHORT = R"(
Run '%s help' to see additional commands (e.g. for testing and debugging).
)";

struct CommandLine {
    bool use_multiprocess{false};
    bool show_version{false};
    bool show_help{false};
    std::string_view command;
    std::vector<const char*> args;
};

CommandLine ParseCommandLine(int argc, char* argv[]);
static void ExecCommand(const std::vector<const char*>& args, std::string_view argv0);

int main(int argc, char* argv[])
{
    try {
        CommandLine cmd{ParseCommandLine(argc, argv)};
        if (cmd.show_version) {
            tfm::format(std::cout, "%s version %s\n%s", CLIENT_NAME, FormatFullVersion(), FormatParagraph(LicenseInfo()));
            return EXIT_SUCCESS;
        }

        std::string exe_name{fs::PathToString(fs::PathFromString(argv[0]).filename())};
        std::vector<const char*> args;
        if (cmd.show_help || cmd.command.empty()) {
            tfm::format(std::cout, HELP_USAGE, exe_name);
            if (cmd.show_help) {
                tfm::format(std::cout, HELP_FULL);
                return EXIT_SUCCESS;
            } else {
                tfm::format(std::cout, HELP_SHORT, exe_name);
                return EXIT_FAILURE;
            }
        } else if (cmd.command == "gui") {
            args.emplace_back(cmd.use_multiprocess ? "bitcoin-gui" : "bitcoin-qt");
        } else if (cmd.command == "node") {
            args.emplace_back(cmd.use_multiprocess ? "bitcoin-node" : "bitcoind");
        } else if (cmd.command == "rpc") {
            args.emplace_back("bitcoin-cli");
            // Since "bitcoin rpc" is a new interface that doesn't need to be
            // backward compatible, enable -named by default so it is convenient
            // for callers to use a mix of named and unnamed parameters. Callers
            // can override this by specifying -nonamed, but should not need to
            // unless they are passing string values containing '=' characters
            // as unnamed parameters.
            args.emplace_back("-named");
        } else if (cmd.command == "wallet") {
            args.emplace_back("bitcoin-wallet");