1

I have implemented an application(lets call it "app") that performs 2 types of tasks, TA and TB. The command line options differs for each type of task. That's why I have decided that the user will specify the type of task with a "command":

app command_a --opt_1  --opt_2     # For TA
app command_b --opt_3  --opt_4     # For TB

Of course command_a and command_b, are mutually exclusive. (You can see how to do this here).

Question 1: What's the best way for selecting which options_description object we will parse the command line with?

Question 2: What's the best way for implementing a help system for commands? Example:

app help command_a              # Display help for TA
Community
  • 1
  • 1
Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60

1 Answers1

0

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:

  1. Create two options_descrition objects ( OptDescA for TA and OptDescB for TB).
  2. Check if the first argument is command_a or command_b.
  3. 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") {}
}
Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60