1*b0d29bc4SBrooks Davis // Copyright 2010 The Kyua Authors.
2*b0d29bc4SBrooks Davis // All rights reserved.
3*b0d29bc4SBrooks Davis //
4*b0d29bc4SBrooks Davis // Redistribution and use in source and binary forms, with or without
5*b0d29bc4SBrooks Davis // modification, are permitted provided that the following conditions are
6*b0d29bc4SBrooks Davis // met:
7*b0d29bc4SBrooks Davis //
8*b0d29bc4SBrooks Davis // * Redistributions of source code must retain the above copyright
9*b0d29bc4SBrooks Davis // notice, this list of conditions and the following disclaimer.
10*b0d29bc4SBrooks Davis // * Redistributions in binary form must reproduce the above copyright
11*b0d29bc4SBrooks Davis // notice, this list of conditions and the following disclaimer in the
12*b0d29bc4SBrooks Davis // documentation and/or other materials provided with the distribution.
13*b0d29bc4SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
14*b0d29bc4SBrooks Davis // may be used to endorse or promote products derived from this software
15*b0d29bc4SBrooks Davis // without specific prior written permission.
16*b0d29bc4SBrooks Davis //
17*b0d29bc4SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*b0d29bc4SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*b0d29bc4SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*b0d29bc4SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*b0d29bc4SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*b0d29bc4SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*b0d29bc4SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*b0d29bc4SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*b0d29bc4SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*b0d29bc4SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*b0d29bc4SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*b0d29bc4SBrooks Davis
29*b0d29bc4SBrooks Davis #include "utils/cmdline/options.hpp"
30*b0d29bc4SBrooks Davis
31*b0d29bc4SBrooks Davis #include <stdexcept>
32*b0d29bc4SBrooks Davis #include <vector>
33*b0d29bc4SBrooks Davis
34*b0d29bc4SBrooks Davis #include "utils/cmdline/exceptions.hpp"
35*b0d29bc4SBrooks Davis #include "utils/defs.hpp"
36*b0d29bc4SBrooks Davis #include "utils/format/macros.hpp"
37*b0d29bc4SBrooks Davis #include "utils/fs/exceptions.hpp"
38*b0d29bc4SBrooks Davis #include "utils/fs/path.hpp"
39*b0d29bc4SBrooks Davis #include "utils/sanity.hpp"
40*b0d29bc4SBrooks Davis #include "utils/text/operations.ipp"
41*b0d29bc4SBrooks Davis
42*b0d29bc4SBrooks Davis namespace cmdline = utils::cmdline;
43*b0d29bc4SBrooks Davis namespace text = utils::text;
44*b0d29bc4SBrooks Davis
45*b0d29bc4SBrooks Davis
46*b0d29bc4SBrooks Davis /// Constructs a generic option with both a short and a long name.
47*b0d29bc4SBrooks Davis ///
48*b0d29bc4SBrooks Davis /// \param short_name_ The short name for the option.
49*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
50*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
51*b0d29bc4SBrooks Davis /// \param arg_name_ If not NULL, specifies that the option must receive an
52*b0d29bc4SBrooks Davis /// argument and specifies the name of such argument for documentation
53*b0d29bc4SBrooks Davis /// purposes.
54*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, specifies that the option has a default
55*b0d29bc4SBrooks Davis /// value for the mandatory argument.
base_option(const char short_name_,const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)56*b0d29bc4SBrooks Davis cmdline::base_option::base_option(const char short_name_,
57*b0d29bc4SBrooks Davis const char* long_name_,
58*b0d29bc4SBrooks Davis const char* description_,
59*b0d29bc4SBrooks Davis const char* arg_name_,
60*b0d29bc4SBrooks Davis const char* default_value_) :
61*b0d29bc4SBrooks Davis _short_name(short_name_),
62*b0d29bc4SBrooks Davis _long_name(long_name_),
63*b0d29bc4SBrooks Davis _description(description_),
64*b0d29bc4SBrooks Davis _arg_name(arg_name_ == NULL ? "" : arg_name_),
65*b0d29bc4SBrooks Davis _has_default_value(default_value_ != NULL),
66*b0d29bc4SBrooks Davis _default_value(default_value_ == NULL ? "" : default_value_)
67*b0d29bc4SBrooks Davis {
68*b0d29bc4SBrooks Davis INV(short_name_ != '\0');
69*b0d29bc4SBrooks Davis }
70*b0d29bc4SBrooks Davis
71*b0d29bc4SBrooks Davis
72*b0d29bc4SBrooks Davis /// Constructs a generic option with a long name only.
73*b0d29bc4SBrooks Davis ///
74*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
75*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
76*b0d29bc4SBrooks Davis /// \param arg_name_ If not NULL, specifies that the option must receive an
77*b0d29bc4SBrooks Davis /// argument and specifies the name of such argument for documentation
78*b0d29bc4SBrooks Davis /// purposes.
79*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, specifies that the option has a default
80*b0d29bc4SBrooks Davis /// value for the mandatory argument.
base_option(const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)81*b0d29bc4SBrooks Davis cmdline::base_option::base_option(const char* long_name_,
82*b0d29bc4SBrooks Davis const char* description_,
83*b0d29bc4SBrooks Davis const char* arg_name_,
84*b0d29bc4SBrooks Davis const char* default_value_) :
85*b0d29bc4SBrooks Davis _short_name('\0'),
86*b0d29bc4SBrooks Davis _long_name(long_name_),
87*b0d29bc4SBrooks Davis _description(description_),
88*b0d29bc4SBrooks Davis _arg_name(arg_name_ == NULL ? "" : arg_name_),
89*b0d29bc4SBrooks Davis _has_default_value(default_value_ != NULL),
90*b0d29bc4SBrooks Davis _default_value(default_value_ == NULL ? "" : default_value_)
91*b0d29bc4SBrooks Davis {
92*b0d29bc4SBrooks Davis }
93*b0d29bc4SBrooks Davis
94*b0d29bc4SBrooks Davis
95*b0d29bc4SBrooks Davis /// Destructor for the option.
~base_option(void)96*b0d29bc4SBrooks Davis cmdline::base_option::~base_option(void)
97*b0d29bc4SBrooks Davis {
98*b0d29bc4SBrooks Davis }
99*b0d29bc4SBrooks Davis
100*b0d29bc4SBrooks Davis
101*b0d29bc4SBrooks Davis /// Checks whether the option has a short name or not.
102*b0d29bc4SBrooks Davis ///
103*b0d29bc4SBrooks Davis /// \return True if the option has a short name, false otherwise.
104*b0d29bc4SBrooks Davis bool
has_short_name(void) const105*b0d29bc4SBrooks Davis cmdline::base_option::has_short_name(void) const
106*b0d29bc4SBrooks Davis {
107*b0d29bc4SBrooks Davis return _short_name != '\0';
108*b0d29bc4SBrooks Davis }
109*b0d29bc4SBrooks Davis
110*b0d29bc4SBrooks Davis
111*b0d29bc4SBrooks Davis /// Returns the short name of the option.
112*b0d29bc4SBrooks Davis ///
113*b0d29bc4SBrooks Davis /// \pre has_short_name() must be true.
114*b0d29bc4SBrooks Davis ///
115*b0d29bc4SBrooks Davis /// \return The short name.
116*b0d29bc4SBrooks Davis char
short_name(void) const117*b0d29bc4SBrooks Davis cmdline::base_option::short_name(void) const
118*b0d29bc4SBrooks Davis {
119*b0d29bc4SBrooks Davis PRE(has_short_name());
120*b0d29bc4SBrooks Davis return _short_name;
121*b0d29bc4SBrooks Davis }
122*b0d29bc4SBrooks Davis
123*b0d29bc4SBrooks Davis
124*b0d29bc4SBrooks Davis /// Returns the long name of the option.
125*b0d29bc4SBrooks Davis ///
126*b0d29bc4SBrooks Davis /// \return The long name.
127*b0d29bc4SBrooks Davis const std::string&
long_name(void) const128*b0d29bc4SBrooks Davis cmdline::base_option::long_name(void) const
129*b0d29bc4SBrooks Davis {
130*b0d29bc4SBrooks Davis return _long_name;
131*b0d29bc4SBrooks Davis }
132*b0d29bc4SBrooks Davis
133*b0d29bc4SBrooks Davis
134*b0d29bc4SBrooks Davis /// Returns the description of the option.
135*b0d29bc4SBrooks Davis ///
136*b0d29bc4SBrooks Davis /// \return The description.
137*b0d29bc4SBrooks Davis const std::string&
description(void) const138*b0d29bc4SBrooks Davis cmdline::base_option::description(void) const
139*b0d29bc4SBrooks Davis {
140*b0d29bc4SBrooks Davis return _description;
141*b0d29bc4SBrooks Davis }
142*b0d29bc4SBrooks Davis
143*b0d29bc4SBrooks Davis
144*b0d29bc4SBrooks Davis /// Checks whether the option needs an argument or not.
145*b0d29bc4SBrooks Davis ///
146*b0d29bc4SBrooks Davis /// \return True if the option needs an argument, false otherwise.
147*b0d29bc4SBrooks Davis bool
needs_arg(void) const148*b0d29bc4SBrooks Davis cmdline::base_option::needs_arg(void) const
149*b0d29bc4SBrooks Davis {
150*b0d29bc4SBrooks Davis return !_arg_name.empty();
151*b0d29bc4SBrooks Davis }
152*b0d29bc4SBrooks Davis
153*b0d29bc4SBrooks Davis
154*b0d29bc4SBrooks Davis /// Returns the argument name of the option for documentation purposes.
155*b0d29bc4SBrooks Davis ///
156*b0d29bc4SBrooks Davis /// \pre needs_arg() must be true.
157*b0d29bc4SBrooks Davis ///
158*b0d29bc4SBrooks Davis /// \return The argument name.
159*b0d29bc4SBrooks Davis const std::string&
arg_name(void) const160*b0d29bc4SBrooks Davis cmdline::base_option::arg_name(void) const
161*b0d29bc4SBrooks Davis {
162*b0d29bc4SBrooks Davis INV(needs_arg());
163*b0d29bc4SBrooks Davis return _arg_name;
164*b0d29bc4SBrooks Davis }
165*b0d29bc4SBrooks Davis
166*b0d29bc4SBrooks Davis
167*b0d29bc4SBrooks Davis /// Checks whether the option has a default value for its argument.
168*b0d29bc4SBrooks Davis ///
169*b0d29bc4SBrooks Davis /// \pre needs_arg() must be true.
170*b0d29bc4SBrooks Davis ///
171*b0d29bc4SBrooks Davis /// \return True if the option has a default value, false otherwise.
172*b0d29bc4SBrooks Davis bool
has_default_value(void) const173*b0d29bc4SBrooks Davis cmdline::base_option::has_default_value(void) const
174*b0d29bc4SBrooks Davis {
175*b0d29bc4SBrooks Davis PRE(needs_arg());
176*b0d29bc4SBrooks Davis return _has_default_value;
177*b0d29bc4SBrooks Davis }
178*b0d29bc4SBrooks Davis
179*b0d29bc4SBrooks Davis
180*b0d29bc4SBrooks Davis /// Returns the default value for the argument to the option.
181*b0d29bc4SBrooks Davis ///
182*b0d29bc4SBrooks Davis /// \pre has_default_value() must be true.
183*b0d29bc4SBrooks Davis ///
184*b0d29bc4SBrooks Davis /// \return The default value.
185*b0d29bc4SBrooks Davis const std::string&
default_value(void) const186*b0d29bc4SBrooks Davis cmdline::base_option::default_value(void) const
187*b0d29bc4SBrooks Davis {
188*b0d29bc4SBrooks Davis INV(has_default_value());
189*b0d29bc4SBrooks Davis return _default_value;;
190*b0d29bc4SBrooks Davis }
191*b0d29bc4SBrooks Davis
192*b0d29bc4SBrooks Davis
193*b0d29bc4SBrooks Davis /// Formats the short name of the option for documentation purposes.
194*b0d29bc4SBrooks Davis ///
195*b0d29bc4SBrooks Davis /// \return A string describing the option's short name.
196*b0d29bc4SBrooks Davis std::string
format_short_name(void) const197*b0d29bc4SBrooks Davis cmdline::base_option::format_short_name(void) const
198*b0d29bc4SBrooks Davis {
199*b0d29bc4SBrooks Davis PRE(has_short_name());
200*b0d29bc4SBrooks Davis
201*b0d29bc4SBrooks Davis if (needs_arg()) {
202*b0d29bc4SBrooks Davis return F("-%s %s") % short_name() % arg_name();
203*b0d29bc4SBrooks Davis } else {
204*b0d29bc4SBrooks Davis return F("-%s") % short_name();
205*b0d29bc4SBrooks Davis }
206*b0d29bc4SBrooks Davis }
207*b0d29bc4SBrooks Davis
208*b0d29bc4SBrooks Davis
209*b0d29bc4SBrooks Davis /// Formats the long name of the option for documentation purposes.
210*b0d29bc4SBrooks Davis ///
211*b0d29bc4SBrooks Davis /// \return A string describing the option's long name.
212*b0d29bc4SBrooks Davis std::string
format_long_name(void) const213*b0d29bc4SBrooks Davis cmdline::base_option::format_long_name(void) const
214*b0d29bc4SBrooks Davis {
215*b0d29bc4SBrooks Davis if (needs_arg()) {
216*b0d29bc4SBrooks Davis return F("--%s=%s") % long_name() % arg_name();
217*b0d29bc4SBrooks Davis } else {
218*b0d29bc4SBrooks Davis return F("--%s") % long_name();
219*b0d29bc4SBrooks Davis }
220*b0d29bc4SBrooks Davis }
221*b0d29bc4SBrooks Davis
222*b0d29bc4SBrooks Davis
223*b0d29bc4SBrooks Davis
224*b0d29bc4SBrooks Davis /// Ensures that an argument passed to the option is valid.
225*b0d29bc4SBrooks Davis ///
226*b0d29bc4SBrooks Davis /// This must be reimplemented by subclasses that describe options with
227*b0d29bc4SBrooks Davis /// arguments.
228*b0d29bc4SBrooks Davis ///
229*b0d29bc4SBrooks Davis /// \throw cmdline::option_argument_value_error Subclasses must raise this
230*b0d29bc4SBrooks Davis /// exception to indicate the cases in which str is invalid.
231*b0d29bc4SBrooks Davis void
validate(const std::string &) const232*b0d29bc4SBrooks Davis cmdline::base_option::validate(const std::string& /* str */) const
233*b0d29bc4SBrooks Davis {
234*b0d29bc4SBrooks Davis UNREACHABLE_MSG("Option does not support an argument");
235*b0d29bc4SBrooks Davis }
236*b0d29bc4SBrooks Davis
237*b0d29bc4SBrooks Davis
238*b0d29bc4SBrooks Davis /// Constructs a boolean option with both a short and a long name.
239*b0d29bc4SBrooks Davis ///
240*b0d29bc4SBrooks Davis /// \param short_name_ The short name for the option.
241*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
242*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
bool_option(const char short_name_,const char * long_name_,const char * description_)243*b0d29bc4SBrooks Davis cmdline::bool_option::bool_option(const char short_name_,
244*b0d29bc4SBrooks Davis const char* long_name_,
245*b0d29bc4SBrooks Davis const char* description_) :
246*b0d29bc4SBrooks Davis base_option(short_name_, long_name_, description_)
247*b0d29bc4SBrooks Davis {
248*b0d29bc4SBrooks Davis }
249*b0d29bc4SBrooks Davis
250*b0d29bc4SBrooks Davis
251*b0d29bc4SBrooks Davis /// Constructs a boolean option with a long name only.
252*b0d29bc4SBrooks Davis ///
253*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
254*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
bool_option(const char * long_name_,const char * description_)255*b0d29bc4SBrooks Davis cmdline::bool_option::bool_option(const char* long_name_,
256*b0d29bc4SBrooks Davis const char* description_) :
257*b0d29bc4SBrooks Davis base_option(long_name_, description_)
258*b0d29bc4SBrooks Davis {
259*b0d29bc4SBrooks Davis }
260*b0d29bc4SBrooks Davis
261*b0d29bc4SBrooks Davis
262*b0d29bc4SBrooks Davis /// Constructs an integer option with both a short and a long name.
263*b0d29bc4SBrooks Davis ///
264*b0d29bc4SBrooks Davis /// \param short_name_ The short name for the option.
265*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
266*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
267*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
268*b0d29bc4SBrooks Davis /// purposes.
269*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, the default value for the mandatory
270*b0d29bc4SBrooks Davis /// argument.
int_option(const char short_name_,const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)271*b0d29bc4SBrooks Davis cmdline::int_option::int_option(const char short_name_,
272*b0d29bc4SBrooks Davis const char* long_name_,
273*b0d29bc4SBrooks Davis const char* description_,
274*b0d29bc4SBrooks Davis const char* arg_name_,
275*b0d29bc4SBrooks Davis const char* default_value_) :
276*b0d29bc4SBrooks Davis base_option(short_name_, long_name_, description_, arg_name_,
277*b0d29bc4SBrooks Davis default_value_)
278*b0d29bc4SBrooks Davis {
279*b0d29bc4SBrooks Davis }
280*b0d29bc4SBrooks Davis
281*b0d29bc4SBrooks Davis
282*b0d29bc4SBrooks Davis /// Constructs an integer option with a long name only.
283*b0d29bc4SBrooks Davis ///
284*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
285*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
286*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
287*b0d29bc4SBrooks Davis /// purposes.
288*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, the default value for the mandatory
289*b0d29bc4SBrooks Davis /// argument.
int_option(const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)290*b0d29bc4SBrooks Davis cmdline::int_option::int_option(const char* long_name_,
291*b0d29bc4SBrooks Davis const char* description_,
292*b0d29bc4SBrooks Davis const char* arg_name_,
293*b0d29bc4SBrooks Davis const char* default_value_) :
294*b0d29bc4SBrooks Davis base_option(long_name_, description_, arg_name_, default_value_)
295*b0d29bc4SBrooks Davis {
296*b0d29bc4SBrooks Davis }
297*b0d29bc4SBrooks Davis
298*b0d29bc4SBrooks Davis
299*b0d29bc4SBrooks Davis /// Ensures that an integer argument passed to the int_option is valid.
300*b0d29bc4SBrooks Davis ///
301*b0d29bc4SBrooks Davis /// \param raw_value The argument representing an integer as provided by the
302*b0d29bc4SBrooks Davis /// user.
303*b0d29bc4SBrooks Davis ///
304*b0d29bc4SBrooks Davis /// \throw cmdline::option_argument_value_error If the integer provided in
305*b0d29bc4SBrooks Davis /// raw_value is invalid.
306*b0d29bc4SBrooks Davis void
validate(const std::string & raw_value) const307*b0d29bc4SBrooks Davis cmdline::int_option::validate(const std::string& raw_value) const
308*b0d29bc4SBrooks Davis {
309*b0d29bc4SBrooks Davis try {
310*b0d29bc4SBrooks Davis (void)text::to_type< int >(raw_value);
311*b0d29bc4SBrooks Davis } catch (const std::runtime_error& e) {
312*b0d29bc4SBrooks Davis throw cmdline::option_argument_value_error(
313*b0d29bc4SBrooks Davis F("--%s") % long_name(), raw_value, "Not a valid integer");
314*b0d29bc4SBrooks Davis }
315*b0d29bc4SBrooks Davis }
316*b0d29bc4SBrooks Davis
317*b0d29bc4SBrooks Davis
318*b0d29bc4SBrooks Davis /// Converts an integer argument to a native integer.
319*b0d29bc4SBrooks Davis ///
320*b0d29bc4SBrooks Davis /// \param raw_value The argument representing an integer as provided by the
321*b0d29bc4SBrooks Davis /// user.
322*b0d29bc4SBrooks Davis ///
323*b0d29bc4SBrooks Davis /// \return The integer.
324*b0d29bc4SBrooks Davis ///
325*b0d29bc4SBrooks Davis /// \pre validate(raw_value) must be true.
326*b0d29bc4SBrooks Davis int
convert(const std::string & raw_value)327*b0d29bc4SBrooks Davis cmdline::int_option::convert(const std::string& raw_value)
328*b0d29bc4SBrooks Davis {
329*b0d29bc4SBrooks Davis try {
330*b0d29bc4SBrooks Davis return text::to_type< int >(raw_value);
331*b0d29bc4SBrooks Davis } catch (const std::runtime_error& e) {
332*b0d29bc4SBrooks Davis PRE_MSG(false, F("Raw value '%s' for int option not properly "
333*b0d29bc4SBrooks Davis "validated: %s") % raw_value % e.what());
334*b0d29bc4SBrooks Davis }
335*b0d29bc4SBrooks Davis }
336*b0d29bc4SBrooks Davis
337*b0d29bc4SBrooks Davis
338*b0d29bc4SBrooks Davis /// Constructs a list option with both a short and a long name.
339*b0d29bc4SBrooks Davis ///
340*b0d29bc4SBrooks Davis /// \param short_name_ The short name for the option.
341*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
342*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
343*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
344*b0d29bc4SBrooks Davis /// purposes.
345*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, the default value for the mandatory
346*b0d29bc4SBrooks Davis /// argument.
list_option(const char short_name_,const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)347*b0d29bc4SBrooks Davis cmdline::list_option::list_option(const char short_name_,
348*b0d29bc4SBrooks Davis const char* long_name_,
349*b0d29bc4SBrooks Davis const char* description_,
350*b0d29bc4SBrooks Davis const char* arg_name_,
351*b0d29bc4SBrooks Davis const char* default_value_) :
352*b0d29bc4SBrooks Davis base_option(short_name_, long_name_, description_, arg_name_,
353*b0d29bc4SBrooks Davis default_value_)
354*b0d29bc4SBrooks Davis {
355*b0d29bc4SBrooks Davis }
356*b0d29bc4SBrooks Davis
357*b0d29bc4SBrooks Davis
358*b0d29bc4SBrooks Davis /// Constructs a list option with a long name only.
359*b0d29bc4SBrooks Davis ///
360*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
361*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
362*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
363*b0d29bc4SBrooks Davis /// purposes.
364*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, the default value for the mandatory
365*b0d29bc4SBrooks Davis /// argument.
list_option(const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)366*b0d29bc4SBrooks Davis cmdline::list_option::list_option(const char* long_name_,
367*b0d29bc4SBrooks Davis const char* description_,
368*b0d29bc4SBrooks Davis const char* arg_name_,
369*b0d29bc4SBrooks Davis const char* default_value_) :
370*b0d29bc4SBrooks Davis base_option(long_name_, description_, arg_name_, default_value_)
371*b0d29bc4SBrooks Davis {
372*b0d29bc4SBrooks Davis }
373*b0d29bc4SBrooks Davis
374*b0d29bc4SBrooks Davis
375*b0d29bc4SBrooks Davis /// Ensures that a lisstring argument passed to the list_option is valid.
376*b0d29bc4SBrooks Davis void
validate(const std::string &) const377*b0d29bc4SBrooks Davis cmdline::list_option::validate(
378*b0d29bc4SBrooks Davis const std::string& /* raw_value */) const
379*b0d29bc4SBrooks Davis {
380*b0d29bc4SBrooks Davis // Any list is potentially valid; the caller must check for semantics.
381*b0d29bc4SBrooks Davis }
382*b0d29bc4SBrooks Davis
383*b0d29bc4SBrooks Davis
384*b0d29bc4SBrooks Davis /// Converts a string argument to a vector.
385*b0d29bc4SBrooks Davis ///
386*b0d29bc4SBrooks Davis /// \param raw_value The argument representing a list as provided by the user.
387*b0d29bc4SBrooks Davis ///
388*b0d29bc4SBrooks Davis /// \return The list.
389*b0d29bc4SBrooks Davis ///
390*b0d29bc4SBrooks Davis /// \pre validate(raw_value) must be true.
391*b0d29bc4SBrooks Davis cmdline::list_option::option_type
convert(const std::string & raw_value)392*b0d29bc4SBrooks Davis cmdline::list_option::convert(const std::string& raw_value)
393*b0d29bc4SBrooks Davis {
394*b0d29bc4SBrooks Davis try {
395*b0d29bc4SBrooks Davis return text::split(raw_value, ',');
396*b0d29bc4SBrooks Davis } catch (const std::runtime_error& e) {
397*b0d29bc4SBrooks Davis PRE_MSG(false, F("Raw value '%s' for list option not properly "
398*b0d29bc4SBrooks Davis "validated: %s") % raw_value % e.what());
399*b0d29bc4SBrooks Davis }
400*b0d29bc4SBrooks Davis }
401*b0d29bc4SBrooks Davis
402*b0d29bc4SBrooks Davis
403*b0d29bc4SBrooks Davis /// Constructs a path option with both a short and a long name.
404*b0d29bc4SBrooks Davis ///
405*b0d29bc4SBrooks Davis /// \param short_name_ The short name for the option.
406*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
407*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
408*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
409*b0d29bc4SBrooks Davis /// purposes.
410*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, the default value for the mandatory
411*b0d29bc4SBrooks Davis /// argument.
path_option(const char short_name_,const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)412*b0d29bc4SBrooks Davis cmdline::path_option::path_option(const char short_name_,
413*b0d29bc4SBrooks Davis const char* long_name_,
414*b0d29bc4SBrooks Davis const char* description_,
415*b0d29bc4SBrooks Davis const char* arg_name_,
416*b0d29bc4SBrooks Davis const char* default_value_) :
417*b0d29bc4SBrooks Davis base_option(short_name_, long_name_, description_, arg_name_,
418*b0d29bc4SBrooks Davis default_value_)
419*b0d29bc4SBrooks Davis {
420*b0d29bc4SBrooks Davis }
421*b0d29bc4SBrooks Davis
422*b0d29bc4SBrooks Davis
423*b0d29bc4SBrooks Davis /// Constructs a path option with a long name only.
424*b0d29bc4SBrooks Davis ///
425*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
426*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
427*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
428*b0d29bc4SBrooks Davis /// purposes.
429*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, the default value for the mandatory
430*b0d29bc4SBrooks Davis /// argument.
path_option(const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)431*b0d29bc4SBrooks Davis cmdline::path_option::path_option(const char* long_name_,
432*b0d29bc4SBrooks Davis const char* description_,
433*b0d29bc4SBrooks Davis const char* arg_name_,
434*b0d29bc4SBrooks Davis const char* default_value_) :
435*b0d29bc4SBrooks Davis base_option(long_name_, description_, arg_name_, default_value_)
436*b0d29bc4SBrooks Davis {
437*b0d29bc4SBrooks Davis }
438*b0d29bc4SBrooks Davis
439*b0d29bc4SBrooks Davis
440*b0d29bc4SBrooks Davis /// Ensures that a path argument passed to the path_option is valid.
441*b0d29bc4SBrooks Davis ///
442*b0d29bc4SBrooks Davis /// \param raw_value The argument representing a path as provided by the user.
443*b0d29bc4SBrooks Davis ///
444*b0d29bc4SBrooks Davis /// \throw cmdline::option_argument_value_error If the path provided in
445*b0d29bc4SBrooks Davis /// raw_value is invalid.
446*b0d29bc4SBrooks Davis void
validate(const std::string & raw_value) const447*b0d29bc4SBrooks Davis cmdline::path_option::validate(const std::string& raw_value) const
448*b0d29bc4SBrooks Davis {
449*b0d29bc4SBrooks Davis try {
450*b0d29bc4SBrooks Davis (void)utils::fs::path(raw_value);
451*b0d29bc4SBrooks Davis } catch (const utils::fs::error& e) {
452*b0d29bc4SBrooks Davis throw cmdline::option_argument_value_error(F("--%s") % long_name(),
453*b0d29bc4SBrooks Davis raw_value, e.what());
454*b0d29bc4SBrooks Davis }
455*b0d29bc4SBrooks Davis }
456*b0d29bc4SBrooks Davis
457*b0d29bc4SBrooks Davis
458*b0d29bc4SBrooks Davis /// Converts a path argument to a utils::fs::path.
459*b0d29bc4SBrooks Davis ///
460*b0d29bc4SBrooks Davis /// \param raw_value The argument representing a path as provided by the user.
461*b0d29bc4SBrooks Davis ///
462*b0d29bc4SBrooks Davis /// \return The path.
463*b0d29bc4SBrooks Davis ///
464*b0d29bc4SBrooks Davis /// \pre validate(raw_value) must be true.
465*b0d29bc4SBrooks Davis utils::fs::path
convert(const std::string & raw_value)466*b0d29bc4SBrooks Davis cmdline::path_option::convert(const std::string& raw_value)
467*b0d29bc4SBrooks Davis {
468*b0d29bc4SBrooks Davis try {
469*b0d29bc4SBrooks Davis return utils::fs::path(raw_value);
470*b0d29bc4SBrooks Davis } catch (const std::runtime_error& e) {
471*b0d29bc4SBrooks Davis PRE_MSG(false, F("Raw value '%s' for path option not properly "
472*b0d29bc4SBrooks Davis "validated: %s") % raw_value % e.what());
473*b0d29bc4SBrooks Davis }
474*b0d29bc4SBrooks Davis }
475*b0d29bc4SBrooks Davis
476*b0d29bc4SBrooks Davis
477*b0d29bc4SBrooks Davis /// Constructs a property option with both a short and a long name.
478*b0d29bc4SBrooks Davis ///
479*b0d29bc4SBrooks Davis /// \param short_name_ The short name for the option.
480*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
481*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
482*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
483*b0d29bc4SBrooks Davis /// purposes. Must include the '=' delimiter.
property_option(const char short_name_,const char * long_name_,const char * description_,const char * arg_name_)484*b0d29bc4SBrooks Davis cmdline::property_option::property_option(const char short_name_,
485*b0d29bc4SBrooks Davis const char* long_name_,
486*b0d29bc4SBrooks Davis const char* description_,
487*b0d29bc4SBrooks Davis const char* arg_name_) :
488*b0d29bc4SBrooks Davis base_option(short_name_, long_name_, description_, arg_name_)
489*b0d29bc4SBrooks Davis {
490*b0d29bc4SBrooks Davis PRE(arg_name().find('=') != std::string::npos);
491*b0d29bc4SBrooks Davis }
492*b0d29bc4SBrooks Davis
493*b0d29bc4SBrooks Davis
494*b0d29bc4SBrooks Davis /// Constructs a property option with a long name only.
495*b0d29bc4SBrooks Davis ///
496*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
497*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
498*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
499*b0d29bc4SBrooks Davis /// purposes. Must include the '=' delimiter.
property_option(const char * long_name_,const char * description_,const char * arg_name_)500*b0d29bc4SBrooks Davis cmdline::property_option::property_option(const char* long_name_,
501*b0d29bc4SBrooks Davis const char* description_,
502*b0d29bc4SBrooks Davis const char* arg_name_) :
503*b0d29bc4SBrooks Davis base_option(long_name_, description_, arg_name_)
504*b0d29bc4SBrooks Davis {
505*b0d29bc4SBrooks Davis PRE(arg_name().find('=') != std::string::npos);
506*b0d29bc4SBrooks Davis }
507*b0d29bc4SBrooks Davis
508*b0d29bc4SBrooks Davis
509*b0d29bc4SBrooks Davis /// Validates the argument to a property option.
510*b0d29bc4SBrooks Davis ///
511*b0d29bc4SBrooks Davis /// \param raw_value The argument provided by the user.
512*b0d29bc4SBrooks Davis void
validate(const std::string & raw_value) const513*b0d29bc4SBrooks Davis cmdline::property_option::validate(const std::string& raw_value) const
514*b0d29bc4SBrooks Davis {
515*b0d29bc4SBrooks Davis const std::string::size_type pos = raw_value.find('=');
516*b0d29bc4SBrooks Davis if (pos == std::string::npos)
517*b0d29bc4SBrooks Davis throw cmdline::option_argument_value_error(
518*b0d29bc4SBrooks Davis F("--%s") % long_name(), raw_value,
519*b0d29bc4SBrooks Davis F("Argument does not have the form '%s'") % arg_name());
520*b0d29bc4SBrooks Davis
521*b0d29bc4SBrooks Davis const std::string key = raw_value.substr(0, pos);
522*b0d29bc4SBrooks Davis if (key.empty())
523*b0d29bc4SBrooks Davis throw cmdline::option_argument_value_error(
524*b0d29bc4SBrooks Davis F("--%s") % long_name(), raw_value, "Empty property name");
525*b0d29bc4SBrooks Davis
526*b0d29bc4SBrooks Davis const std::string value = raw_value.substr(pos + 1);
527*b0d29bc4SBrooks Davis if (value.empty())
528*b0d29bc4SBrooks Davis throw cmdline::option_argument_value_error(
529*b0d29bc4SBrooks Davis F("--%s") % long_name(), raw_value, "Empty value");
530*b0d29bc4SBrooks Davis }
531*b0d29bc4SBrooks Davis
532*b0d29bc4SBrooks Davis
533*b0d29bc4SBrooks Davis /// Returns the property option in a key/value pair form.
534*b0d29bc4SBrooks Davis ///
535*b0d29bc4SBrooks Davis /// \param raw_value The argument provided by the user.
536*b0d29bc4SBrooks Davis ///
537*b0d29bc4SBrooks Davis /// \return raw_value The key/value pair representation of the property.
538*b0d29bc4SBrooks Davis ///
539*b0d29bc4SBrooks Davis /// \pre validate(raw_value) must be true.
540*b0d29bc4SBrooks Davis cmdline::property_option::option_type
convert(const std::string & raw_value)541*b0d29bc4SBrooks Davis cmdline::property_option::convert(const std::string& raw_value)
542*b0d29bc4SBrooks Davis {
543*b0d29bc4SBrooks Davis const std::string::size_type pos = raw_value.find('=');
544*b0d29bc4SBrooks Davis return std::make_pair(raw_value.substr(0, pos), raw_value.substr(pos + 1));
545*b0d29bc4SBrooks Davis }
546*b0d29bc4SBrooks Davis
547*b0d29bc4SBrooks Davis
548*b0d29bc4SBrooks Davis /// Constructs a string option with both a short and a long name.
549*b0d29bc4SBrooks Davis ///
550*b0d29bc4SBrooks Davis /// \param short_name_ The short name for the option.
551*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
552*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
553*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
554*b0d29bc4SBrooks Davis /// purposes.
555*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, the default value for the mandatory
556*b0d29bc4SBrooks Davis /// argument.
string_option(const char short_name_,const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)557*b0d29bc4SBrooks Davis cmdline::string_option::string_option(const char short_name_,
558*b0d29bc4SBrooks Davis const char* long_name_,
559*b0d29bc4SBrooks Davis const char* description_,
560*b0d29bc4SBrooks Davis const char* arg_name_,
561*b0d29bc4SBrooks Davis const char* default_value_) :
562*b0d29bc4SBrooks Davis base_option(short_name_, long_name_, description_, arg_name_,
563*b0d29bc4SBrooks Davis default_value_)
564*b0d29bc4SBrooks Davis {
565*b0d29bc4SBrooks Davis }
566*b0d29bc4SBrooks Davis
567*b0d29bc4SBrooks Davis
568*b0d29bc4SBrooks Davis /// Constructs a string option with a long name only.
569*b0d29bc4SBrooks Davis ///
570*b0d29bc4SBrooks Davis /// \param long_name_ The long name for the option.
571*b0d29bc4SBrooks Davis /// \param description_ A user-friendly description for the option.
572*b0d29bc4SBrooks Davis /// \param arg_name_ The name of the mandatory argument, for documentation
573*b0d29bc4SBrooks Davis /// purposes.
574*b0d29bc4SBrooks Davis /// \param default_value_ If not NULL, the default value for the mandatory
575*b0d29bc4SBrooks Davis /// argument.
string_option(const char * long_name_,const char * description_,const char * arg_name_,const char * default_value_)576*b0d29bc4SBrooks Davis cmdline::string_option::string_option(const char* long_name_,
577*b0d29bc4SBrooks Davis const char* description_,
578*b0d29bc4SBrooks Davis const char* arg_name_,
579*b0d29bc4SBrooks Davis const char* default_value_) :
580*b0d29bc4SBrooks Davis base_option(long_name_, description_, arg_name_, default_value_)
581*b0d29bc4SBrooks Davis {
582*b0d29bc4SBrooks Davis }
583*b0d29bc4SBrooks Davis
584*b0d29bc4SBrooks Davis
585*b0d29bc4SBrooks Davis /// Does nothing; all string values are valid arguments to a string_option.
586*b0d29bc4SBrooks Davis void
validate(const std::string &) const587*b0d29bc4SBrooks Davis cmdline::string_option::validate(
588*b0d29bc4SBrooks Davis const std::string& /* raw_value */) const
589*b0d29bc4SBrooks Davis {
590*b0d29bc4SBrooks Davis // Nothing to do.
591*b0d29bc4SBrooks Davis }
592*b0d29bc4SBrooks Davis
593*b0d29bc4SBrooks Davis
594*b0d29bc4SBrooks Davis /// Returns the string unmodified.
595*b0d29bc4SBrooks Davis ///
596*b0d29bc4SBrooks Davis /// \param raw_value The argument provided by the user.
597*b0d29bc4SBrooks Davis ///
598*b0d29bc4SBrooks Davis /// \return raw_value
599*b0d29bc4SBrooks Davis ///
600*b0d29bc4SBrooks Davis /// \pre validate(raw_value) must be true.
601*b0d29bc4SBrooks Davis std::string
convert(const std::string & raw_value)602*b0d29bc4SBrooks Davis cmdline::string_option::convert(const std::string& raw_value)
603*b0d29bc4SBrooks Davis {
604*b0d29bc4SBrooks Davis return raw_value;
605*b0d29bc4SBrooks Davis }
606