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 | enum match_result { no_match, full_match, approximate_match }; |
---|
82 | |
---|
83 | /** Given 'option', specified in the input source, |
---|
84 | return 'true' is 'option' specifies *this. |
---|
85 | */ |
---|
86 | match_result match(const std::string& option, bool approx) const; |
---|
87 | |
---|
88 | /** Return the key that should identify the option, in |
---|
89 | particular in the variables_map class. |
---|
90 | The 'option' parameter is the option spelling from the |
---|
91 | input source. |
---|
92 | If option name contains '*', returns 'option'. |
---|
93 | If long name was specified, it's the long name, otherwise |
---|
94 | it's a short name with prepended '-'. |
---|
95 | */ |
---|
96 | const std::string& key(const std::string& option) const; |
---|
97 | |
---|
98 | const std::string& long_name() const; |
---|
99 | |
---|
100 | /// Explanation of this option |
---|
101 | const std::string& description() const; |
---|
102 | |
---|
103 | /// Semantic of option's value |
---|
104 | shared_ptr<const value_semantic> semantic() const; |
---|
105 | |
---|
106 | /// Returns the option name, formatted suitably for usage message. |
---|
107 | std::string format_name() const; |
---|
108 | |
---|
109 | /** Return the parameter name and properties, formatted suitably for |
---|
110 | usage message. */ |
---|
111 | std::string format_parameter() const; |
---|
112 | |
---|
113 | private: |
---|
114 | |
---|
115 | option_description& set_name(const char* name); |
---|
116 | |
---|
117 | std::string m_short_name, m_long_name, m_description; |
---|
118 | // shared_ptr is needed to simplify memory management in |
---|
119 | // copy ctor and destructor. |
---|
120 | shared_ptr<const value_semantic> m_value_semantic; |
---|
121 | }; |
---|
122 | |
---|
123 | class options_description; |
---|
124 | |
---|
125 | /** Class which provides convenient creation syntax to option_description. |
---|
126 | */ |
---|
127 | class BOOST_PROGRAM_OPTIONS_DECL options_description_easy_init { |
---|
128 | public: |
---|
129 | options_description_easy_init(options_description* owner); |
---|
130 | |
---|
131 | options_description_easy_init& |
---|
132 | operator()(const char* name, |
---|
133 | const char* description); |
---|
134 | |
---|
135 | options_description_easy_init& |
---|
136 | operator()(const char* name, |
---|
137 | const value_semantic* s); |
---|
138 | |
---|
139 | options_description_easy_init& |
---|
140 | operator()(const char* name, |
---|
141 | const value_semantic* s, |
---|
142 | const char* description); |
---|
143 | |
---|
144 | private: |
---|
145 | options_description* owner; |
---|
146 | }; |
---|
147 | |
---|
148 | |
---|
149 | /** A set of option descriptions. This provides convenient interface for |
---|
150 | adding new option (the add_options) method, and facilities to search |
---|
151 | for options by name. |
---|
152 | |
---|
153 | See @ref a_adding_options "here" for option adding interface discussion. |
---|
154 | @sa option_description |
---|
155 | */ |
---|
156 | class BOOST_PROGRAM_OPTIONS_DECL options_description { |
---|
157 | public: |
---|
158 | static const unsigned m_default_line_length = 80; |
---|
159 | |
---|
160 | /** Creates the instance. */ |
---|
161 | options_description(unsigned line_length = m_default_line_length); |
---|
162 | /** Creates the instance. The 'caption' parameter gives the name of |
---|
163 | this 'options_description' instance. Primarily useful for output. |
---|
164 | */ |
---|
165 | options_description(const std::string& caption, |
---|
166 | unsigned line_length = m_default_line_length); |
---|
167 | /** Adds new variable description. Throws duplicate_variable_error if |
---|
168 | either short or long name matches that of already present one. |
---|
169 | */ |
---|
170 | void add(shared_ptr<option_description> desc); |
---|
171 | /** Adds a group of option description. This has the same |
---|
172 | effect as adding all option_descriptions in 'desc' |
---|
173 | individually, except that output operator will show |
---|
174 | a separate group. |
---|
175 | Returns *this. |
---|
176 | */ |
---|
177 | options_description& add(const options_description& desc); |
---|
178 | |
---|
179 | public: |
---|
180 | /** Returns an object of implementation-defined type suitable for adding |
---|
181 | options to options_description. The returned object will |
---|
182 | have overloaded operator() with parameter type matching |
---|
183 | 'option_description' constructors. Calling the operator will create |
---|
184 | new option_description instance and add it. |
---|
185 | */ |
---|
186 | options_description_easy_init add_options(); |
---|
187 | |
---|
188 | const option_description& find(const std::string& name, bool approx) |
---|
189 | const; |
---|
190 | |
---|
191 | const option_description* find_nothrow(const std::string& name, |
---|
192 | bool approx) const; |
---|
193 | |
---|
194 | |
---|
195 | const std::vector< shared_ptr<option_description> >& options() const; |
---|
196 | |
---|
197 | /** Produces a human readable output of 'desc', listing options, |
---|
198 | their descriptions and allowed parameters. Other options_description |
---|
199 | instances previously passed to add will be output separately. */ |
---|
200 | friend BOOST_PROGRAM_OPTIONS_DECL std::ostream& operator<<(std::ostream& os, |
---|
201 | const options_description& desc); |
---|
202 | |
---|
203 | /** Output 'desc' to the specified stream, calling 'f' to output each |
---|
204 | option_description element. */ |
---|
205 | void print(std::ostream& os) const; |
---|
206 | |
---|
207 | private: |
---|
208 | typedef std::map<std::string, int>::const_iterator name2index_iterator; |
---|
209 | typedef std::pair<name2index_iterator, name2index_iterator> |
---|
210 | approximation_range; |
---|
211 | |
---|
212 | //approximation_range find_approximation(const std::string& prefix) const; |
---|
213 | |
---|
214 | std::string m_caption; |
---|
215 | const unsigned m_line_length; |
---|
216 | // Data organization is chosen because: |
---|
217 | // - there could be two names for one option |
---|
218 | // - option_add_proxy needs to know the last added option |
---|
219 | std::vector< shared_ptr<option_description> > m_options; |
---|
220 | |
---|
221 | // Whether the option comes from one of declared groups. |
---|
222 | #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(313)) |
---|
223 | // vector<bool> is buggy there, see |
---|
224 | // http://support.microsoft.com/default.aspx?scid=kb;en-us;837698 |
---|
225 | std::vector<char> belong_to_group; |
---|
226 | #else |
---|
227 | std::vector<bool> belong_to_group; |
---|
228 | #endif |
---|
229 | |
---|
230 | std::vector< shared_ptr<options_description> > groups; |
---|
231 | |
---|
232 | }; |
---|
233 | |
---|
234 | /** Class thrown when duplicate option description is found. */ |
---|
235 | class BOOST_PROGRAM_OPTIONS_DECL duplicate_option_error : public error { |
---|
236 | public: |
---|
237 | duplicate_option_error(const std::string& what) : error(what) {} |
---|
238 | }; |
---|
239 | }} |
---|
240 | |
---|
241 | #endif |
---|