Commit 456ea951ab097c5efd555151c3c49698a8f51dd7

Authored by Baptiste Wicht
1 parent b343ad98

Add support for implicit values

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&amp; argc, char**&amp; argv) @@ -799,8 +846,7 @@ Options::parse(int&amp; argc, char**&amp; 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&amp; argc, char**&amp; argv) @@ -841,9 +887,7 @@ Options::parse(int&amp; argc, char**&amp; 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>())