1 // Copyright Sascha Ochsenknecht 2009.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt
4 // or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6
7 #include <boost/program_options/parsers.hpp>
8 #include <boost/program_options/options_description.hpp>
9 #include <boost/program_options/variables_map.hpp>
10 #include <boost/program_options/cmdline.hpp>
11 using namespace boost::program_options;
12
13 #include <iostream>
14 #include <sstream>
15 #include <vector>
16 #include <cassert>
17 using namespace std;
18
19 #include "minitest.hpp"
20
21
test_ambiguous()22 void test_ambiguous()
23 {
24 options_description desc;
25 desc.add_options()
26 ("cfgfile,c", value<string>()->multitoken(), "the config file")
27 ("output,c", value<string>(), "the output file")
28 ("output,o", value<string>(), "the output file")
29 ;
30
31 const char* cmdline[] = {"program", "-c", "file", "-o", "anotherfile"};
32
33 variables_map vm;
34 try {
35 store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
36 const_cast<char**>(cmdline), desc), vm);
37 }
38 catch (ambiguous_option& e)
39 {
40 BOOST_CHECK_EQUAL(e.alternatives().size(), 2);
41 BOOST_CHECK_EQUAL(e.get_option_name(), "-c");
42 BOOST_CHECK_EQUAL(e.alternatives()[0], "cfgfile");
43 BOOST_CHECK_EQUAL(e.alternatives()[1], "output");
44 }
45 }
46
47
48
test_unknown_option()49 void test_unknown_option()
50 {
51 options_description desc;
52 desc.add_options()
53 ("cfgfile,c", value<string>(), "the configfile")
54 ;
55
56 const char* cmdline[] = {"program", "-c", "file", "-f", "anotherfile"};
57
58 variables_map vm;
59 try {
60 store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
61 const_cast<char**>(cmdline), desc), vm);
62 }
63 catch (unknown_option& e)
64 {
65 BOOST_CHECK_EQUAL(e.get_option_name(), "-f");
66 BOOST_CHECK_EQUAL(string(e.what()), "unrecognised option '-f'");
67 }
68 }
69
70
71
test_multiple_values()72 void test_multiple_values()
73 {
74 options_description desc;
75 desc.add_options()
76 ("cfgfile,c", value<string>()->multitoken(), "the config file")
77 ("output,o", value<string>(), "the output file")
78 ;
79
80 const char* cmdline[] = { "program", "-o", "fritz", "hugo", "--cfgfile", "file", "c", "-o", "text.out" };
81
82 variables_map vm;
83 try {
84 store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
85 const_cast<char**>(cmdline), desc), vm);
86 notify(vm);
87 }
88 catch (validation_error& e)
89 {
90 // TODO: this is currently validation_error, shouldn't it be multiple_values ???
91 //
92 // multiple_values is thrown only at one place untyped_value::xparse(),
93 // but I think this can never be reached
94 // because: untyped_value always has one value and this is filtered before reach specific
95 // validation and parsing
96 //
97 BOOST_CHECK_EQUAL(e.get_option_name(), "--cfgfile");
98 BOOST_CHECK_EQUAL(string(e.what()), "option '--cfgfile' only takes a single argument");
99 }
100 }
101
102
103
test_multiple_occurrences()104 void test_multiple_occurrences()
105 {
106 options_description desc;
107 desc.add_options()
108 ("cfgfile,c", value<string>(), "the configfile")
109 ;
110
111 const char* cmdline[] = {"program", "--cfgfile", "file", "-c", "anotherfile"};
112
113 variables_map vm;
114 try {
115 store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
116 const_cast<char**>(cmdline), desc), vm);
117 notify(vm);
118 }
119 catch (multiple_occurrences& e)
120 {
121 BOOST_CHECK_EQUAL(e.get_option_name(), "--cfgfile");
122 BOOST_CHECK_EQUAL(string(e.what()), "option '--cfgfile' cannot be specified more than once");
123 }
124 }
125
126
127
test_missing_value()128 void test_missing_value()
129 {
130 options_description desc;
131 desc.add_options()
132 ("cfgfile,c", value<string>()->multitoken(), "the config file")
133 ("output,o", value<string>(), "the output file")
134 ;
135 // missing value for option '-c'
136 const char* cmdline[] = { "program", "-c", "-c", "output.txt"};
137
138 variables_map vm;
139
140 try {
141 store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
142 const_cast<char**>(cmdline), desc), vm);
143 notify(vm);
144 }
145 catch (invalid_command_line_syntax& e)
146 {
147 BOOST_CHECK_EQUAL(e.kind(), invalid_syntax::missing_parameter);
148 BOOST_CHECK_EQUAL(e.tokens(), "--cfgfile");
149 }
150 }
151
152
153
main(int,char **)154 int main(int /*ac*/, char** /*av*/)
155 {
156 test_ambiguous();
157 test_unknown_option();
158 test_multiple_values();
159 test_multiple_occurrences();
160 test_missing_value();
161
162 return 0;
163 }
164
165