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
|
---|