Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping boost::program_options together into mandatory groups

I am using boost::program_options to handle command line parameters to a program. In the program below I would like group algo, exchanges and admin_port together such that they should all be provided else an exception is thrown (i.e. the don't make sense unless they are together).

I'd also like to print them out in a manner which makes it obvious they are a group.

How would this best be achieved?

#include <boost/program_options.hpp>
#include <cassert>
#include <iostream>
#include <string>

namespace prog_opts = boost::program_options;

int main(int argc, char *argv[])
{
    int rc = 0;

    prog_opts::options_description desc("Usage");
    desc.add_options()
        ("algo", prog_opts::value<std::string>(), "Name of the algo to run")
        ("exchanges", prog_opts::value< std::vector<std::string> >(), "Name(s) of the exchanges which will be available for use")
        ("admin_port", prog_opts::value<unsigned>(), "Admin port on which admin requests will be listened for")
        ("version", "Show version information")
        ("help", "Show help information");

    prog_opts::variables_map args;

    try
    {
        prog_opts::store(prog_opts::parse_command_line(argc, argv, desc), args);
        prog_opts::notify(args);

        if(args.count("algo") && args.count("exchanges") && args.count("admin_port"))
        {
            //TODO:
        }
        else if(args.count("version"))
        {
            //TODO:
        }
        else if(args.count("help"))
        {
            std::cout << desc << std::endl;
        }
        else
        {
            std::cerr << desc << std::endl;
            rc = 1;
        }  
    }
    catch(const prog_opts::error& e)
    {
        std::cerr << "Failed start with given command line arguments: " << e.what() << std::endl;
        rc = 1;
    }

    return rc;
}  
like image 572
Graeme Avatar asked Aug 21 '12 21:08

Graeme


1 Answers

To create mandatory groups you can do that with

prog_opts::value<std::string>()->required()

in the option description part of your program. This would look something like that:

#include <boost/program_options.hpp>
#include <cassert>
#include <iostream>
#include <string>

namespace prog_opts = boost::program_options;

int main(int argc, char *argv[])
{
int rc = 0;

prog_opts::options_description desc("Usage");
desc.add_options()
    ("algo", prog_opts::value<std::string>()->required(), "Name of the algo to run")
    ("exchanges", prog_opts::value< std::vector<std::string> >()->required(), "Name(s) of the exchanges which will be available for use")
    ("admin_port", prog_opts::value<unsigned>()->required(), "Admin port on which admin requests will be listened for")
    ("version", "Show version information")
    ("help", "Show help information");

prog_opts::variables_map args;

try
{
    prog_opts::store(prog_opts::parse_command_line(argc, argv, desc), args);
    prog_opts::notify(args);

    if(args.count("algo") && args.count("exchanges") && args.count("admin_port"))
    {
        //TODO:
    }
    else if(args.count("version"))
    {
        //TODO:
    }
    else if(args.count("help"))
    {
        std::cout << desc << std::endl;
    }
    else
    {
        std::cerr << desc << std::endl;
        rc = 1;
    }  
}
catch(const prog_opts::error& e)
{
    std::cerr << "Failed start with given command line arguments: " << e.what() << std::endl;
    rc = 1;
}

return rc;
}

I would suggest you check out the boost documentation in detail: http://www.boost.org/doc/libs/1_32_0/doc/html/program_options/overview.html#id548509

Also for more complicated argument dependencies it might make sense to "group" them together, creating several option descriptions. http://www.boost.org/doc/libs/1_32_0/doc/html/program_options/howto.html#id549397

like image 139
Jathavan Sriram Avatar answered Sep 28 '22 06:09

Jathavan Sriram