Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Is it possible to find out if an option was specified on the command line? #4

Open
colonelsammy opened this issue Jan 28, 2016 · 4 comments
Labels

Comments

@colonelsammy
Copy link

I would like to know if the user specified a particular command line option. I can do that by setting a bool in a bound function, but I can't help thinking that the framework already 'knows' if the option got used...I couldn't see any way to find out if it had been set though - can it be done?

My rather cludgy example code;

#define CLARA_CONFIG_MAIN
#include <clara.h>
#include <iostream>

struct Opt
{
    Opt()
        : hostnameWasSet(false)
    {}
    std::string processName;
    bool hostnameWasSet;
    std::string hostname;

    void setHostname(const std::string& h)
    {
        hostnameWasSet = true;
        hostname = h;
    }
};

int main(int argc, char* argv[])
{
    using namespace Clara;
    try
    {
        CommandLine<Opt> cli;

        cli.bindProcessName(&Opt::processName);
        cli["--host"]
            .describe("set the host name")
            .bind(&Opt::setHostname, "api.github.com");

        Opt opt;
        cli.parseInto(argc, const_cast<const char**>(argv), opt);
        if (opt.hostnameWasSet)
        {
            std::cout << "Hostname was set..." << opt.hostname << std::endl;
        }
        else
        {
            std::cout << "Hostname was NOT set...do stuff that doesn't need the hostname" << std::endl;
        }
    }
    catch (const std::exception& e)
    {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
    catch (...)
    {
        std::cerr << "Unknown exception..." << std::endl;
    }

    return 0;
}

This is the result that I want:

c:\Projects\ClaraExample\Debug>ClaraExample.exe --host=fred
Hostname was set...fred

c:\Projects\ClaraExample\Debug>ClaraExample.exe
Hostname was NOT set...do stuff that doesn't need the hostname
@philsquared
Copy link
Collaborator

I'm considering pulling the Option type out of Catch and making it available to Clara (and all users of Clara), so you could make your field Clara::Option<std::String> hostname; and test it with:
if( opt.hostname ) std::cout << "Hostname was set..." << *opt.hostname << std::end;

How would that sound to you?

@colonelsammy
Copy link
Author

Yes, I think that would work pretty well...please do that!

@KingDuckZ
Copy link

I've achieved this by passing std::optional as the value to Opt. I implemented a trivial operator>> that simply initializes the std::optional argument with whatever T it extracts from the stream and everything works just fine. After parsing I can test if the optional value was initialized.

@philsquared
Copy link
Collaborator

I've finally implemented this in Clara (not in the single include yet - but will do a release soon).
It tries to auto-detect availability of std::optional, which seems to work for GCC, but from what I have read probably doesn't for VS 2017 yet (will get to that).
Either way you can override it to force support by defining:

CLARA_CONFIG_OPTIONAL_TYPE std::optional

Or you can use that to specify any alternative optional (template) type, as long as it supports the ! and * operators.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants