1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
|
// 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)
#ifndef BOOST_OPTION_DESCRIPTION_VP_2003_05_19
#define BOOST_OPTION_DESCRIPTION_VP_2003_05_19
#include <boost/program_options/config.hpp>
#include <boost/program_options/errors.hpp>
#include <boost/program_options/value_semantic.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/any.hpp>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stdexcept>
#include <iosfwd>
#if defined(BOOST_MSVC)
# pragma warning (push)
# pragma warning (disable:4251) // class 'boost::shared_ptr<T>' needs to have dll-interface to be used by clients of class 'boost::program_options::option_description'
#endif
/** Boost namespace */
namespace boost {
/** Namespace for the library. */
namespace program_options {
/** Describes one possible command line/config file option. There are two
kinds of properties of an option. First describe it syntactically and
are used only to validate input. Second affect interpretation of the
option, for example default value for it or function that should be
called when the value is finally known. Routines which perform parsing
never use second kind of properties -- they are side effect free.
@sa options_description
*/
class BOOST_PROGRAM_OPTIONS_DECL option_description {
public:
option_description();
/** Initializes the object with the passed data.
Note: it would be nice to make the second parameter auto_ptr,
to explicitly pass ownership. Unfortunately, it's often needed to
create objects of types derived from 'value_semantic':
options_description d;
d.add_options()("a", parameter<int>("n")->default_value(1));
Here, the static type returned by 'parameter' should be derived
from value_semantic.
Alas, derived->base conversion for auto_ptr does not really work,
see
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2000/n1232.pdf
http://std.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#84
So, we have to use plain old pointers. Besides, users are not
expected to use the constructor directly.
The 'name' parameter is interpreted by the following rules:
- if there's no "," character in 'name', it specifies long name
- otherwise, the part before "," specifies long name and the part
after -- short name.
*/
option_description(const char* name,
const value_semantic* s);
/** Initializes the class with the passed data.
*/
option_description(const char* name,
const value_semantic* s,
const char* description);
virtual ~option_description();
enum match_result { no_match, full_match, approximate_match };
/** Given 'option', specified in the input source,
returns 'true' if 'option' specifies *this.
*/
match_result match(const std::string& option, bool approx,
bool long_ignore_case, bool short_ignore_case) const;
/** Returns the key that should identify the option, in
particular in the variables_map class.
The 'option' parameter is the option spelling from the
input source.
If option name contains '*', returns 'option'.
If long name was specified, it's the long name, otherwise
it's a short name with prepended '-'.
*/
const std::string& key(const std::string& option) const;
const std::string& long_name() const;
/// Explanation of this option
const std::string& description() const;
/// Semantic of option's value
shared_ptr<const value_semantic> semantic() const;
/// Returns the option name, formatted suitably for usage message.
std::string format_name() const;
/** Returns the parameter name and properties, formatted suitably for
usage message. */
std::string format_parameter() const;
private:
option_description& set_name(const char* name);
std::string m_short_name, m_long_name, m_description;
// shared_ptr is needed to simplify memory management in
// copy ctor and destructor.
shared_ptr<const value_semantic> m_value_semantic;
};
class options_description;
/** Class which provides convenient creation syntax to option_description.
*/
class BOOST_PROGRAM_OPTIONS_DECL options_description_easy_init {
public:
options_description_easy_init(options_description* owner);
options_description_easy_init&
operator()(const char* name,
const char* description);
options_description_easy_init&
operator()(const char* name,
const value_semantic* s);
options_description_easy_init&
operator()(const char* name,
const value_semantic* s,
const char* description);
private:
options_description* owner;
};
/** A set of option descriptions. This provides convenient interface for
adding new option (the add_options) method, and facilities to search
for options by name.
See @ref a_adding_options "here" for option adding interface discussion.
@sa option_description
*/
class BOOST_PROGRAM_OPTIONS_DECL options_description {
public:
static const unsigned m_default_line_length;
/** Creates the instance. */
options_description(unsigned line_length = m_default_line_length,
unsigned min_description_length = m_default_line_length / 2);
/** Creates the instance. The 'caption' parameter gives the name of
this 'options_description' instance. Primarily useful for output.
The 'description_length' specifies the number of columns that
should be reserved for the description text; if the option text
encroaches into this, then the description will start on the next
line.
*/
options_description(const std::string& caption,
unsigned line_length = m_default_line_length,
unsigned min_description_length = m_default_line_length / 2);
/** Adds new variable description. Throws duplicate_variable_error if
either short or long name matches that of already present one.
*/
void add(shared_ptr<option_description> desc);
/** Adds a group of option description. This has the same
effect as adding all option_descriptions in 'desc'
individually, except that output operator will show
a separate group.
Returns *this.
*/
options_description& add(const options_description& desc);
public:
/** Returns an object of implementation-defined type suitable for adding
options to options_description. The returned object will
have overloaded operator() with parameter type matching
'option_description' constructors. Calling the operator will create
new option_description instance and add it.
*/
options_description_easy_init add_options();
const option_description& find(const std::string& name,
bool approx,
bool long_ignore_case = false,
bool short_ignore_case = false) const;
const option_description* find_nothrow(const std::string& name,
bool approx,
bool long_ignore_case = false,
bool short_ignore_case = false) const;
const std::vector< shared_ptr<option_description> >& options() const;
/** Produces a human readable output of 'desc', listing options,
their descriptions and allowed parameters. Other options_description
instances previously passed to add will be output separately. */
friend BOOST_PROGRAM_OPTIONS_DECL std::ostream& operator<<(std::ostream& os,
const options_description& desc);
/** Outputs 'desc' to the specified stream, calling 'f' to output each
option_description element. */
void print(std::ostream& os) const;
private:
typedef std::map<std::string, int>::const_iterator name2index_iterator;
typedef std::pair<name2index_iterator, name2index_iterator>
approximation_range;
//approximation_range find_approximation(const std::string& prefix) const;
std::string m_caption;
const unsigned m_line_length;
const unsigned m_min_description_length;
// Data organization is chosen because:
// - there could be two names for one option
// - option_add_proxy needs to know the last added option
std::vector< shared_ptr<option_description> > m_options;
// Whether the option comes from one of declared groups.
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(313))
// vector<bool> is buggy there, see
// http://support.microsoft.com/default.aspx?scid=kb;en-us;837698
std::vector<char> belong_to_group;
#else
std::vector<bool> belong_to_group;
#endif
std::vector< shared_ptr<options_description> > groups;
};
/** Class thrown when duplicate option description is found. */
class BOOST_PROGRAM_OPTIONS_DECL duplicate_option_error : public error {
public:
duplicate_option_error(const std::string& xwhat) : error(xwhat) {}
};
}}
#if defined(BOOST_MSVC)
# pragma warning (pop)
#endif
#endif
|