]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
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 | ||
92f5a8d4 TL |
48 | void test_ambiguous_long() |
49 | { | |
50 | options_description desc; | |
51 | desc.add_options() | |
52 | ("cfgfile,c", value<string>()->multitoken(), "the config file") | |
53 | ("output,c", value<string>(), "the output file") | |
54 | ("output,o", value<string>(), "the output file") | |
55 | ; | |
56 | ||
57 | const char* cmdline[] = {"program", "--cfgfile", "file", "--output", "anotherfile"}; | |
58 | ||
59 | variables_map vm; | |
60 | try { | |
61 | store(parse_command_line(sizeof(cmdline)/sizeof(const char*), | |
62 | const_cast<char**>(cmdline), desc), vm); | |
63 | } | |
64 | catch (ambiguous_option& e) | |
65 | { | |
66 | BOOST_CHECK_EQUAL(e.alternatives().size(), 2); | |
67 | BOOST_CHECK_EQUAL(e.get_option_name(), "--output"); | |
68 | BOOST_CHECK_EQUAL(e.alternatives()[0], "output"); | |
69 | BOOST_CHECK_EQUAL(e.alternatives()[1], "output"); | |
70 | } | |
71 | } | |
72 | ||
73 | void test_ambiguous_multiple_long_names() | |
74 | { | |
75 | options_description desc; | |
76 | desc.add_options() | |
77 | ("cfgfile,foo,c", value<string>()->multitoken(), "the config file") | |
78 | ("output,foo,o", value<string>(), "the output file") | |
79 | ; | |
80 | ||
81 | const char* cmdline[] = {"program", "--foo", "file"}; | |
82 | ||
83 | variables_map vm; | |
84 | try { | |
85 | store(parse_command_line(sizeof(cmdline)/sizeof(const char*), | |
86 | const_cast<char**>(cmdline), desc), vm); | |
87 | } | |
88 | catch (ambiguous_option& e) | |
89 | { | |
90 | BOOST_CHECK_EQUAL(e.alternatives().size(), 2); | |
91 | BOOST_CHECK_EQUAL(e.get_option_name(), "--foo"); | |
92 | BOOST_CHECK_EQUAL(e.alternatives()[0], "cfgfile"); | |
93 | BOOST_CHECK_EQUAL(e.alternatives()[1], "output"); | |
94 | } | |
95 | } | |
96 | ||
97 | ||
7c673cae FG |
98 | |
99 | void test_unknown_option() | |
100 | { | |
101 | options_description desc; | |
102 | desc.add_options() | |
103 | ("cfgfile,c", value<string>(), "the configfile") | |
104 | ; | |
105 | ||
106 | const char* cmdline[] = {"program", "-c", "file", "-f", "anotherfile"}; | |
107 | ||
108 | variables_map vm; | |
109 | try { | |
110 | store(parse_command_line(sizeof(cmdline)/sizeof(const char*), | |
111 | const_cast<char**>(cmdline), desc), vm); | |
112 | } | |
113 | catch (unknown_option& e) | |
114 | { | |
115 | BOOST_CHECK_EQUAL(e.get_option_name(), "-f"); | |
116 | BOOST_CHECK_EQUAL(string(e.what()), "unrecognised option '-f'"); | |
117 | } | |
118 | } | |
119 | ||
120 | ||
121 | ||
122 | void test_multiple_values() | |
123 | { | |
124 | options_description desc; | |
125 | desc.add_options() | |
126 | ("cfgfile,c", value<string>()->multitoken(), "the config file") | |
127 | ("output,o", value<string>(), "the output file") | |
128 | ; | |
129 | ||
130 | const char* cmdline[] = { "program", "-o", "fritz", "hugo", "--cfgfile", "file", "c", "-o", "text.out" }; | |
131 | ||
132 | variables_map vm; | |
133 | try { | |
134 | store(parse_command_line(sizeof(cmdline)/sizeof(const char*), | |
135 | const_cast<char**>(cmdline), desc), vm); | |
136 | notify(vm); | |
137 | } | |
138 | catch (validation_error& e) | |
139 | { | |
140 | // TODO: this is currently validation_error, shouldn't it be multiple_values ??? | |
141 | // | |
142 | // multiple_values is thrown only at one place untyped_value::xparse(), | |
143 | // but I think this can never be reached | |
144 | // because: untyped_value always has one value and this is filtered before reach specific | |
145 | // validation and parsing | |
146 | // | |
147 | BOOST_CHECK_EQUAL(e.get_option_name(), "--cfgfile"); | |
148 | BOOST_CHECK_EQUAL(string(e.what()), "option '--cfgfile' only takes a single argument"); | |
149 | } | |
150 | } | |
151 | ||
152 | ||
7c673cae FG |
153 | void test_multiple_occurrences() |
154 | { | |
155 | options_description desc; | |
156 | desc.add_options() | |
157 | ("cfgfile,c", value<string>(), "the configfile") | |
158 | ; | |
159 | ||
160 | const char* cmdline[] = {"program", "--cfgfile", "file", "-c", "anotherfile"}; | |
92f5a8d4 | 161 | |
7c673cae FG |
162 | variables_map vm; |
163 | try { | |
92f5a8d4 | 164 | store(parse_command_line(sizeof(cmdline)/sizeof(const char*), |
7c673cae FG |
165 | const_cast<char**>(cmdline), desc), vm); |
166 | notify(vm); | |
167 | } | |
168 | catch (multiple_occurrences& e) | |
169 | { | |
92f5a8d4 | 170 | BOOST_CHECK_EQUAL(e.get_option_name(), "--cfgfile"); |
7c673cae FG |
171 | BOOST_CHECK_EQUAL(string(e.what()), "option '--cfgfile' cannot be specified more than once"); |
172 | } | |
173 | } | |
174 | ||
92f5a8d4 TL |
175 | void test_multiple_occurrences_with_different_names() |
176 | { | |
177 | options_description desc; | |
178 | desc.add_options() | |
179 | ("cfgfile,config-file,c", value<string>(), "the configfile") | |
180 | ; | |
181 | ||
182 | const char* cmdline[] = {"program", "--config-file", "file", "--cfgfile", "anotherfile"}; | |
183 | ||
184 | variables_map vm; | |
185 | try { | |
186 | store(parse_command_line(sizeof(cmdline)/sizeof(const char*), | |
187 | const_cast<char**>(cmdline), desc), vm); | |
188 | notify(vm); | |
189 | } | |
190 | catch (multiple_occurrences& e) | |
191 | { | |
192 | BOOST_CHECK( (e.get_option_name() == "--cfgfile") || (e.get_option_name() == "--config-file")); | |
193 | BOOST_CHECK( | |
194 | (string(e.what()) == "option '--cfgfile' cannot be specified more than once") || | |
195 | (string(e.what()) == "option '--config-file' cannot be specified more than once") | |
196 | ); | |
197 | } | |
198 | } | |
199 | ||
200 | ||
201 | void test_multiple_occurrences_with_non_key_names() | |
202 | { | |
203 | options_description desc; | |
204 | desc.add_options() | |
205 | ("cfgfile,config-file,c", value<string>(), "the configfile") | |
206 | ; | |
207 | ||
208 | const char* cmdline[] = {"program", "--config-file", "file", "-c", "anotherfile"}; | |
209 | ||
210 | variables_map vm; | |
211 | try { | |
212 | store(parse_command_line(sizeof(cmdline)/sizeof(const char*), | |
213 | const_cast<char**>(cmdline), desc), vm); | |
214 | notify(vm); | |
215 | } | |
216 | catch (multiple_occurrences& e) | |
217 | { | |
218 | BOOST_CHECK_EQUAL(e.get_option_name(), "--cfgfile"); | |
219 | BOOST_CHECK_EQUAL(string(e.what()), "option '--cfgfile' cannot be specified more than once"); | |
220 | } | |
221 | } | |
7c673cae FG |
222 | |
223 | ||
224 | void test_missing_value() | |
225 | { | |
226 | options_description desc; | |
227 | desc.add_options() | |
228 | ("cfgfile,c", value<string>()->multitoken(), "the config file") | |
229 | ("output,o", value<string>(), "the output file") | |
230 | ; | |
231 | // missing value for option '-c' | |
232 | const char* cmdline[] = { "program", "-c", "-c", "output.txt"}; | |
233 | ||
234 | variables_map vm; | |
235 | ||
236 | try { | |
237 | store(parse_command_line(sizeof(cmdline)/sizeof(const char*), | |
238 | const_cast<char**>(cmdline), desc), vm); | |
239 | notify(vm); | |
240 | } | |
241 | catch (invalid_command_line_syntax& e) | |
242 | { | |
243 | BOOST_CHECK_EQUAL(e.kind(), invalid_syntax::missing_parameter); | |
244 | BOOST_CHECK_EQUAL(e.tokens(), "--cfgfile"); | |
245 | } | |
246 | } | |
247 | ||
248 | ||
249 | ||
250 | int main(int /*ac*/, char** /*av*/) | |
251 | { | |
252 | test_ambiguous(); | |
92f5a8d4 TL |
253 | test_ambiguous_long(); |
254 | test_ambiguous_multiple_long_names(); | |
7c673cae FG |
255 | test_unknown_option(); |
256 | test_multiple_values(); | |
257 | test_multiple_occurrences(); | |
92f5a8d4 TL |
258 | test_multiple_occurrences_with_different_names(); |
259 | test_multiple_occurrences_with_non_key_names(); | |
7c673cae FG |
260 | test_missing_value(); |
261 | ||
262 | return 0; | |
263 | } | |
264 |