Search code examples
c++boost-program-options

How can I parse command line arguments that themselves contain switches using boost::program_options?


I'm writing a program in C++ that is a wrapper for some benchmarks that contains some setup code at the beginning and analisys code in the end.

I want to run up to two benchmarks in parallel. The original commandlines for these are:

/path0/benchmark0 -switch0 -switch1 -switch2
/path1/benchmark1 -arg0 -arg1 -arg2 -arg4

And I want to put these on my wrapper's commandline:

wrapper -setup_arg0 -setup_arg1 -analysis_arg0 --command0 /path0/benchmark0 -switch0 -switch1 -switch2 --command1 /path1/benchmark1 -arg0 -arg1 -arg2 -arg4

Where I want to get two std::vector<std::string>s, one for each of command0 and command1, containing the original commandlines. This is how I'm doing it (using boost::program_options):

("command0", po::value<std::vector< std::string> >(&command0)->multitoken(), "command line for thread 0")
("command1", po::value<std::vector< std::string> >(&command1)->multitoken(), "command line for thread 1")

and this basically works. However, if the benchmark's arguments begin with - (as most switches on most programs I've seen do), the program_options tries to parse them as part of the wrapper's switches, because it doesn't know that they should be grouped together under command0 or command1.

Does program_options support that? If so, how?


Example:

Where I work there is a convention for doing this by "terminating" the multitoken like this:

wrapper <snip> --command0 /path0/benchmark0 -switch0 -switch1 -switch2 -command0- 

(in this example I terminated --command0 with -command0-.)

How can I make program_options handle it like this?


Solution

  • I think it's best if you take command0 and command1's values as a single string. e.g.,

    wrapper --command0 "/path0/benchmark0 ..." --command1 "/path1/benchmark1 ..."
    

    Yes, there's more work for you in that you have to wordexp your respective command strings (unless you're already just passing those strings straight to the shell ;-)), but it more cleanly separates out what's for the wrapper and what's for the invoked commands.