]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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/variables_map.hpp> | |
8 | #include <boost/program_options/options_description.hpp> | |
9 | #include <boost/program_options/parsers.hpp> | |
10 | #include <boost/program_options/detail/utf8_codecvt_facet.hpp> | |
11 | using namespace boost::program_options; | |
12 | // We'll use po::value everywhere to workaround vc6 bug. | |
13 | namespace po = boost::program_options; | |
14 | ||
15 | #include <boost/function.hpp> | |
16 | using namespace boost; | |
17 | ||
18 | #include <sstream> | |
19 | using namespace std; | |
20 | ||
21 | #include "minitest.hpp" | |
22 | ||
23 | // Test that unicode input is forwarded to unicode option without | |
24 | // problems. | |
25 | void test_unicode_to_unicode() | |
26 | { | |
27 | options_description desc; | |
28 | ||
29 | desc.add_options() | |
30 | ("foo", po::wvalue<wstring>(), "unicode option") | |
31 | ; | |
32 | ||
33 | vector<wstring> args; | |
34 | args.push_back(L"--foo=\x044F"); | |
35 | ||
36 | variables_map vm; | |
37 | basic_parsed_options<wchar_t> parsed = | |
38 | wcommand_line_parser(args).options(desc).run(); | |
39 | store(parsed, vm); | |
40 | ||
41 | BOOST_CHECK(vm["foo"].as<wstring>() == L"\x044F"); | |
42 | BOOST_CHECK(parsed.options[0].original_tokens.size() == 1); | |
43 | BOOST_CHECK(parsed.options[0].original_tokens[0] == L"--foo=\x044F"); | |
44 | } | |
45 | ||
46 | // Test that unicode input is property converted into | |
47 | // local 8 bit string. To test this, make local 8 bit encoding | |
48 | // be utf8. | |
49 | void test_unicode_to_native() | |
50 | { | |
51 | std::codecvt<wchar_t, char, mbstate_t>* facet = | |
52 | new boost::program_options::detail::utf8_codecvt_facet; | |
53 | locale::global(locale(locale(), facet)); | |
54 | ||
55 | options_description desc; | |
56 | ||
57 | desc.add_options() | |
58 | ("foo", po::value<string>(), "unicode option") | |
59 | ; | |
60 | ||
61 | vector<wstring> args; | |
62 | args.push_back(L"--foo=\x044F"); | |
63 | ||
64 | variables_map vm; | |
65 | store(wcommand_line_parser(args).options(desc).run(), vm); | |
66 | ||
67 | BOOST_CHECK(vm["foo"].as<string>() == "\xD1\x8F"); | |
68 | } | |
69 | ||
70 | void test_native_to_unicode() | |
71 | { | |
72 | std::codecvt<wchar_t, char, mbstate_t>* facet = | |
73 | new boost::program_options::detail::utf8_codecvt_facet; | |
74 | locale::global(locale(locale(), facet)); | |
75 | ||
76 | options_description desc; | |
77 | ||
78 | desc.add_options() | |
79 | ("foo", po::wvalue<wstring>(), "unicode option") | |
80 | ; | |
81 | ||
82 | vector<string> args; | |
83 | args.push_back("--foo=\xD1\x8F"); | |
84 | ||
85 | variables_map vm; | |
86 | store(command_line_parser(args).options(desc).run(), vm); | |
87 | ||
88 | BOOST_CHECK(vm["foo"].as<wstring>() == L"\x044F"); | |
89 | } | |
90 | ||
91 | vector<wstring> sv(const wchar_t* array[], unsigned size) | |
92 | { | |
93 | vector<wstring> r; | |
94 | for (unsigned i = 0; i < size; ++i) | |
95 | r.push_back(array[i]); | |
96 | return r; | |
97 | } | |
98 | ||
99 | void check_value(const woption& option, const char* name, const wchar_t* value) | |
100 | { | |
101 | BOOST_CHECK(option.string_key == name); | |
102 | BOOST_REQUIRE(option.value.size() == 1); | |
103 | BOOST_CHECK(option.value.front() == value); | |
104 | } | |
105 | ||
106 | void test_command_line() | |
107 | { | |
108 | options_description desc; | |
109 | desc.add_options() | |
110 | ("foo,f", new untyped_value(), "") | |
111 | // Explicit qualification is a workaround for vc6 | |
112 | ("bar,b", po::value<std::string>(), "") | |
113 | ("baz", new untyped_value()) | |
92f5a8d4 | 114 | ("qux,plug*", new untyped_value()) |
7c673cae FG |
115 | ; |
116 | ||
117 | const wchar_t* cmdline4_[] = { L"--foo=1\u0FF52", L"-f4", L"--bar=11", | |
118 | L"-b4", L"--plug3=10"}; | |
119 | vector<wstring> cmdline4 = sv(cmdline4_, | |
120 | sizeof(cmdline4_)/sizeof(cmdline4_[0])); | |
121 | vector<woption> a4 = | |
122 | wcommand_line_parser(cmdline4).options(desc).run().options; | |
123 | ||
124 | BOOST_REQUIRE(a4.size() == 5); | |
125 | ||
126 | check_value(a4[0], "foo", L"1\u0FF52"); | |
127 | check_value(a4[1], "foo", L"4"); | |
128 | check_value(a4[2], "bar", L"11"); | |
92f5a8d4 | 129 | check_value(a4[4], "qux", L"10"); |
7c673cae FG |
130 | } |
131 | ||
132 | // Since we've already tested conversion between parser encoding and | |
133 | // option encoding, all we need to check for config file is that | |
134 | // when reading wistream, it generates proper UTF8 data. | |
135 | void test_config_file() | |
136 | { | |
137 | std::codecvt<wchar_t, char, mbstate_t>* facet = | |
138 | new boost::program_options::detail::utf8_codecvt_facet; | |
139 | locale::global(locale(locale(), facet)); | |
140 | ||
141 | options_description desc; | |
142 | ||
143 | desc.add_options() | |
144 | ("foo", po::value<string>(), "unicode option") | |
145 | ; | |
146 | ||
147 | std::wstringstream stream(L"foo = \x044F"); | |
148 | ||
149 | variables_map vm; | |
150 | store(parse_config_file(stream, desc), vm); | |
151 | ||
152 | BOOST_CHECK(vm["foo"].as<string>() == "\xD1\x8F"); | |
153 | } | |
154 | ||
155 | int main(int, char* []) | |
156 | { | |
157 | test_unicode_to_unicode(); | |
158 | test_unicode_to_native(); | |
159 | test_native_to_unicode(); | |
160 | test_command_line(); | |
161 | test_config_file(); | |
162 | return 0; | |
163 | } | |
164 |