aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/boost/libs/program_options/src/value_semantic.cpp
diff options
context:
space:
mode:
authorneksard <neksard@yandex-team.ru>2022-02-10 16:45:33 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:33 +0300
commit1d9c550e7c38e051d7961f576013a482003a70d9 (patch)
treeb2cc84ee7850122e7ccf51d0ea21e4fa7e7a5685 /contrib/restricted/boost/libs/program_options/src/value_semantic.cpp
parent8f7cf138264e0caa318144bf8a2c950e0b0a8593 (diff)
downloadydb-1d9c550e7c38e051d7961f576013a482003a70d9.tar.gz
Restoring authorship annotation for <neksard@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/restricted/boost/libs/program_options/src/value_semantic.cpp')
-rw-r--r--contrib/restricted/boost/libs/program_options/src/value_semantic.cpp850
1 files changed, 425 insertions, 425 deletions
diff --git a/contrib/restricted/boost/libs/program_options/src/value_semantic.cpp b/contrib/restricted/boost/libs/program_options/src/value_semantic.cpp
index 8951a0d2f2..6055f62713 100644
--- a/contrib/restricted/boost/libs/program_options/src/value_semantic.cpp
+++ b/contrib/restricted/boost/libs/program_options/src/value_semantic.cpp
@@ -1,428 +1,428 @@
-// 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 <boost/program_options/detail/cmdline.hpp>
-#include <set>
-
-#include <cctype>
-
-namespace boost { namespace program_options {
-
- using namespace std;
-
-
-#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>";
- }
- }
- }
-#endif
-
- 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(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(invalid_bool_value(convert_value(s)));
- }
-#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)
- {
- set_substitute("value", bad_value);
- }
-
-#ifndef BOOST_NO_STD_WSTRING
- invalid_option_value::
- invalid_option_value(const std::wstring& bad_value)
- : validation_error(validation_error::invalid_option_value)
- {
- set_substitute("value", convert_value(bad_value));
- }
-#endif
-
-
-
- invalid_bool_value::
- invalid_bool_value(const std::string& bad_value)
- : validation_error(validation_error::invalid_bool_value)
- {
- set_substitute("value", bad_value);
- }
-
-
-
-
-
-
- error_with_option_name::error_with_option_name( const std::string& template_,
- const std::string& option_name,
- const std::string& original_token,
- int option_style) :
- error(template_),
- m_option_style(option_style),
- m_error_template(template_)
- {
- // parameter | placeholder | value
- // --------- | ----------- | -----
- set_substitute_default("canonical_option", "option '%canonical_option%'", "option");
- set_substitute_default("value", "argument ('%value%')", "argument");
- set_substitute_default("prefix", "%prefix%", "");
- m_substitutions["option"] = option_name;
- m_substitutions["original_token"] = original_token;
- }
-
-
+// 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 <boost/program_options/detail/cmdline.hpp>
+#include <set>
+
+#include <cctype>
+
+namespace boost { namespace program_options {
+
+ using namespace std;
+
+
+#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>";
+ }
+ }
+ }
+#endif
+
+ 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(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(invalid_bool_value(convert_value(s)));
+ }
+#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)
+ {
+ set_substitute("value", bad_value);
+ }
+
+#ifndef BOOST_NO_STD_WSTRING
+ invalid_option_value::
+ invalid_option_value(const std::wstring& bad_value)
+ : validation_error(validation_error::invalid_option_value)
+ {
+ set_substitute("value", convert_value(bad_value));
+ }
+#endif
+
+
+
+ invalid_bool_value::
+ invalid_bool_value(const std::string& bad_value)
+ : validation_error(validation_error::invalid_bool_value)
+ {
+ set_substitute("value", bad_value);
+ }
+
+
+
+
+
+
+ error_with_option_name::error_with_option_name( const std::string& template_,
+ const std::string& option_name,
+ const std::string& original_token,
+ int option_style) :
+ error(template_),
+ m_option_style(option_style),
+ m_error_template(template_)
+ {
+ // parameter | placeholder | value
+ // --------- | ----------- | -----
+ set_substitute_default("canonical_option", "option '%canonical_option%'", "option");
+ set_substitute_default("value", "argument ('%value%')", "argument");
+ set_substitute_default("prefix", "%prefix%", "");
+ m_substitutions["option"] = option_name;
+ m_substitutions["original_token"] = original_token;
+ }
+
+
const char* error_with_option_name::what() const noexcept
- {
- // will substitute tokens each time what is run()
- substitute_placeholders(m_error_template);
-
- return m_message.c_str();
- }
-
- void error_with_option_name::replace_token(const string& from, const string& to) const
- {
- for (;;)
- {
- std::size_t pos = m_message.find(from.c_str(), 0, from.length());
- // not found: all replaced
- if (pos == std::string::npos)
- return;
- m_message.replace(pos, from.length(), to);
- }
- }
-
- string error_with_option_name::get_canonical_option_prefix() const
- {
- switch (m_option_style)
- {
- case command_line_style::allow_dash_for_short:
- return "-";
- case command_line_style::allow_slash_for_short:
- return "/";
- case command_line_style::allow_long_disguise:
- return "-";
- case command_line_style::allow_long:
- return "--";
- case 0:
- return "";
- }
- throw std::logic_error("error_with_option_name::m_option_style can only be "
- "one of [0, allow_dash_for_short, allow_slash_for_short, "
- "allow_long_disguise or allow_long]");
- }
-
-
- string error_with_option_name::get_canonical_option_name() const
- {
- if (!m_substitutions.find("option")->second.length())
- return m_substitutions.find("original_token")->second;
-
- string original_token = strip_prefixes(m_substitutions.find("original_token")->second);
- string option_name = strip_prefixes(m_substitutions.find("option")->second);
-
- // For long options, use option name
- if (m_option_style == command_line_style::allow_long ||
- m_option_style == command_line_style::allow_long_disguise)
- return get_canonical_option_prefix() + option_name;
-
- // For short options use first letter of original_token
- if (m_option_style && original_token.length())
- return get_canonical_option_prefix() + original_token[0];
-
- // no prefix
- return option_name;
- }
-
-
- void error_with_option_name::substitute_placeholders(const string& error_template) const
- {
- m_message = error_template;
- std::map<std::string, std::string> substitutions(m_substitutions);
- substitutions["canonical_option"] = get_canonical_option_name();
- substitutions["prefix"] = get_canonical_option_prefix();
-
-
+ {
+ // will substitute tokens each time what is run()
+ substitute_placeholders(m_error_template);
+
+ return m_message.c_str();
+ }
+
+ void error_with_option_name::replace_token(const string& from, const string& to) const
+ {
+ for (;;)
+ {
+ std::size_t pos = m_message.find(from.c_str(), 0, from.length());
+ // not found: all replaced
+ if (pos == std::string::npos)
+ return;
+ m_message.replace(pos, from.length(), to);
+ }
+ }
+
+ string error_with_option_name::get_canonical_option_prefix() const
+ {
+ switch (m_option_style)
+ {
+ case command_line_style::allow_dash_for_short:
+ return "-";
+ case command_line_style::allow_slash_for_short:
+ return "/";
+ case command_line_style::allow_long_disguise:
+ return "-";
+ case command_line_style::allow_long:
+ return "--";
+ case 0:
+ return "";
+ }
+ throw std::logic_error("error_with_option_name::m_option_style can only be "
+ "one of [0, allow_dash_for_short, allow_slash_for_short, "
+ "allow_long_disguise or allow_long]");
+ }
+
+
+ string error_with_option_name::get_canonical_option_name() const
+ {
+ if (!m_substitutions.find("option")->second.length())
+ return m_substitutions.find("original_token")->second;
+
+ string original_token = strip_prefixes(m_substitutions.find("original_token")->second);
+ string option_name = strip_prefixes(m_substitutions.find("option")->second);
+
+ // For long options, use option name
+ if (m_option_style == command_line_style::allow_long ||
+ m_option_style == command_line_style::allow_long_disguise)
+ return get_canonical_option_prefix() + option_name;
+
+ // For short options use first letter of original_token
+ if (m_option_style && original_token.length())
+ return get_canonical_option_prefix() + original_token[0];
+
+ // no prefix
+ return option_name;
+ }
+
+
+ void error_with_option_name::substitute_placeholders(const string& error_template) const
+ {
+ m_message = error_template;
+ std::map<std::string, std::string> substitutions(m_substitutions);
+ substitutions["canonical_option"] = get_canonical_option_name();
+ substitutions["prefix"] = get_canonical_option_prefix();
+
+
+ //
+ // replace placeholder with defaults if values are missing
//
- // replace placeholder with defaults if values are missing
- //
- for (map<string, string_pair>::const_iterator iter = m_substitution_defaults.begin();
- iter != m_substitution_defaults.end(); ++iter)
- {
- // missing parameter: use default
- if (substitutions.count(iter->first) == 0 ||
- substitutions[iter->first].length() == 0)
- replace_token(iter->second.first, iter->second.second);
- }
-
-
+ for (map<string, string_pair>::const_iterator iter = m_substitution_defaults.begin();
+ iter != m_substitution_defaults.end(); ++iter)
+ {
+ // missing parameter: use default
+ if (substitutions.count(iter->first) == 0 ||
+ substitutions[iter->first].length() == 0)
+ replace_token(iter->second.first, iter->second.second);
+ }
+
+
+ //
+ // replace placeholder with values
+ // placeholder are denoted by surrounding '%'
//
- // replace placeholder with values
- // placeholder are denoted by surrounding '%'
- //
- for (map<string, string>::iterator iter = substitutions.begin();
- iter != substitutions.end(); ++iter)
- replace_token('%' + iter->first + '%', iter->second);
- }
-
-
- void ambiguous_option::substitute_placeholders(const string& original_error_template) const
- {
- // For short forms, all alternatives must be identical, by
- // definition, to the specified option, so we don't need to
- // display alternatives
- if (m_option_style == command_line_style::allow_dash_for_short ||
- m_option_style == command_line_style::allow_slash_for_short)
- {
- error_with_option_name::substitute_placeholders(original_error_template);
- return;
- }
-
-
- string error_template = original_error_template;
- // remove duplicates using std::set
- std::set<std::string> alternatives_set (m_alternatives.begin(), m_alternatives.end());
- std::vector<std::string> alternatives_vec (alternatives_set.begin(), alternatives_set.end());
-
- error_template += " and matches ";
- // Being very cautious: should be > 1 alternative!
- if (alternatives_vec.size() > 1)
- {
- for (unsigned i = 0; i < alternatives_vec.size() - 1; ++i)
- error_template += "'%prefix%" + alternatives_vec[i] + "', ";
- error_template += "and ";
- }
-
- // there is a programming error if multiple options have the same name...
- if (m_alternatives.size() > 1 && alternatives_vec.size() == 1)
- error_template += "different versions of ";
-
- error_template += "'%prefix%" + alternatives_vec.back() + "'";
-
-
- // use inherited logic
- error_with_option_name::substitute_placeholders(error_template);
- }
-
-
-
-
-
-
- string
- validation_error::get_template(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 invalid_bool_value:
- msg = "the argument ('%value%') for option '%canonical_option%' is invalid. Valid choices are 'on|off', 'yes|no', '1|0' and 'true|false'";
- break;
- case invalid_option_value:
- msg = "the argument ('%value%') for option '%canonical_option%' is invalid";
- break;
- case multiple_values_not_allowed:
- msg = "option '%canonical_option%' only takes a single argument";
- break;
- case at_least_one_value_required:
- msg = "option '%canonical_option%' requires at least one argument";
- break;
- // currently unused
- case invalid_option:
- msg = "option '%canonical_option%' is not valid";
- break;
- default:
- msg = "unknown error";
- }
- return msg;
- }
-
-}}
+ for (map<string, string>::iterator iter = substitutions.begin();
+ iter != substitutions.end(); ++iter)
+ replace_token('%' + iter->first + '%', iter->second);
+ }
+
+
+ void ambiguous_option::substitute_placeholders(const string& original_error_template) const
+ {
+ // For short forms, all alternatives must be identical, by
+ // definition, to the specified option, so we don't need to
+ // display alternatives
+ if (m_option_style == command_line_style::allow_dash_for_short ||
+ m_option_style == command_line_style::allow_slash_for_short)
+ {
+ error_with_option_name::substitute_placeholders(original_error_template);
+ return;
+ }
+
+
+ string error_template = original_error_template;
+ // remove duplicates using std::set
+ std::set<std::string> alternatives_set (m_alternatives.begin(), m_alternatives.end());
+ std::vector<std::string> alternatives_vec (alternatives_set.begin(), alternatives_set.end());
+
+ error_template += " and matches ";
+ // Being very cautious: should be > 1 alternative!
+ if (alternatives_vec.size() > 1)
+ {
+ for (unsigned i = 0; i < alternatives_vec.size() - 1; ++i)
+ error_template += "'%prefix%" + alternatives_vec[i] + "', ";
+ error_template += "and ";
+ }
+
+ // there is a programming error if multiple options have the same name...
+ if (m_alternatives.size() > 1 && alternatives_vec.size() == 1)
+ error_template += "different versions of ";
+
+ error_template += "'%prefix%" + alternatives_vec.back() + "'";
+
+
+ // use inherited logic
+ error_with_option_name::substitute_placeholders(error_template);
+ }
+
+
+
+
+
+
+ string
+ validation_error::get_template(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 invalid_bool_value:
+ msg = "the argument ('%value%') for option '%canonical_option%' is invalid. Valid choices are 'on|off', 'yes|no', '1|0' and 'true|false'";
+ break;
+ case invalid_option_value:
+ msg = "the argument ('%value%') for option '%canonical_option%' is invalid";
+ break;
+ case multiple_values_not_allowed:
+ msg = "option '%canonical_option%' only takes a single argument";
+ break;
+ case at_least_one_value_required:
+ msg = "option '%canonical_option%' requires at least one argument";
+ break;
+ // currently unused
+ case invalid_option:
+ msg = "option '%canonical_option%' is not valid";
+ break;
+ default:
+ msg = "unknown error";
+ }
+ return msg;
+ }
+
+}}