📄 options_description.cpp
字号:
// Copyright Vladimir Prus 2002-2004.// Copyright Bertolt Mildner 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/options_description.hpp>// FIXME: this is only to get multiple_occureces class// should move that to a separate headers.#include <boost/program_options/parsers.hpp>#include <boost/lexical_cast.hpp>#include <boost/tokenizer.hpp>#include <boost/detail/workaround.hpp>#include <boost/throw_exception.hpp>#include <cassert>#include <climits>#include <cstring>#include <cstdarg>#include <sstream>#include <iterator>using namespace std;namespace boost { namespace program_options { option_description::option_description() { } option_description:: option_description(const char* name, const value_semantic* s) : m_value_semantic(s) { this->set_name(name); } option_description:: option_description(const char* name, const value_semantic* s, const char* description) : m_description(description), m_value_semantic(s) { this->set_name(name); } option_description::~option_description() { } option_description::match_result option_description::match(const std::string& option, bool approx) const { match_result result = no_match; if (!m_long_name.empty()) { if (*m_long_name.rbegin() == '*') { // The name ends with '*'. Any specified name with the given // prefix is OK. if (option.find(m_long_name.substr(0, m_long_name.length()-1)) == 0) result = approximate_match; } if (approx) { if (m_long_name.find(option) == 0) if (m_long_name == option) result = full_match; else result = approximate_match; } else { if (m_long_name == option) result = full_match; } } if (m_short_name == option) result = full_match; return result; } const std::string& option_description::key(const std::string& option) const { if (!m_long_name.empty()) if (m_long_name.find('*') != string::npos) // The '*' character means we're long_name // matches only part of the input. So, returning // long name will remove some of the information, // and we have to return the option as specified // in the source. return option; else return m_long_name; else return m_short_name; } const std::string& option_description::long_name() const { return m_long_name; } option_description& option_description::set_name(const char* _name) { std::string name(_name); string::size_type n = name.find(','); if (n != string::npos) { assert(n == name.size()-2); m_long_name = name.substr(0, n); m_short_name = '-' + name.substr(n+1,1); } else { m_long_name = name; } return *this; } const std::string& option_description::description() const { return m_description; } shared_ptr<const value_semantic> option_description::semantic() const { return m_value_semantic; } std::string option_description::format_name() const { if (!m_short_name.empty()) return string(m_short_name).append(" [ --"). append(m_long_name).append(" ]"); else return string("--").append(m_long_name); } std::string option_description::format_parameter() const { if (m_value_semantic->max_tokens() != 0) return m_value_semantic->name(); else return ""; } options_description_easy_init:: options_description_easy_init(options_description* owner) : owner(owner) {} options_description_easy_init& options_description_easy_init:: operator()(const char* name, const char* description) { // Create untypes semantic which accepts zero tokens: i.e. // no value can be specified on command line. // FIXME: does not look exception-safe shared_ptr<option_description> d( new option_description(name, new untyped_value(true), description)); owner->add(d); return *this; } options_description_easy_init& options_description_easy_init:: operator()(const char* name, const value_semantic* s) { shared_ptr<option_description> d(new option_description(name, s)); owner->add(d); return *this; } options_description_easy_init& options_description_easy_init:: operator()(const char* name, const value_semantic* s, const char* description) { shared_ptr<option_description> d(new option_description(name, s, description)); owner->add(d); return *this; } const unsigned options_description::m_default_line_length = 80; options_description::options_description(unsigned line_length) : m_line_length(line_length) {} options_description::options_description(const string& caption, unsigned line_length) : m_caption(caption), m_line_length(line_length) {} void options_description::add(shared_ptr<option_description> desc) { m_options.push_back(desc); belong_to_group.push_back(false); } options_description& options_description::add(const options_description& desc) { shared_ptr<options_description> d(new options_description(desc)); groups.push_back(d); for (size_t i = 0; i < desc.m_options.size(); ++i) { add(desc.m_options[i]); belong_to_group.back() = true; } return *this; } options_description_easy_init options_description::add_options() { return options_description_easy_init(this); } const option_description& options_description::find(const std::string& name, bool approx) const { const option_description* d = find_nothrow(name, approx); if (!d) boost::throw_exception(unknown_option(name)); return *d; } const std::vector< shared_ptr<option_description> >& options_description::options() const { return m_options; } const option_description* options_description::find_nothrow(const std::string& name, bool approx) const { shared_ptr<option_description> found; vector<string> approximate_matches; // We use linear search because matching specified option // name with the declared option name need to take care about // case sensitivity and trailing '*' and so we can't use simple map. for(unsigned i = 0; i < m_options.size(); ++i) { option_description::match_result r = m_options[i]->match(name, approx); if (r == option_description::no_match) continue; // If we have a full patch, and an approximate match, // ignore approximate match instead of reporting error. // Say, if we have options "all" and "all-chroots", then // "--all" on the command line should select the first one, // without ambiguity. //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -