1 // Copyright 2010 The Kyua Authors.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "utils/cmdline/options.hpp"
34 #include "utils/cmdline/exceptions.hpp"
35 #include "utils/defs.hpp"
36 #include "utils/format/macros.hpp"
37 #include "utils/fs/exceptions.hpp"
38 #include "utils/fs/path.hpp"
39 #include "utils/sanity.hpp"
40 #include "utils/text/operations.ipp"
42 namespace cmdline = utils::cmdline;
43 namespace text = utils::text;
46 /// Constructs a generic option with both a short and a long name.
48 /// \param short_name_ The short name for the option.
49 /// \param long_name_ The long name for the option.
50 /// \param description_ A user-friendly description for the option.
51 /// \param arg_name_ If not NULL, specifies that the option must receive an
52 /// argument and specifies the name of such argument for documentation
54 /// \param default_value_ If not NULL, specifies that the option has a default
55 /// value for the mandatory argument.
56 cmdline::base_option::base_option(const char short_name_,
57 const char* long_name_,
58 const char* description_,
59 const char* arg_name_,
60 const char* default_value_) :
61 _short_name(short_name_),
62 _long_name(long_name_),
63 _description(description_),
64 _arg_name(arg_name_ == NULL ? "" : arg_name_),
65 _has_default_value(default_value_ != NULL),
66 _default_value(default_value_ == NULL ? "" : default_value_)
68 INV(short_name_ != '\0');
72 /// Constructs a generic option with a long name only.
74 /// \param long_name_ The long name for the option.
75 /// \param description_ A user-friendly description for the option.
76 /// \param arg_name_ If not NULL, specifies that the option must receive an
77 /// argument and specifies the name of such argument for documentation
79 /// \param default_value_ If not NULL, specifies that the option has a default
80 /// value for the mandatory argument.
81 cmdline::base_option::base_option(const char* long_name_,
82 const char* description_,
83 const char* arg_name_,
84 const char* default_value_) :
86 _long_name(long_name_),
87 _description(description_),
88 _arg_name(arg_name_ == NULL ? "" : arg_name_),
89 _has_default_value(default_value_ != NULL),
90 _default_value(default_value_ == NULL ? "" : default_value_)
95 /// Destructor for the option.
96 cmdline::base_option::~base_option(void)
101 /// Checks whether the option has a short name or not.
103 /// \return True if the option has a short name, false otherwise.
105 cmdline::base_option::has_short_name(void) const
107 return _short_name != '\0';
111 /// Returns the short name of the option.
113 /// \pre has_short_name() must be true.
115 /// \return The short name.
117 cmdline::base_option::short_name(void) const
119 PRE(has_short_name());
124 /// Returns the long name of the option.
126 /// \return The long name.
128 cmdline::base_option::long_name(void) const
134 /// Returns the description of the option.
136 /// \return The description.
138 cmdline::base_option::description(void) const
144 /// Checks whether the option needs an argument or not.
146 /// \return True if the option needs an argument, false otherwise.
148 cmdline::base_option::needs_arg(void) const
150 return !_arg_name.empty();
154 /// Returns the argument name of the option for documentation purposes.
156 /// \pre needs_arg() must be true.
158 /// \return The argument name.
160 cmdline::base_option::arg_name(void) const
167 /// Checks whether the option has a default value for its argument.
169 /// \pre needs_arg() must be true.
171 /// \return True if the option has a default value, false otherwise.
173 cmdline::base_option::has_default_value(void) const
176 return _has_default_value;
180 /// Returns the default value for the argument to the option.
182 /// \pre has_default_value() must be true.
184 /// \return The default value.
186 cmdline::base_option::default_value(void) const
188 INV(has_default_value());
189 return _default_value;;
193 /// Formats the short name of the option for documentation purposes.
195 /// \return A string describing the option's short name.
197 cmdline::base_option::format_short_name(void) const
199 PRE(has_short_name());
202 return F("-%s %s") % short_name() % arg_name();
204 return F("-%s") % short_name();
209 /// Formats the long name of the option for documentation purposes.
211 /// \return A string describing the option's long name.
213 cmdline::base_option::format_long_name(void) const
216 return F("--%s=%s") % long_name() % arg_name();
218 return F("--%s") % long_name();
224 /// Ensures that an argument passed to the option is valid.
226 /// This must be reimplemented by subclasses that describe options with
229 /// \throw cmdline::option_argument_value_error Subclasses must raise this
230 /// exception to indicate the cases in which str is invalid.
232 cmdline::base_option::validate(const std::string& /* str */) const
234 UNREACHABLE_MSG("Option does not support an argument");
238 /// Constructs a boolean option with both a short and a long name.
240 /// \param short_name_ The short name for the option.
241 /// \param long_name_ The long name for the option.
242 /// \param description_ A user-friendly description for the option.
243 cmdline::bool_option::bool_option(const char short_name_,
244 const char* long_name_,
245 const char* description_) :
246 base_option(short_name_, long_name_, description_)
251 /// Constructs a boolean option with a long name only.
253 /// \param long_name_ The long name for the option.
254 /// \param description_ A user-friendly description for the option.
255 cmdline::bool_option::bool_option(const char* long_name_,
256 const char* description_) :
257 base_option(long_name_, description_)
262 /// Constructs an integer option with both a short and a long name.
264 /// \param short_name_ The short name for the option.
265 /// \param long_name_ The long name for the option.
266 /// \param description_ A user-friendly description for the option.
267 /// \param arg_name_ The name of the mandatory argument, for documentation
269 /// \param default_value_ If not NULL, the default value for the mandatory
271 cmdline::int_option::int_option(const char short_name_,
272 const char* long_name_,
273 const char* description_,
274 const char* arg_name_,
275 const char* default_value_) :
276 base_option(short_name_, long_name_, description_, arg_name_,
282 /// Constructs an integer option with a long name only.
284 /// \param long_name_ The long name for the option.
285 /// \param description_ A user-friendly description for the option.
286 /// \param arg_name_ The name of the mandatory argument, for documentation
288 /// \param default_value_ If not NULL, the default value for the mandatory
290 cmdline::int_option::int_option(const char* long_name_,
291 const char* description_,
292 const char* arg_name_,
293 const char* default_value_) :
294 base_option(long_name_, description_, arg_name_, default_value_)
299 /// Ensures that an integer argument passed to the int_option is valid.
301 /// \param raw_value The argument representing an integer as provided by the
304 /// \throw cmdline::option_argument_value_error If the integer provided in
305 /// raw_value is invalid.
307 cmdline::int_option::validate(const std::string& raw_value) const
310 (void)text::to_type< int >(raw_value);
311 } catch (const std::runtime_error& e) {
312 throw cmdline::option_argument_value_error(
313 F("--%s") % long_name(), raw_value, "Not a valid integer");
318 /// Converts an integer argument to a native integer.
320 /// \param raw_value The argument representing an integer as provided by the
323 /// \return The integer.
325 /// \pre validate(raw_value) must be true.
327 cmdline::int_option::convert(const std::string& raw_value)
330 return text::to_type< int >(raw_value);
331 } catch (const std::runtime_error& e) {
332 PRE_MSG(false, F("Raw value '%s' for int option not properly "
333 "validated: %s") % raw_value % e.what());
338 /// Constructs a list option with both a short and a long name.
340 /// \param short_name_ The short name for the option.
341 /// \param long_name_ The long name for the option.
342 /// \param description_ A user-friendly description for the option.
343 /// \param arg_name_ The name of the mandatory argument, for documentation
345 /// \param default_value_ If not NULL, the default value for the mandatory
347 cmdline::list_option::list_option(const char short_name_,
348 const char* long_name_,
349 const char* description_,
350 const char* arg_name_,
351 const char* default_value_) :
352 base_option(short_name_, long_name_, description_, arg_name_,
358 /// Constructs a list option with a long name only.
360 /// \param long_name_ The long name for the option.
361 /// \param description_ A user-friendly description for the option.
362 /// \param arg_name_ The name of the mandatory argument, for documentation
364 /// \param default_value_ If not NULL, the default value for the mandatory
366 cmdline::list_option::list_option(const char* long_name_,
367 const char* description_,
368 const char* arg_name_,
369 const char* default_value_) :
370 base_option(long_name_, description_, arg_name_, default_value_)
375 /// Ensures that a lisstring argument passed to the list_option is valid.
377 cmdline::list_option::validate(
378 const std::string& /* raw_value */) const
380 // Any list is potentially valid; the caller must check for semantics.
384 /// Converts a string argument to a vector.
386 /// \param raw_value The argument representing a list as provided by the user.
388 /// \return The list.
390 /// \pre validate(raw_value) must be true.
391 cmdline::list_option::option_type
392 cmdline::list_option::convert(const std::string& raw_value)
395 return text::split(raw_value, ',');
396 } catch (const std::runtime_error& e) {
397 PRE_MSG(false, F("Raw value '%s' for list option not properly "
398 "validated: %s") % raw_value % e.what());
403 /// Constructs a path option with both a short and a long name.
405 /// \param short_name_ The short name for the option.
406 /// \param long_name_ The long name for the option.
407 /// \param description_ A user-friendly description for the option.
408 /// \param arg_name_ The name of the mandatory argument, for documentation
410 /// \param default_value_ If not NULL, the default value for the mandatory
412 cmdline::path_option::path_option(const char short_name_,
413 const char* long_name_,
414 const char* description_,
415 const char* arg_name_,
416 const char* default_value_) :
417 base_option(short_name_, long_name_, description_, arg_name_,
423 /// Constructs a path option with a long name only.
425 /// \param long_name_ The long name for the option.
426 /// \param description_ A user-friendly description for the option.
427 /// \param arg_name_ The name of the mandatory argument, for documentation
429 /// \param default_value_ If not NULL, the default value for the mandatory
431 cmdline::path_option::path_option(const char* long_name_,
432 const char* description_,
433 const char* arg_name_,
434 const char* default_value_) :
435 base_option(long_name_, description_, arg_name_, default_value_)
440 /// Ensures that a path argument passed to the path_option is valid.
442 /// \param raw_value The argument representing a path as provided by the user.
444 /// \throw cmdline::option_argument_value_error If the path provided in
445 /// raw_value is invalid.
447 cmdline::path_option::validate(const std::string& raw_value) const
450 (void)utils::fs::path(raw_value);
451 } catch (const utils::fs::error& e) {
452 throw cmdline::option_argument_value_error(F("--%s") % long_name(),
453 raw_value, e.what());
458 /// Converts a path argument to a utils::fs::path.
460 /// \param raw_value The argument representing a path as provided by the user.
462 /// \return The path.
464 /// \pre validate(raw_value) must be true.
466 cmdline::path_option::convert(const std::string& raw_value)
469 return utils::fs::path(raw_value);
470 } catch (const std::runtime_error& e) {
471 PRE_MSG(false, F("Raw value '%s' for path option not properly "
472 "validated: %s") % raw_value % e.what());
477 /// Constructs a property option with both a short and a long name.
479 /// \param short_name_ The short name for the option.
480 /// \param long_name_ The long name for the option.
481 /// \param description_ A user-friendly description for the option.
482 /// \param arg_name_ The name of the mandatory argument, for documentation
483 /// purposes. Must include the '=' delimiter.
484 cmdline::property_option::property_option(const char short_name_,
485 const char* long_name_,
486 const char* description_,
487 const char* arg_name_) :
488 base_option(short_name_, long_name_, description_, arg_name_)
490 PRE(arg_name().find('=') != std::string::npos);
494 /// Constructs a property option with a long name only.
496 /// \param long_name_ The long name for the option.
497 /// \param description_ A user-friendly description for the option.
498 /// \param arg_name_ The name of the mandatory argument, for documentation
499 /// purposes. Must include the '=' delimiter.
500 cmdline::property_option::property_option(const char* long_name_,
501 const char* description_,
502 const char* arg_name_) :
503 base_option(long_name_, description_, arg_name_)
505 PRE(arg_name().find('=') != std::string::npos);
509 /// Validates the argument to a property option.
511 /// \param raw_value The argument provided by the user.
513 cmdline::property_option::validate(const std::string& raw_value) const
515 const std::string::size_type pos = raw_value.find('=');
516 if (pos == std::string::npos)
517 throw cmdline::option_argument_value_error(
518 F("--%s") % long_name(), raw_value,
519 F("Argument does not have the form '%s'") % arg_name());
521 const std::string key = raw_value.substr(0, pos);
523 throw cmdline::option_argument_value_error(
524 F("--%s") % long_name(), raw_value, "Empty property name");
526 const std::string value = raw_value.substr(pos + 1);
528 throw cmdline::option_argument_value_error(
529 F("--%s") % long_name(), raw_value, "Empty value");
533 /// Returns the property option in a key/value pair form.
535 /// \param raw_value The argument provided by the user.
537 /// \return raw_value The key/value pair representation of the property.
539 /// \pre validate(raw_value) must be true.
540 cmdline::property_option::option_type
541 cmdline::property_option::convert(const std::string& raw_value)
543 const std::string::size_type pos = raw_value.find('=');
544 return std::make_pair(raw_value.substr(0, pos), raw_value.substr(pos + 1));
548 /// Constructs a string option with both a short and a long name.
550 /// \param short_name_ The short name for the option.
551 /// \param long_name_ The long name for the option.
552 /// \param description_ A user-friendly description for the option.
553 /// \param arg_name_ The name of the mandatory argument, for documentation
555 /// \param default_value_ If not NULL, the default value for the mandatory
557 cmdline::string_option::string_option(const char short_name_,
558 const char* long_name_,
559 const char* description_,
560 const char* arg_name_,
561 const char* default_value_) :
562 base_option(short_name_, long_name_, description_, arg_name_,
568 /// Constructs a string option with a long name only.
570 /// \param long_name_ The long name for the option.
571 /// \param description_ A user-friendly description for the option.
572 /// \param arg_name_ The name of the mandatory argument, for documentation
574 /// \param default_value_ If not NULL, the default value for the mandatory
576 cmdline::string_option::string_option(const char* long_name_,
577 const char* description_,
578 const char* arg_name_,
579 const char* default_value_) :
580 base_option(long_name_, description_, arg_name_, default_value_)
585 /// Does nothing; all string values are valid arguments to a string_option.
587 cmdline::string_option::validate(
588 const std::string& /* raw_value */) const
594 /// Returns the string unmodified.
596 /// \param raw_value The argument provided by the user.
598 /// \return raw_value
600 /// \pre validate(raw_value) must be true.
602 cmdline::string_option::convert(const std::string& raw_value)