I am using boost::program_options to make a simple executable with the following general syntax:
program --command <cmd> [args]
For example:
program --command run --listen locahost --port 8080
I would like to make the command
part a positional argument, so that the user is not forced to type it everytime. Therefore it should also work like this:
program run --listen locahost --port 8080
Each command has its own set of arguments, and all are optional.
The following code does function properly only when the positional arguments are not used. This looks fine according to the boost docs (unless I am missing a point). When adding positional argument, I get an exception on parsing that says too many positional options have been specified on the command line
// Define the options
po::options_description args("Generic options");
args.add_options()
("command", po::value<std::string>(), "command to execute");
("arg1", po::value<std::string>(), "argument 1")
("arg2", po::value<std::string>(), "argument 2")
("arg3", po::value<std::string>(), "argument 3")
("arg4", po::value<std::string>(), "argument 4");
po::positional_options_description positional;
positional.add("command", 1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(args)
.positional(positional) // Problem here
.allow_unregistered()
.run(), vm);
// Check if positional command is present
if (vm.count("command")) {
std::string command = vm["command"].as<std::string>();
std::cout << "Command: " << command << "n";
}
po::notify(vm);
std::cout << "arg1: " << vm["arg1"].as<std::string>() << "n";
std::cout << "arg2: " << vm["arg2"].as<std::string>() << "n";
std::cout << "arg3: " << vm["arg3"].as<std::string>() << "n";
std::cout << "arg4: " << vm["arg4"].as<std::string>() << "n";