diff options
Diffstat (limited to '3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp')
-rw-r--r-- | 3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp b/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp new file mode 100644 index 0000000..f5770f1 --- /dev/null +++ b/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp @@ -0,0 +1,335 @@ +// Copyright Vladimir Prus 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/value_semantic.hpp> +#include <boost/program_options/detail/convert.hpp> + +#include <cctype> + +namespace boost { namespace program_options { + + using namespace std; + + void + value_semantic_codecvt_helper<char>:: + parse(boost::any& value_store, + const std::vector<std::string>& new_tokens, + bool utf8) const + { + if (utf8) { +#ifndef BOOST_NO_STD_WSTRING + // Need to convert to local encoding. + std::vector<string> local_tokens; + for (unsigned i = 0; i < new_tokens.size(); ++i) { + std::wstring w = from_utf8(new_tokens[i]); + local_tokens.push_back(to_local_8_bit(w)); + } + xparse(value_store, local_tokens); +#else + boost::throw_exception( + std::runtime_error("UTF-8 conversion not supported.")); +#endif + } else { + // Already in local encoding, pass unmodified + xparse(value_store, new_tokens); + } + } + +#ifndef BOOST_NO_STD_WSTRING + void + value_semantic_codecvt_helper<wchar_t>:: + parse(boost::any& value_store, + const std::vector<std::string>& new_tokens, + bool utf8) const + { + std::vector<wstring> tokens; + if (utf8) { + // Convert from utf8 + for (unsigned i = 0; i < new_tokens.size(); ++i) { + tokens.push_back(from_utf8(new_tokens[i])); + } + + } else { + // Convert from local encoding + for (unsigned i = 0; i < new_tokens.size(); ++i) { + tokens.push_back(from_local_8_bit(new_tokens[i])); + } + } + + xparse(value_store, tokens); + } +#endif + + BOOST_PROGRAM_OPTIONS_DECL std::string arg("arg"); + + std::string + untyped_value::name() const + { + return arg; + } + + unsigned + untyped_value::min_tokens() const + { + if (m_zero_tokens) + return 0; + else + return 1; + } + + unsigned + untyped_value::max_tokens() const + { + if (m_zero_tokens) + return 0; + else + return 1; + } + + + void + untyped_value::xparse(boost::any& value_store, + const std::vector<std::string>& new_tokens) const + { + if (!value_store.empty()) + boost::throw_exception( + multiple_occurrences()); + if (new_tokens.size() > 1) + boost::throw_exception(multiple_values()); + value_store = new_tokens.empty() ? std::string("") : new_tokens.front(); + } + + BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>* + bool_switch() + { + return bool_switch(0); + } + + BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>* + bool_switch(bool* v) + { + typed_value<bool>* r = new typed_value<bool>(v); + r->default_value(0); + r->zero_tokens(); + + return r; + } + + /* Validates bool value. + Any of "1", "true", "yes", "on" will be converted to "1".<br> + Any of "0", "false", "no", "off" will be converted to "0".<br> + Case is ignored. The 'xs' vector can either be empty, in which + case the value is 'true', or can contain explicit value. + */ + BOOST_PROGRAM_OPTIONS_DECL void validate(any& v, const vector<string>& xs, + bool*, int) + { + check_first_occurrence(v); + string s(get_single_string(xs, true)); + + for (size_t i = 0; i < s.size(); ++i) + s[i] = char(tolower(s[i])); + + if (s.empty() || s == "on" || s == "yes" || s == "1" || s == "true") + v = any(true); + else if (s == "off" || s == "no" || s == "0" || s == "false") + v = any(false); + else + boost::throw_exception(validation_error(validation_error::invalid_bool_value, s)); + } + + // This is blatant copy-paste. However, templating this will cause a problem, + // since wstring can't be constructed/compared with char*. We'd need to + // create auxiliary 'widen' routine to convert from char* into + // needed string type, and that's more work. +#if !defined(BOOST_NO_STD_WSTRING) + BOOST_PROGRAM_OPTIONS_DECL + void validate(any& v, const vector<wstring>& xs, bool*, int) + { + check_first_occurrence(v); + wstring s(get_single_string(xs, true)); + + for (size_t i = 0; i < s.size(); ++i) + s[i] = wchar_t(tolower(s[i])); + + if (s.empty() || s == L"on" || s == L"yes" || s == L"1" || s == L"true") + v = any(true); + else if (s == L"off" || s == L"no" || s == L"0" || s == L"false") + v = any(false); + else + boost::throw_exception(validation_error(validation_error::invalid_bool_value)); + } +#endif + BOOST_PROGRAM_OPTIONS_DECL + void validate(any& v, const vector<string>& xs, std::string*, int) + { + check_first_occurrence(v); + v = any(get_single_string(xs)); + } + +#if !defined(BOOST_NO_STD_WSTRING) + BOOST_PROGRAM_OPTIONS_DECL + void validate(any& v, const vector<wstring>& xs, std::string*, int) + { + check_first_occurrence(v); + v = any(get_single_string(xs)); + } +#endif + + namespace validators { + + BOOST_PROGRAM_OPTIONS_DECL + void check_first_occurrence(const boost::any& value) + { + if (!value.empty()) + boost::throw_exception( + multiple_occurrences()); + } + } + + + invalid_option_value:: + invalid_option_value(const std::string& bad_value) + : validation_error(validation_error::invalid_option_value, bad_value) + {} + +#ifndef BOOST_NO_STD_WSTRING + namespace + { + std::string convert_value(const std::wstring& s) + { + try { + return to_local_8_bit(s); + } + catch(const std::exception&) { + return "<unrepresentable unicode string>"; + } + } + } + + invalid_option_value:: + invalid_option_value(const std::wstring& bad_value) + : validation_error(validation_error::invalid_option_value, convert_value(bad_value)) + {} +#endif + const std::string& + unknown_option::get_option_name() const throw() + { + return m_option_name; + } + + const std::string& + ambiguous_option::get_option_name() const throw() + { + return m_option_name; + } + + const std::vector<std::string>& + ambiguous_option::alternatives() const throw() + { + return m_alternatives; + } + + void + multiple_values::set_option_name(const std::string& option_name) + { + m_option_name = option_name; + } + + const std::string& + multiple_values::get_option_name() const throw() + { + return m_option_name; + } + + void + multiple_occurrences::set_option_name(const std::string& option_name) + { + m_option_name = option_name; + } + + const std::string& + multiple_occurrences::get_option_name() const throw() + { + return m_option_name; + } + + validation_error:: + validation_error(kind_t kind, + const std::string& option_value, + const std::string& option_name) + : error("") + , m_kind(kind) + , m_option_name(option_name) + , m_option_value(option_value) + , m_message(error_message(kind)) + { + if (!option_value.empty()) + { + m_message.append(std::string("'") + option_value + std::string("'")); + } + } + + void + validation_error::set_option_name(const std::string& option_name) + { + m_option_name = option_name; + } + + const std::string& + validation_error::get_option_name() const throw() + { + return m_option_name; + } + + std::string + validation_error::error_message(kind_t kind) + { + // Initially, store the message in 'const char*' variable, + // to avoid conversion to std::string in all cases. + const char* msg; + switch(kind) + { + case multiple_values_not_allowed: + msg = "multiple values not allowed"; + break; + case at_least_one_value_required: + msg = "at least one value required"; + break; + case invalid_bool_value: + msg = "invalid bool value"; + break; + case invalid_option_value: + msg = "invalid option value"; + break; + case invalid_option: + msg = "invalid option"; + break; + default: + msg = "unknown error"; + } + return msg; + } + + const char* + validation_error::what() const throw() + { + if (!m_option_name.empty()) + { + m_message = "in option '" + m_option_name + "': " + + error_message(m_kind); + } + return m_message.c_str(); + } + + const std::string& + required_option::get_option_name() const throw() + { + return m_option_name; + } + +}} |