I am attempting to create a program with the following command line usage:
test_program [General Options] <mode_1_option_1> <required_option_1> OR
test_program [General Options] --toggle-mode <mode_2_option_1> <mode_2_option_2> <mode_2_option_3> <required_option_1> Where the inclusion of '--toggle-mode' dictates which mode the program runs in.
The following is my attempt at implementing Boost::program_options to accomplish this:
namespace po = boost::program_options; bool use_mode_2 = false; po::options_description general_options_desc("General Options"); general_options_desc.add_options() ("help,h", "this help message"); po::options_description mode_options_desc("Mode options"); mode_options_desc.add_options() ("toggle-mode,M", po::bool_switch(&use_mode_2), "specify mode 2 operations"); po::options_description required_options_desc("Required Options"); required_options_desc.add_options() ("required_option_1", po::value<std::string>()->required()); po::options_description mode_1_options_desc("Mode #1 Options"); mode_1_options_desc.add_options() ("mode_1_option_1", po::value<std::string>()->required()); po::options_description mode_2_options_desc("Mode #2 Options"); mode_2_options_desc.add_options() ("mode_2_option_1", po::value<std::string>()->required()) ("mode_2_option_2", po::value<std::string>()->required()) ("mode_2_option_3", po::value<std::string>()->required()); /* Sets my "use_mode_2" variable */ { po::variables_map mode_vm; po::store(po::command_line_parser(argc, argv).options(mode_options_desc).allow_unregistered().run(), mode_vm); po::notify(mode_vm); } po::options_description visible_options_desc("Visible Options"); visible_options_desc.add(general_options_desc); visible_options_desc.add(mode_options_desc); po::options_description all_options_desc("All Options"); all_options_desc.add(visible_options_desc); int positional_index = 1; po::positional_options_description positional_options_desc; if (use_mode_2) { positional_options_desc.add("mode_2_option_1", positional_index++); positional_options_desc.add("mode_2_option_2", positional_index++); positional_options_desc.add("mode_2_option_3", positional_index++); all_options_desc.add(mode_2_options_desc); } else { positional_options_desc.add("mode_1_option_1", positional_index++); all_options_desc.add(mode_1_options_desc); } positional_options_desc.add("required_option_1", positional_index); all_options_desc.add(required_options_desc); po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(all_options_desc).positional(positional_options_desc).run(), vm); if (vm.count("help")) { fprintf(stderr, "Usage:\n"); fprintf(stderr, " test_program [General Options] <mode_1_option_1> <required_option_1>\n"); fprintf(stderr, " test_program [General Options] --toggle-mode <mode_2_option_1> <mode_2_option_2> <mode_2_option_3> <required_option_1>\n\n"); visible_options_desc.print(std::cout); return EXIT_SUCCESS; } Running my program in Mode #1 works as expected:
.\test_program mode_1_option_1 required_option_1 But I run into issues while running it in Mode #2:
.\test_program -M mode_2_option_1 mode_2_option_2 mode_2_option_3 required_option_1 std_exception: option '--mode_2_option_2' cannot be specified more than once Does anyone have any idea what I may be missing?
Thanks!
