]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/program_options/src/parsers.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / program_options / src / parsers.cpp
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/config.hpp>
8
9 #define BOOST_PROGRAM_OPTIONS_SOURCE
10 #include <boost/program_options/config.hpp>
11 #include <boost/program_options/parsers.hpp>
12 #include <boost/program_options/options_description.hpp>
13 #include <boost/program_options/positional_options.hpp>
14 #include <boost/program_options/detail/cmdline.hpp>
15 #include <boost/program_options/detail/config_file.hpp>
16 #include <boost/program_options/environment_iterator.hpp>
17 #include <boost/program_options/detail/convert.hpp>
18
19 #include <boost/bind.hpp>
20 #include <boost/throw_exception.hpp>
21
22 #include <cctype>
23 #include <fstream>
24
25 #if !defined(__GNUC__) || __GNUC__ < 3
26 #include <iostream>
27 #else
28 #include <istream>
29 #endif
30
31 #ifdef _WIN32
32 #include <stdlib.h>
33 #else
34 #include <unistd.h>
35 #endif
36
37 // The 'environ' should be declared in some cases. E.g. Linux man page says:
38 // (This variable must be declared in the user program, but is declared in
39 // the header file unistd.h in case the header files came from libc4 or libc5,
40 // and in case they came from glibc and _GNU_SOURCE was defined.)
41 // To be safe, declare it here.
42
43 // It appears that on Mac OS X the 'environ' variable is not
44 // available to dynamically linked libraries.
45 // See: http://article.gmane.org/gmane.comp.lib.boost.devel/103843
46 // See: http://lists.gnu.org/archive/html/bug-guile/2004-01/msg00013.html
47 #if defined(__APPLE__) && defined(__DYNAMIC__)
48 // The proper include for this is crt_externs.h, however it's not
49 // available on iOS. The right replacement is not known. See
50 // https://svn.boost.org/trac/boost/ticket/5053
51 extern "C" { extern char ***_NSGetEnviron(void); }
52 #define environ (*_NSGetEnviron())
53 #else
54 #if defined(__MWERKS__)
55 #include <crtl.h>
56 #else
57 #if !defined(_WIN32) || defined(__COMO_VERSION__)
58 extern char** environ;
59 #endif
60 #endif
61 #endif
62
63 using namespace std;
64
65 namespace boost { namespace program_options {
66
67 #ifndef BOOST_NO_STD_WSTRING
68 namespace {
69 woption woption_from_option(const option& opt)
70 {
71 woption result;
72 result.string_key = opt.string_key;
73 result.position_key = opt.position_key;
74 result.unregistered = opt.unregistered;
75
76 std::transform(opt.value.begin(), opt.value.end(),
77 back_inserter(result.value),
78 boost::bind(from_utf8, _1));
79
80 std::transform(opt.original_tokens.begin(),
81 opt.original_tokens.end(),
82 back_inserter(result.original_tokens),
83 boost::bind(from_utf8, _1));
84 return result;
85 }
86 }
87
88 basic_parsed_options<wchar_t>
89 ::basic_parsed_options(const parsed_options& po)
90 : description(po.description),
91 utf8_encoded_options(po),
92 m_options_prefix(po.m_options_prefix)
93 {
94 for (unsigned i = 0; i < po.options.size(); ++i)
95 options.push_back(woption_from_option(po.options[i]));
96 }
97 #endif
98
99 template<class charT>
100 basic_parsed_options<charT>
101 parse_config_file(std::basic_istream<charT>& is,
102 const options_description& desc,
103 bool allow_unregistered)
104 {
105 set<string> allowed_options;
106
107 const vector<shared_ptr<option_description> >& options = desc.options();
108 for (unsigned i = 0; i < options.size(); ++i)
109 {
110 const option_description& d = *options[i];
111
112 if (d.long_name().empty())
113 boost::throw_exception(
114 error("abbreviated option names are not permitted in options configuration files"));
115
116 allowed_options.insert(d.long_name());
117 }
118
119 // Parser return char strings
120 parsed_options result(&desc);
121 copy(detail::basic_config_file_iterator<charT>(
122 is, allowed_options, allow_unregistered),
123 detail::basic_config_file_iterator<charT>(),
124 back_inserter(result.options));
125 // Convert char strings into desired type.
126 return basic_parsed_options<charT>(result);
127 }
128
129 template
130 BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<char>
131 parse_config_file(std::basic_istream<char>& is,
132 const options_description& desc,
133 bool allow_unregistered);
134
135 #ifndef BOOST_NO_STD_WSTRING
136 template
137 BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<wchar_t>
138 parse_config_file(std::basic_istream<wchar_t>& is,
139 const options_description& desc,
140 bool allow_unregistered);
141 #endif
142
143 template<class charT>
144 basic_parsed_options<charT>
145 parse_config_file(const char* filename,
146 const options_description& desc,
147 bool allow_unregistered)
148 {
149 // Parser return char strings
150 std::basic_ifstream< charT > strm(filename);
151 if (!strm)
152 {
153 boost::throw_exception(reading_file(filename));
154 }
155 return parse_config_file(strm, desc, allow_unregistered);
156 }
157
158 template
159 BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<char>
160 parse_config_file(const char* filename,
161 const options_description& desc,
162 bool allow_unregistered);
163
164 #ifndef BOOST_NO_STD_WSTRING
165 template
166 BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<wchar_t>
167 parse_config_file(const char* filename,
168 const options_description& desc,
169 bool allow_unregistered);
170 #endif
171
172
173 // This versio, which accepts any options without validation, is disabled,
174 // in the hope that nobody will need it and we cant drop it altogether.
175 // Besides, probably the right way to handle all options is the '*' name.
176 #if 0
177 BOOST_PROGRAM_OPTIONS_DECL parsed_options
178 parse_config_file(std::istream& is)
179 {
180 detail::config_file_iterator cf(is, false);
181 parsed_options result(0);
182 copy(cf, detail::config_file_iterator(),
183 back_inserter(result.options));
184 return result;
185 }
186 #endif
187
188 BOOST_PROGRAM_OPTIONS_DECL parsed_options
189 parse_environment(const options_description& desc,
190 const function1<std::string, std::string>& name_mapper)
191 {
192 parsed_options result(&desc);
193
194 for(environment_iterator i(environ), e; i != e; ++i) {
195 string option_name = name_mapper(i->first);
196
197 if (!option_name.empty()) {
198 option n;
199 n.string_key = option_name;
200 n.value.push_back(i->second);
201 result.options.push_back(n);
202 }
203 }
204
205 return result;
206 }
207
208 namespace detail {
209 class prefix_name_mapper {
210 public:
211 prefix_name_mapper(const std::string& prefix)
212 : prefix(prefix)
213 {}
214
215 std::string operator()(const std::string& s)
216 {
217 string result;
218 if (s.find(prefix) == 0) {
219 for(string::size_type n = prefix.size(); n < s.size(); ++n)
220 {
221 // Intel-Win-7.1 does not understand
222 // push_back on string.
223 result += static_cast<char>(tolower(s[n]));
224 }
225 }
226 return result;
227 }
228 private:
229 std::string prefix;
230 };
231 }
232
233 BOOST_PROGRAM_OPTIONS_DECL parsed_options
234 parse_environment(const options_description& desc,
235 const std::string& prefix)
236 {
237 return parse_environment(desc, detail::prefix_name_mapper(prefix));
238 }
239
240 BOOST_PROGRAM_OPTIONS_DECL parsed_options
241 parse_environment(const options_description& desc, const char* prefix)
242 {
243 return parse_environment(desc, string(prefix));
244 }
245
246
247
248
249 }}