diff options
Diffstat (limited to 'src/third_party/boost-1.69.0/libs/program_options/src/config_file.cpp')
-rw-r--r-- | src/third_party/boost-1.69.0/libs/program_options/src/config_file.cpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src/third_party/boost-1.69.0/libs/program_options/src/config_file.cpp b/src/third_party/boost-1.69.0/libs/program_options/src/config_file.cpp new file mode 100644 index 00000000000..f2a57b4b829 --- /dev/null +++ b/src/third_party/boost-1.69.0/libs/program_options/src/config_file.cpp @@ -0,0 +1,198 @@ +// Copyright Vladimir Prus 2002-2004. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#define BOOST_PROGRAM_OPTIONS_SOURCE +#include <boost/program_options/config.hpp> + +#include <boost/program_options/detail/config_file.hpp> +#include <boost/program_options/errors.hpp> +#include <boost/program_options/detail/convert.hpp> +#include <boost/throw_exception.hpp> + +#include <iostream> +#include <fstream> +#include <cassert> + +namespace boost { namespace program_options { namespace detail { + + using namespace std; + + common_config_file_iterator::common_config_file_iterator( + const std::set<std::string>& allowed_options, + bool allow_unregistered) + : allowed_options(allowed_options), + m_allow_unregistered(allow_unregistered) + { + for(std::set<std::string>::const_iterator i = allowed_options.begin(); + i != allowed_options.end(); + ++i) + { + add_option(i->c_str()); + } + } + + void + common_config_file_iterator::add_option(const char* name) + { + string s(name); + assert(!s.empty()); + if (*s.rbegin() == '*') { + s.resize(s.size()-1); + bool bad_prefixes(false); + // If 's' is a prefix of one of allowed suffix, then + // lower_bound will return that element. + // If some element is prefix of 's', then lower_bound will + // return the next element. + set<string>::iterator i = allowed_prefixes.lower_bound(s); + if (i != allowed_prefixes.end()) { + if (i->find(s) == 0) + bad_prefixes = true; + } + if (i != allowed_prefixes.begin()) { + --i; + if (s.find(*i) == 0) + bad_prefixes = true; + } + if (bad_prefixes) + boost::throw_exception(error("options '" + string(name) + "' and '" + + *i + "*' will both match the same " + "arguments from the configuration file")); + allowed_prefixes.insert(s); + } + } + + namespace { + string trim_ws(const string& s) + { + string::size_type n, n2; + n = s.find_first_not_of(" \t\r\n"); + if (n == string::npos) + return string(); + else { + n2 = s.find_last_not_of(" \t\r\n"); + return s.substr(n, n2-n+1); + } + } + } + + + void common_config_file_iterator::get() + { + string s; + string::size_type n; + bool found = false; + + while(this->getline(s)) { + + // strip '#' comments and whitespace + if ((n = s.find('#')) != string::npos) + s = s.substr(0, n); + s = trim_ws(s); + + if (!s.empty()) { + // Handle section name + if (*s.begin() == '[' && *s.rbegin() == ']') { + m_prefix = s.substr(1, s.size()-2); + if (*m_prefix.rbegin() != '.') + m_prefix += '.'; + } + else if ((n = s.find('=')) != string::npos) { + + string name = m_prefix + trim_ws(s.substr(0, n)); + string value = trim_ws(s.substr(n+1)); + + bool registered = allowed_option(name); + if (!registered && !m_allow_unregistered) + boost::throw_exception(unknown_option(name)); + + found = true; + this->value().string_key = name; + this->value().value.clear(); + this->value().value.push_back(value); + this->value().unregistered = !registered; + this->value().original_tokens.clear(); + this->value().original_tokens.push_back(name); + this->value().original_tokens.push_back(value); + break; + + } else { + boost::throw_exception(invalid_config_file_syntax(s, invalid_syntax::unrecognized_line)); + } + } + } + if (!found) + found_eof(); + } + + + bool + common_config_file_iterator::allowed_option(const std::string& s) const + { + set<string>::const_iterator i = allowed_options.find(s); + if (i != allowed_options.end()) + return true; + // If s is "pa" where "p" is allowed prefix then + // lower_bound should find the element after "p". + // This depends on 'allowed_prefixes' invariant. + i = allowed_prefixes.lower_bound(s); + if (i != allowed_prefixes.begin() && s.find(*--i) == 0) + return true; + return false; + } + +#if BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4303)) || \ + (defined(__sgi) && BOOST_WORKAROUND(_COMPILER_VERSION, BOOST_TESTED_AT(741))) + template<> + bool + basic_config_file_iterator<wchar_t>::getline(std::string& s) + { + std::wstring ws; + // On Comeau, using two-argument version causes + // call to some internal function with std::wstring, and '\n' + // (not L'\n') and compile can't resolve that call. + + if (std::getline(*is, ws, L'\n')) { + s = to_utf8(ws); + return true; + } else { + return false; + } + } +#endif + +}}} + +#if 0 +using boost::program_options::config_file; + +#include <sstream> +#include <cassert> + +int main() +{ + try { + stringstream s( + "a = 1\n" + "b = 2\n"); + + config_file cf(s); + cf.add_option("a"); + cf.add_option("b"); + + assert(++cf); + assert(cf.name() == "a"); + assert(cf.value() == "1"); + assert(++cf); + assert(cf.name() == "b"); + assert(cf.value() == "2"); + assert(!++cf); + } + catch(exception& e) + { + cout << e.what() << "\n"; + } +} +#endif |