Commit 456ea951ab097c5efd555151c3c49698a8f51dd7
1 parent
b343ad98
Add support for implicit values
Showing
2 changed files
with
59 additions
and
14 deletions
src/cxxopts.hpp
| ... | ... | @@ -52,11 +52,17 @@ namespace cxxopts |
| 52 | 52 | virtual bool |
| 53 | 53 | has_default() const = 0; |
| 54 | 54 | |
| 55 | + virtual bool | |
| 56 | + has_implicit() const = 0; | |
| 57 | + | |
| 55 | 58 | virtual std::string |
| 56 | 59 | get_default_value() const = 0; |
| 57 | 60 | |
| 58 | 61 | virtual std::shared_ptr<Value> |
| 59 | 62 | default_value(const std::string& value) = 0; |
| 63 | + | |
| 64 | + virtual std::shared_ptr<Value> | |
| 65 | + implicit_value(const std::string& value) = 0; | |
| 60 | 66 | }; |
| 61 | 67 | |
| 62 | 68 | class OptionException : public std::exception |
| ... | ... | @@ -236,19 +242,28 @@ namespace cxxopts |
| 236 | 242 | : m_result(std::make_shared<T>()) |
| 237 | 243 | , m_store(m_result.get()) |
| 238 | 244 | , m_default(false), m_default_value("") |
| 245 | + , m_implicit(false), m_implicit_value("") | |
| 239 | 246 | { |
| 240 | 247 | } |
| 241 | 248 | |
| 242 | 249 | standard_value(T* t) |
| 243 | 250 | : m_store(t) |
| 244 | 251 | , m_default(false), m_default_value("") |
| 252 | + , m_implicit(false), m_implicit_value("") | |
| 245 | 253 | { |
| 246 | 254 | } |
| 247 | 255 | |
| 248 | 256 | void |
| 249 | 257 | parse(const std::string& text) const |
| 250 | 258 | { |
| 251 | - parse_value(text, *m_store); | |
| 259 | + if (m_implicit && text.empty()) | |
| 260 | + { | |
| 261 | + parse_value(m_implicit_value, *m_store); | |
| 262 | + } | |
| 263 | + else | |
| 264 | + { | |
| 265 | + parse_value(text, *m_store); | |
| 266 | + } | |
| 252 | 267 | } |
| 253 | 268 | |
| 254 | 269 | void |
| ... | ... | @@ -268,7 +283,13 @@ namespace cxxopts |
| 268 | 283 | { |
| 269 | 284 | return m_default; |
| 270 | 285 | } |
| 271 | - | |
| 286 | + | |
| 287 | + bool | |
| 288 | + has_implicit() const | |
| 289 | + { | |
| 290 | + return m_implicit; | |
| 291 | + } | |
| 292 | + | |
| 272 | 293 | virtual std::shared_ptr<Value> |
| 273 | 294 | default_value(const std::string& value){ |
| 274 | 295 | m_default = true; |
| ... | ... | @@ -276,6 +297,13 @@ namespace cxxopts |
| 276 | 297 | return shared_from_this(); |
| 277 | 298 | } |
| 278 | 299 | |
| 300 | + virtual std::shared_ptr<Value> | |
| 301 | + implicit_value(const std::string& value){ | |
| 302 | + m_implicit = true; | |
| 303 | + m_implicit_value = value; | |
| 304 | + return shared_from_this(); | |
| 305 | + } | |
| 306 | + | |
| 279 | 307 | std::string |
| 280 | 308 | get_default_value() const |
| 281 | 309 | { |
| ... | ... | @@ -300,6 +328,8 @@ namespace cxxopts |
| 300 | 328 | T* m_store; |
| 301 | 329 | bool m_default; |
| 302 | 330 | std::string m_default_value; |
| 331 | + bool m_implicit; | |
| 332 | + std::string m_implicit_value; | |
| 303 | 333 | }; |
| 304 | 334 | } |
| 305 | 335 | |
| ... | ... | @@ -495,7 +525,7 @@ namespace cxxopts |
| 495 | 525 | ( |
| 496 | 526 | int argc, |
| 497 | 527 | char* argv[], |
| 498 | - int argPos, | |
| 528 | + int& current, | |
| 499 | 529 | std::shared_ptr<OptionDetails> value, |
| 500 | 530 | const std::string& name |
| 501 | 531 | ); |
| ... | ... | @@ -696,17 +726,34 @@ Options::checked_parse_arg |
| 696 | 726 | ( |
| 697 | 727 | int argc, |
| 698 | 728 | char* argv[], |
| 699 | - int argPos, | |
| 729 | + int& current, | |
| 700 | 730 | std::shared_ptr<OptionDetails> value, |
| 701 | 731 | const std::string& name |
| 702 | 732 | ) |
| 703 | 733 | { |
| 704 | - if (argPos >= argc) | |
| 734 | + if (current + 1 >= argc) | |
| 735 | + { | |
| 736 | + if (value->value().has_implicit()) | |
| 737 | + { | |
| 738 | + parse_option(value, name, ""); | |
| 739 | + } | |
| 740 | + else | |
| 741 | + { | |
| 742 | + throw missing_argument_exception(name); | |
| 743 | + } | |
| 744 | + } | |
| 745 | + else | |
| 705 | 746 | { |
| 706 | - throw missing_argument_exception(name); | |
| 747 | + if (argv[current + 1][0] == '-' && value->value().has_implicit()) | |
| 748 | + { | |
| 749 | + parse_option(value, name, ""); | |
| 750 | + } | |
| 751 | + else | |
| 752 | + { | |
| 753 | + parse_option(value, name, argv[current + 1]); | |
| 754 | + ++current; | |
| 755 | + } | |
| 707 | 756 | } |
| 708 | - | |
| 709 | - parse_option(value, name, argv[argPos]); | |
| 710 | 757 | } |
| 711 | 758 | |
| 712 | 759 | void |
| ... | ... | @@ -799,8 +846,7 @@ Options::parse(int& argc, char**& argv) |
| 799 | 846 | //it must be the last argument |
| 800 | 847 | if (i + 1 == s.size()) |
| 801 | 848 | { |
| 802 | - checked_parse_arg(argc, argv, current+1, value, name); | |
| 803 | - ++current; | |
| 849 | + checked_parse_arg(argc, argv, current, value, name); | |
| 804 | 850 | } |
| 805 | 851 | else |
| 806 | 852 | { |
| ... | ... | @@ -841,9 +887,7 @@ Options::parse(int& argc, char**& argv) |
| 841 | 887 | if (opt->has_arg()) |
| 842 | 888 | { |
| 843 | 889 | //parse the next argument |
| 844 | - checked_parse_arg(argc, argv, current + 1, opt, name); | |
| 845 | - | |
| 846 | - ++current; | |
| 890 | + checked_parse_arg(argc, argv, current, opt, name); | |
| 847 | 891 | } |
| 848 | 892 | else |
| 849 | 893 | { | ... | ... |
src/example.cpp
| ... | ... | @@ -38,7 +38,8 @@ int main(int argc, char* argv[]) |
| 38 | 38 | ("a,apple", "an apple", cxxopts::value<bool>(apple)) |
| 39 | 39 | ("b,bob", "Bob") |
| 40 | 40 | ("f,file", "File", cxxopts::value<std::vector<std::string>>()) |
| 41 | - ("o,output", "Output file", cxxopts::value<std::string>()->default_value("a.out")) | |
| 41 | + ("o,output", "Output file", cxxopts::value<std::string>() | |
| 42 | + ->default_value("a.out")->implicit_value("b.def")) | |
| 42 | 43 | ("positional", |
| 43 | 44 | "Positional arguments: these are the arguments that are entered " |
| 44 | 45 | "without an option", cxxopts::value<std::string>()) | ... | ... |