123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- // Copyright Sascha Ochsenknecht 2009.
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt
- // or copy at http://www.boost.org/LICENSE_1_0.txt)
- #include <boost/program_options/parsers.hpp>
- #include <boost/program_options/options_description.hpp>
- #include <boost/program_options/variables_map.hpp>
- #include <boost/program_options/cmdline.hpp>
- using namespace boost::program_options;
- #include <iostream>
- #include <sstream>
- #include <vector>
- #include <cassert>
- using namespace std;
- #include "minitest.hpp"
- void test_ambiguous()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,c", value<string>()->multitoken(), "the config file")
- ("output,c", value<string>(), "the output file")
- ("output,o", value<string>(), "the output file")
- ;
- const char* cmdline[] = {"program", "-c", "file", "-o", "anotherfile"};
- variables_map vm;
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- }
- catch (ambiguous_option& e)
- {
- BOOST_CHECK_EQUAL(e.alternatives().size(), 2);
- BOOST_CHECK_EQUAL(e.get_option_name(), "-c");
- BOOST_CHECK_EQUAL(e.alternatives()[0], "cfgfile");
- BOOST_CHECK_EQUAL(e.alternatives()[1], "output");
- }
- }
- void test_ambiguous_long()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,c", value<string>()->multitoken(), "the config file")
- ("output,c", value<string>(), "the output file")
- ("output,o", value<string>(), "the output file")
- ;
- const char* cmdline[] = {"program", "--cfgfile", "file", "--output", "anotherfile"};
- variables_map vm;
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- }
- catch (ambiguous_option& e)
- {
- BOOST_CHECK_EQUAL(e.alternatives().size(), 2);
- BOOST_CHECK_EQUAL(e.get_option_name(), "--output");
- BOOST_CHECK_EQUAL(e.alternatives()[0], "output");
- BOOST_CHECK_EQUAL(e.alternatives()[1], "output");
- }
- }
- void test_ambiguous_multiple_long_names()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,foo,c", value<string>()->multitoken(), "the config file")
- ("output,foo,o", value<string>(), "the output file")
- ;
- const char* cmdline[] = {"program", "--foo", "file"};
- variables_map vm;
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- }
- catch (ambiguous_option& e)
- {
- BOOST_CHECK_EQUAL(e.alternatives().size(), 2);
- BOOST_CHECK_EQUAL(e.get_option_name(), "--foo");
- BOOST_CHECK_EQUAL(e.alternatives()[0], "cfgfile");
- BOOST_CHECK_EQUAL(e.alternatives()[1], "output");
- }
- }
- void test_unknown_option()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,c", value<string>(), "the configfile")
- ;
- const char* cmdline[] = {"program", "-c", "file", "-f", "anotherfile"};
-
- variables_map vm;
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- }
- catch (unknown_option& e)
- {
- BOOST_CHECK_EQUAL(e.get_option_name(), "-f");
- BOOST_CHECK_EQUAL(string(e.what()), "unrecognised option '-f'");
- }
- }
- void test_multiple_values()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,c", value<string>()->multitoken(), "the config file")
- ("output,o", value<string>(), "the output file")
- ;
- const char* cmdline[] = { "program", "-o", "fritz", "hugo", "--cfgfile", "file", "c", "-o", "text.out" };
-
- variables_map vm;
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- notify(vm);
- }
- catch (validation_error& e)
- {
- // TODO: this is currently validation_error, shouldn't it be multiple_values ???
- //
- // multiple_values is thrown only at one place untyped_value::xparse(),
- // but I think this can never be reached
- // because: untyped_value always has one value and this is filtered before reach specific
- // validation and parsing
- //
- BOOST_CHECK_EQUAL(e.get_option_name(), "--cfgfile");
- BOOST_CHECK_EQUAL(string(e.what()), "option '--cfgfile' only takes a single argument");
- }
- }
- void test_multiple_occurrences()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,c", value<string>(), "the configfile")
- ;
- const char* cmdline[] = {"program", "--cfgfile", "file", "-c", "anotherfile"};
- variables_map vm;
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- notify(vm);
- }
- catch (multiple_occurrences& e)
- {
- BOOST_CHECK_EQUAL(e.get_option_name(), "--cfgfile");
- BOOST_CHECK_EQUAL(string(e.what()), "option '--cfgfile' cannot be specified more than once");
- }
- }
- void test_multiple_occurrences_with_different_names()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,config-file,c", value<string>(), "the configfile")
- ;
- const char* cmdline[] = {"program", "--config-file", "file", "--cfgfile", "anotherfile"};
- variables_map vm;
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- notify(vm);
- }
- catch (multiple_occurrences& e)
- {
- BOOST_CHECK( (e.get_option_name() == "--cfgfile") || (e.get_option_name() == "--config-file"));
- BOOST_CHECK(
- (string(e.what()) == "option '--cfgfile' cannot be specified more than once") ||
- (string(e.what()) == "option '--config-file' cannot be specified more than once")
- );
- }
- }
- void test_multiple_occurrences_with_non_key_names()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,config-file,c", value<string>(), "the configfile")
- ;
- const char* cmdline[] = {"program", "--config-file", "file", "-c", "anotherfile"};
- variables_map vm;
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- notify(vm);
- }
- catch (multiple_occurrences& e)
- {
- BOOST_CHECK_EQUAL(e.get_option_name(), "--cfgfile");
- BOOST_CHECK_EQUAL(string(e.what()), "option '--cfgfile' cannot be specified more than once");
- }
- }
- void test_missing_value()
- {
- options_description desc;
- desc.add_options()
- ("cfgfile,c", value<string>()->multitoken(), "the config file")
- ("output,o", value<string>(), "the output file")
- ;
- // missing value for option '-c'
- const char* cmdline[] = { "program", "-c", "-c", "output.txt"};
-
- variables_map vm;
-
- try {
- store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
- const_cast<char**>(cmdline), desc), vm);
- notify(vm);
- }
- catch (invalid_command_line_syntax& e)
- {
- BOOST_CHECK_EQUAL(e.kind(), invalid_syntax::missing_parameter);
- BOOST_CHECK_EQUAL(e.tokens(), "--cfgfile");
- }
- }
- int main(int /*ac*/, char** /*av*/)
- {
- test_ambiguous();
- test_ambiguous_long();
- test_ambiguous_multiple_long_names();
- test_unknown_option();
- test_multiple_values();
- test_multiple_occurrences();
- test_multiple_occurrences_with_different_names();
- test_multiple_occurrences_with_non_key_names();
- test_missing_value();
- return 0;
- }
|