I am using Boost.program_options to parse commandlines for my implementation of POSIX utilities. As a simple example, take cmp
.
Now I would like to have an extra argument --help
which shows a description of all arguments, which is important in this case. I have:
po::options_description options("Options");
options.add_options()("help", "Show this help output.")
(",l", "(Lowercase ell.) Write the byte number (decimal) and the differing bytes (octal) for each difference.")
(",s", "Write nothing for differing files; return exit status only.")
po::positional_options_description operands;
operands.add("file1", 1);//, "A pathname of the first file to be compared. If file1 is '-', the standard input shall be used.")
operands.add("file2", 1);//, "A pathname of the second file to be compared. If file2 is '-', the standard input shall be used.");
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(options).positional(operands).run(), vm);
po::notify(vm);
if(vm.count("help"))
{
std::cout << "cmp: compare two files\nUsage: cmp [ -l | -s ] file1 file2\n" << options;
return 0;
}
which is unable to show the file1
and file2
options' description. I can of course add them to options
, but this would add at least two unwanted arguments [-]-file{1,2}
, which I really do not want. I just want this output for --help
(without obviously hardcoding it):
cmp: compare two files
Usage: cmp [ -l | -s ] file1 file2
Options:
--help Show this help output.
-l (Lowercase ell.) Write the byte number (decimal) and the differing bytes (octal) for each difference.
-s Write nothing for differing files; return exit status only.
Operands:
file1 A pathname of the first file to be compared. If file1 is '-', the standard input shall be used.
file2 A pathname of the second file to be compared. If file2 is '-', the standard input shall be used.
Is there any way to achieve this without hacking around the library? I'd think this is pretty basic stuff, but I can't find it in any of the tutorials.
UPDATE For everyone's benefit, I submitted a feature request for this, in a hopefully backwards compatible way.
It's not ideal, but how about creating a "dummy" set of program options, let the boost::program_options formatter format its help text for you, and then just remove the dashes with a quick replace?
Then output that help text in addition to the options
help text.
Something like this:
po::options_description dummy_options("Operands");
dummy_options.add_options()
("file1", po::value<std::string>(), "A pathname of the first file to be compared. If file1 is '-', the standard input shall be used.")
("file2", po::value<std::string>(), "A pathname of the second file to be compared. If file2 is '-', the standard input shall be used.")
;
std::stringstream s;
s << dummy_options;
std::string dummy_help_text = s.str();
boost::replace_all(dummy_help_text, "--", "");
boost::replace_all(dummy_help_text, "arg", " ");
std::cout << dummy_help_text << std::endl;
The output looks like this:
Operands:
file1 A pathname of the first file to be compared. If file1
is '-', the standard input shall be used.
file2 A pathname of the second file to be compared. If file2
is '-', the standard input shall be used.
It's not ideal because, among other things, the the spacing between columns will not match the help output from your other options
output. But for something quick-and-dirty, that basically works, it could be OK.
It's a thought, anyway.
(I do not see anything in the Boost.Program_Options API that allows you to do this the "right" way, either. https://stackoverflow.com/a/3621947/368896 gives a hint that this sort of thing is not supported, but that is 3 years old now.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With