This is the best answer I could implement after 2 hours studing the library. I posted this as answer because in some way give a solution to the question, but I'm aware it's very possible that someone comes with a better solution.
What's the best way for selecting which options_description object we will parse the command line with?
So far, I managed to select between two options_description objects according the first option(See code for more detail). What I did is the following:
- Create two options_descrition objects (
OptDescA
for TA
and OptDescB
for TB
).
- Check if the first argument is
command_a
or command_b
.
- Depending on the first argument I parse the command line with
OptDescA
or OptDescB
For the point 3, I had to decrement argc
by one and move the argv
pointer 1 forward.
po::store(po::parse_command_line(argc - 1, argv + 1, OptDescA), vm);
that way I don't have to handlecommand_a
nor command_b
in OptDescA
or OptDescB
.
What's the best way for implementing a help system for "commands".
Well, this was (actually is) the most difficult for me. For implemetation details see the code below.
The problem with my help system is I have to type:
app help command_a
instead the most common:
app command_a help
besides after you type app help the ouput is:
Available commands:
--help arg Display this message
--command_a Do command_a stuff
--command_b Do command_b stuff
note the ugly --help arg
Code
#include <iostream>
#include <string>
#include <boost/program_options.hpp>
using namespace std;
void help_system(string target);
int main(int argc, char *argv[])
{
namespace po = boost::program_options;
po::options_description command_a("Command_a options");
command_a.add_options()
("option_1", po::value<int>()->required(), "option_1 desc")
("option_2", po::value<int>()->required(), "option_2 desc")
;
po::options_description command_b("Command_b options");
command_b.add_options()
("option_3", po::value<int>()->required(), "option_3 desc")
("option_4", po::value<int>()->required(), "option_4 desc")
;
po::options_description commands("Available commands");
commands.add_options()
("help", po::value<string>()->default_value(""), "Display this message")
("command_a", "Do command_a stuff")
("command_b", "Do command_b stuff")
;
po::variables_map vm;
if (string("command_a") == string(*(argv + 1))) {
try{ po::store(po::parse_command_line(argc - 1, argv + 1, command_a), vm); }
catch (exception &e){ cout << "Error: " << e.what() << endl; }
}
else if (string("command_b") == string(*(argv + 1))) {
try{ po::store(po::parse_command_line(argc - 1, argv + 1, command_b), vm); }
catch (exception &e){ cout << "Error: " << e.what() << endl; }
}
else if (string("help") == string(*(argv + 1)))
{
cout << commands << endl;
}
try { po::notify(vm); }
catch (exception &e) { cout << "Error: " << e.what() << endl; }
return 0;
}
void help_system(string target)
{
if (target.c_str() == "command_a") {} // The ideal is to do "cout << command_a" here
// but right now command_a is out of the scope.
if (target.c_str() == "command_b") {}
}