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,11 +52,17 @@ namespace cxxopts | ||
| 52 | virtual bool | 52 | virtual bool |
| 53 | has_default() const = 0; | 53 | has_default() const = 0; |
| 54 | 54 | ||
| 55 | + virtual bool | ||
| 56 | + has_implicit() const = 0; | ||
| 57 | + | ||
| 55 | virtual std::string | 58 | virtual std::string |
| 56 | get_default_value() const = 0; | 59 | get_default_value() const = 0; |
| 57 | 60 | ||
| 58 | virtual std::shared_ptr<Value> | 61 | virtual std::shared_ptr<Value> |
| 59 | default_value(const std::string& value) = 0; | 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 | class OptionException : public std::exception | 68 | class OptionException : public std::exception |
| @@ -236,19 +242,28 @@ namespace cxxopts | @@ -236,19 +242,28 @@ namespace cxxopts | ||
| 236 | : m_result(std::make_shared<T>()) | 242 | : m_result(std::make_shared<T>()) |
| 237 | , m_store(m_result.get()) | 243 | , m_store(m_result.get()) |
| 238 | , m_default(false), m_default_value("") | 244 | , m_default(false), m_default_value("") |
| 245 | + , m_implicit(false), m_implicit_value("") | ||
| 239 | { | 246 | { |
| 240 | } | 247 | } |
| 241 | 248 | ||
| 242 | standard_value(T* t) | 249 | standard_value(T* t) |
| 243 | : m_store(t) | 250 | : m_store(t) |
| 244 | , m_default(false), m_default_value("") | 251 | , m_default(false), m_default_value("") |
| 252 | + , m_implicit(false), m_implicit_value("") | ||
| 245 | { | 253 | { |
| 246 | } | 254 | } |
| 247 | 255 | ||
| 248 | void | 256 | void |
| 249 | parse(const std::string& text) const | 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 | void | 269 | void |
| @@ -268,7 +283,13 @@ namespace cxxopts | @@ -268,7 +283,13 @@ namespace cxxopts | ||
| 268 | { | 283 | { |
| 269 | return m_default; | 284 | return m_default; |
| 270 | } | 285 | } |
| 271 | - | 286 | + |
| 287 | + bool | ||
| 288 | + has_implicit() const | ||
| 289 | + { | ||
| 290 | + return m_implicit; | ||
| 291 | + } | ||
| 292 | + | ||
| 272 | virtual std::shared_ptr<Value> | 293 | virtual std::shared_ptr<Value> |
| 273 | default_value(const std::string& value){ | 294 | default_value(const std::string& value){ |
| 274 | m_default = true; | 295 | m_default = true; |
| @@ -276,6 +297,13 @@ namespace cxxopts | @@ -276,6 +297,13 @@ namespace cxxopts | ||
| 276 | return shared_from_this(); | 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 | std::string | 307 | std::string |
| 280 | get_default_value() const | 308 | get_default_value() const |
| 281 | { | 309 | { |
| @@ -300,6 +328,8 @@ namespace cxxopts | @@ -300,6 +328,8 @@ namespace cxxopts | ||
| 300 | T* m_store; | 328 | T* m_store; |
| 301 | bool m_default; | 329 | bool m_default; |
| 302 | std::string m_default_value; | 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,7 +525,7 @@ namespace cxxopts | ||
| 495 | ( | 525 | ( |
| 496 | int argc, | 526 | int argc, |
| 497 | char* argv[], | 527 | char* argv[], |
| 498 | - int argPos, | 528 | + int& current, |
| 499 | std::shared_ptr<OptionDetails> value, | 529 | std::shared_ptr<OptionDetails> value, |
| 500 | const std::string& name | 530 | const std::string& name |
| 501 | ); | 531 | ); |
| @@ -696,17 +726,34 @@ Options::checked_parse_arg | @@ -696,17 +726,34 @@ Options::checked_parse_arg | ||
| 696 | ( | 726 | ( |
| 697 | int argc, | 727 | int argc, |
| 698 | char* argv[], | 728 | char* argv[], |
| 699 | - int argPos, | 729 | + int& current, |
| 700 | std::shared_ptr<OptionDetails> value, | 730 | std::shared_ptr<OptionDetails> value, |
| 701 | const std::string& name | 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 | void | 759 | void |
| @@ -799,8 +846,7 @@ Options::parse(int& argc, char**& argv) | @@ -799,8 +846,7 @@ Options::parse(int& argc, char**& argv) | ||
| 799 | //it must be the last argument | 846 | //it must be the last argument |
| 800 | if (i + 1 == s.size()) | 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 | else | 851 | else |
| 806 | { | 852 | { |
| @@ -841,9 +887,7 @@ Options::parse(int& argc, char**& argv) | @@ -841,9 +887,7 @@ Options::parse(int& argc, char**& argv) | ||
| 841 | if (opt->has_arg()) | 887 | if (opt->has_arg()) |
| 842 | { | 888 | { |
| 843 | //parse the next argument | 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 | else | 892 | else |
| 849 | { | 893 | { |
src/example.cpp
| @@ -38,7 +38,8 @@ int main(int argc, char* argv[]) | @@ -38,7 +38,8 @@ int main(int argc, char* argv[]) | ||
| 38 | ("a,apple", "an apple", cxxopts::value<bool>(apple)) | 38 | ("a,apple", "an apple", cxxopts::value<bool>(apple)) |
| 39 | ("b,bob", "Bob") | 39 | ("b,bob", "Bob") |
| 40 | ("f,file", "File", cxxopts::value<std::vector<std::string>>()) | 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 | ("positional", | 43 | ("positional", |
| 43 | "Positional arguments: these are the arguments that are entered " | 44 | "Positional arguments: these are the arguments that are entered " |
| 44 | "without an option", cxxopts::value<std::string>()) | 45 | "without an option", cxxopts::value<std::string>()) |