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