Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/program_options/test/parsers_test.cpp @ 33

Last change on this file since 33 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 7.0 KB
Line 
1// Copyright Vladimir Prus 2002-2004.
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>
10using namespace boost::program_options;
11// We'll use po::value everywhere to workaround vc6 bug.
12namespace po = boost::program_options;
13
14#include <boost/function.hpp>
15using namespace boost;
16
17#define BOOST_INCLUDE_MAIN  // for testing, include rather than link
18#include <boost/test/test_tools.hpp>
19
20#include <sstream>
21using namespace std;
22
23#include <cstdlib> // for putenv
24
25#define TEST_CHECK_THROW(expression, exception, description) \
26    try \
27    { \
28        expression; \
29        BOOST_ERROR(description);\
30        throw 10; \
31    } \
32    catch(exception &) \
33    { \
34    }
35
36pair<string, vector< vector<string> > > msp(const string& s1)
37{
38    return std::make_pair(s1, vector< vector<string> >());
39}
40
41
42pair<string, vector< vector<string> > > msp(const string& s1, const string& s2)
43{
44    vector< vector<string> > v(1);
45    v[0].push_back(s2);
46    return std::make_pair(s1, v);
47}
48
49void check_value(const option& option, const char* name, const char* value)
50{
51    BOOST_CHECK(option.string_key == name);
52    BOOST_REQUIRE(option.value.size() == 1);
53    BOOST_CHECK(option.value.front() == value);
54}
55
56vector<string> sv(char* array[], unsigned size)
57{
58    vector<string> r;
59    for (unsigned i = 0; i < size; ++i)
60        r.push_back(array[i]);
61    return r;
62}
63
64pair<string, string> additional_parser(const std::string&)
65{
66    return pair<string, string>();
67}
68
69void test_command_line()
70{
71    // The following commented out blocks used to test parsing
72    // command line without syntax specification behaviour.
73    // It is disabled now and probably will never be enabled again:
74    // it is not possible to figure out what command line means without
75    // user's help.
76    #if 0
77    char* cmdline1[] = { "--a", "--b=12", "-f", "-g4", "-", "file" };
78
79    options_and_arguments a1 =
80        parse_command_line(cmdline1,
81                           cmdline1 + sizeof(cmdline1)/sizeof(cmdline1[0]));
82
83    BOOST_REQUIRE(a1.options().size() == 4);
84    BOOST_CHECK(a1.options()[0] == msp("a", ""));
85    BOOST_CHECK(a1.options()[1] == msp("b", "12"));
86    BOOST_CHECK(a1.options()[2] == msp("-f", ""));
87    BOOST_CHECK(a1.options()[3] == msp("-g", "4"));
88    BOOST_REQUIRE(a1.arguments().size() == 2);
89    BOOST_CHECK(a1.arguments()[0] == "-");
90    BOOST_CHECK(a1.arguments()[1] == "file");
91
92    char* cmdline2[] = { "--a", "--", "file" };
93
94    options_and_arguments a2 =
95        parse_command_line(cmdline2,
96                           cmdline2 + sizeof(cmdline2)/sizeof(cmdline2[0]));
97
98    BOOST_REQUIRE(a2.options().size() == 1);
99    BOOST_CHECK(a2.options()[0] == msp("a", ""));
100    BOOST_CHECK(a2.arguments().size() == 1);
101    BOOST_CHECK(a2.arguments()[0] == "file");
102    #endif
103   
104    options_description desc;
105    desc.add_options()
106        ("foo,f", new untyped_value(), "")
107        // Explicit qualification is a workaround for vc6
108        ("bar,b", po::value<std::string>(), "")
109        ("baz", new untyped_value())
110        ("plug*", new untyped_value())
111        ;
112    char* cmdline3_[] = { "--foo=12", "-f4", "--bar=11", "-b4",
113                          "--plug3=10"};
114    vector<string> cmdline3 = sv(cmdline3_,
115                                 sizeof(cmdline3_)/sizeof(cmdline3_[0]));
116    vector<option> a3 = 
117        command_line_parser(cmdline3).options(desc).run().options;
118                       
119    BOOST_CHECK_EQUAL(a3.size(), 5u);
120
121    check_value(a3[0], "foo", "12");
122    check_value(a3[1], "foo", "4");
123    check_value(a3[2], "bar", "11");
124    check_value(a3[3], "bar", "4");
125    check_value(a3[4], "plug3", "10");
126
127    // Regression test: check that '0' as style is interpreted as
128    // 'default_style'
129    vector<option> a4 = 
130        parse_command_line(5, cmdline3_, desc, 0, additional_parser).options;
131
132    BOOST_CHECK_EQUAL(a4.size(), 4u);
133    check_value(a4[0], "foo", "4");
134    check_value(a4[1], "bar", "11");
135
136    // Check that we don't crash on empty values of type 'string'
137    char* cmdline4[] = {"", "--open", ""};
138    options_description desc2;
139    desc2.add_options()
140        ("open", po::value<string>())
141        ;
142    variables_map vm;
143    po::store(po::parse_command_line(3, cmdline4, desc2), vm);
144
145
146
147}
148
149void test_config_file()
150{
151    options_description desc;
152    desc.add_options()
153        ("gv1", new untyped_value)
154        ("gv2", new untyped_value)
155        ("plug*", new untyped_value)
156        ("m1.v1", new untyped_value)
157        ("m1.v2", new untyped_value)
158        ("b", bool_switch())
159    ;
160
161    const char content1[] =
162    " gv1 = 0#asd\n"
163    "plug3 = 7\n"
164    "b = true\n"
165    "[m1]\n"
166    "v1 = 1\n"
167    "\n"
168    "v2 = 2\n"   
169    ;
170
171    stringstream ss(content1);
172    vector<option> a1 = parse_config_file(ss, desc).options;
173    BOOST_REQUIRE(a1.size() == 5);
174    check_value(a1[0], "gv1", "0");
175    check_value(a1[1], "plug3", "7");
176    check_value(a1[2], "b", "true");
177    check_value(a1[3], "m1.v1", "1");
178    check_value(a1[4], "m1.v2", "2");
179
180}
181
182void test_environment()
183{
184    options_description desc;
185    desc.add_options()
186        ("foo", new untyped_value, "")
187        ("bar", new untyped_value, "")
188        ;
189
190#if defined(_WIN32) && ! defined(__BORLANDC__)
191    _putenv("PO_TEST_FOO=1");
192#else
193    putenv("PO_TEST_FOO=1");
194#endif
195    parsed_options p = parse_environment(desc, "PO_TEST_");
196
197    BOOST_REQUIRE(p.options.size() == 1);
198    BOOST_CHECK(p.options[0].string_key == "foo");
199    BOOST_REQUIRE(p.options[0].value.size() == 1);
200    BOOST_CHECK(p.options[0].value[0] == "1");
201
202    //TODO: since 'bar' does not allow a value, it cannot appear in environemt,
203    // which already has a value.
204}
205
206void test_unregistered()
207{
208    options_description desc;
209
210    char* cmdline1_[] = { "--foo=12", "--bar", "1"};
211    vector<string> cmdline1 = sv(cmdline1_,
212                                 sizeof(cmdline1_)/sizeof(cmdline1_[0]));
213    vector<option> a1 = 
214        command_line_parser(cmdline1).options(desc).allow_unregistered().run()
215        .options;
216
217    BOOST_REQUIRE(a1.size() == 3);
218    BOOST_CHECK(a1[0].string_key == "foo");
219    BOOST_CHECK(a1[0].unregistered == true);
220    BOOST_REQUIRE(a1[0].value.size() == 1);
221    BOOST_CHECK(a1[0].value[0] == "12");
222    BOOST_CHECK(a1[1].string_key == "bar");
223    BOOST_CHECK(a1[1].unregistered == true);
224    BOOST_CHECK(a1[2].string_key == "");
225    BOOST_CHECK(a1[2].unregistered == false);
226   
227
228    vector<string> a2 = collect_unrecognized(a1, include_positional);
229    BOOST_CHECK(a2[0] == "--foo=12");
230    BOOST_CHECK(a2[1] == "--bar");
231    BOOST_CHECK(a2[2] == "1");
232
233    // Test that storing unregisted options has no effect
234    variables_map vm;
235   
236    store(command_line_parser(cmdline1).options(desc).
237          allow_unregistered().run(),
238          vm);
239
240    BOOST_CHECK_EQUAL(vm.size(), 0u);   
241}
242
243int test_main(int, char* [])
244{
245    test_command_line();
246    test_config_file();
247    test_environment();
248    test_unregistered();
249    return 0;
250}
251
Note: See TracBrowser for help on using the repository browser.