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