Commit b2e7efe7f4c2e738a42b0bceea2761ce32d6cc21

Authored by Jarryd Beck
1 parent 8844335d

positional arguments parse into multiple options

src/cxxopts.hpp
1 1 /*
2 2  
3   -Copyright (c) 2014 Jarryd Beck
  3 +Copyright (c) 2014, 2015 Jarryd Beck
4 4  
5 5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 6 of this software and associated documentation files (the "Software"), to deal
... ... @@ -244,6 +244,9 @@ namespace cxxopts
244 244 has_default() const = 0;
245 245  
246 246 virtual bool
  247 + is_container() const = 0;
  248 +
  249 + virtual bool
247 250 has_implicit() const = 0;
248 251  
249 252 virtual std::string
... ... @@ -436,6 +439,18 @@ namespace cxxopts
436 439 };
437 440  
438 441 template <typename T>
  442 + struct type_is_container
  443 + {
  444 + static constexpr bool value = false;
  445 + };
  446 +
  447 + template <typename T>
  448 + struct type_is_container<std::vector<T>>
  449 + {
  450 + static constexpr bool value = true;
  451 + };
  452 +
  453 + template <typename T>
439 454 class standard_value : public Value
440 455 {
441 456 public:
... ... @@ -463,6 +478,12 @@ namespace cxxopts
463 478 }
464 479 }
465 480  
  481 + bool
  482 + is_container() const
  483 + {
  484 + return type_is_container<T>::value;
  485 + }
  486 +
466 487 void
467 488 parse() const
468 489 {
... ... @@ -700,6 +721,10 @@ namespace cxxopts
700 721 parse_positional(std::string option);
701 722  
702 723 inline
  724 + void
  725 + parse_positional(std::vector<std::string> options);
  726 +
  727 + inline
703 728 std::string
704 729 help(const std::vector<std::string>& groups = {""}) const;
705 730  
... ... @@ -757,7 +782,8 @@ namespace cxxopts
757 782 String m_help_string;
758 783  
759 784 std::map<std::string, std::shared_ptr<OptionDetails>> m_options;
760   - std::string m_positional;
  785 + std::vector<std::string> m_positional;
  786 + std::vector<std::string>::iterator m_next_positional;
761 787  
762 788 //mapping from groups to help options
763 789 std::map<std::string, HelpGroupDetails> m_help;
... ... @@ -1005,9 +1031,14 @@ Options::add_to_option(const std::string&amp; option, const std::string&amp; arg)
1005 1031 bool
1006 1032 Options::consume_positional(std::string a)
1007 1033 {
1008   - if (m_positional.size() > 0)
  1034 + if (m_next_positional != m_positional.end())
1009 1035 {
1010   - add_to_option(m_positional, a);
  1036 + add_to_option(*m_next_positional, a);
  1037 +
  1038 + auto iter = m_options.find(*m_next_positional);
  1039 + if (iter != m_options.end() && !iter->second->value().is_container()) {
  1040 + ++m_next_positional;
  1041 + }
1011 1042 return true;
1012 1043 }
1013 1044 else
... ... @@ -1019,7 +1050,14 @@ Options::consume_positional(std::string a)
1019 1050 void
1020 1051 Options::parse_positional(std::string option)
1021 1052 {
1022   - m_positional = std::move(option);
  1053 + parse_positional(std::vector<std::string>{option});
  1054 +}
  1055 +
  1056 +void
  1057 +Options::parse_positional(std::vector<std::string> options)
  1058 +{
  1059 + m_positional = std::move(options);
  1060 + m_next_positional = m_positional.begin();
1023 1061 }
1024 1062  
1025 1063 void
... ...
src/example.cpp
... ... @@ -38,11 +38,12 @@ 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>>(), "FILE")
  41 + ("i,input", "Input", cxxopts::value<std::string>())
41 42 ("o,output", "Output file", cxxopts::value<std::string>()
42 43 ->default_value("a.out")->implicit_value("b.def"), "BIN")
43 44 ("positional",
44 45 "Positional arguments: these are the arguments that are entered "
45   - "without an option", cxxopts::value<std::string>())
  46 + "without an option", cxxopts::value<std::vector<std::string>>())
46 47 ("long-description",
47 48 "thisisareallylongwordthattakesupthewholelineandcannotbebrokenataspace")
48 49 ("help", "Print help")
... ... @@ -58,7 +59,7 @@ int main(int argc, char* argv[])
58 59 ("c,compile", "compile")
59 60 ("d,drop", "drop", cxxopts::value<std::vector<std::string>>());
60 61  
61   - options.parse_positional("positional");
  62 + options.parse_positional({"input", "output", "positional"});
62 63  
63 64 options.parse(argc, argv);
64 65  
... ... @@ -88,9 +89,9 @@ int main(int argc, char* argv[])
88 89 }
89 90 }
90 91  
91   - if (options.count("positional"))
  92 + if (options.count("input"))
92 93 {
93   - std::cout << "Positional = " << options["positional"].as<std::string>()
  94 + std::cout << "Input = " << options["input"].as<std::string>()
94 95 << std::endl;
95 96 }
96 97  
... ... @@ -100,6 +101,16 @@ int main(int argc, char* argv[])
100 101 << std::endl;
101 102 }
102 103  
  104 + if (options.count("positional"))
  105 + {
  106 + std::cout << "Positional = {";
  107 + auto& v = options["positional"].as<std::vector<std::string>>();
  108 + for (const auto& s : v) {
  109 + std::cout << s << ", ";
  110 + }
  111 + std::cout << "}" << std::endl;
  112 + }
  113 +
103 114 if (options.count("int"))
104 115 {
105 116 std::cout << "int = " << options["int"].as<int>() << std::endl;
... ...