Commit 456ea951ab097c5efd555151c3c49698a8f51dd7

Authored by Baptiste Wicht
1 parent b343ad98

Add support for implicit values

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&amp; argc, char**&amp; 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&amp; argc, char**&amp; 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>())
... ...