Commit c59e0c132cd955a11d77a83e4929f094a0bcd833

Authored by Long Deng
Committed by GitHub
1 parent f0f465b2

Solve arguments() showing empty keys when only short-only option exists (#318)

* Solve `arguments()` showing empty keys when there is only a short option.
include/cxxopts.hpp
... ... @@ -1287,6 +1287,13 @@ namespace cxxopts
1287 1287 return m_long;
1288 1288 }
1289 1289  
  1290 + CXXOPTS_NODISCARD
  1291 + const std::string&
  1292 + essential_name() const
  1293 + {
  1294 + return m_long.empty() ? m_short : m_long;
  1295 + }
  1296 +
1290 1297 size_t
1291 1298 hash() const
1292 1299 {
... ... @@ -2152,7 +2159,7 @@ OptionParser::parse_default(const std::shared_ptr<OptionDetails>& details)
2152 2159 // TODO: remove the duplicate code here
2153 2160 auto& store = m_parsed[details->hash()];
2154 2161 store.parse_default(details);
2155   - m_defaults.emplace_back(details->long_name(), details->value().get_default_value());
  2162 + m_defaults.emplace_back(details->essential_name(), details->value().get_default_value());
2156 2163 }
2157 2164  
2158 2165 inline
... ... @@ -2176,7 +2183,7 @@ OptionParser::parse_option
2176 2183 auto& result = m_parsed[hash];
2177 2184 result.parse(value, arg);
2178 2185  
2179   - m_sequential.emplace_back(value->long_name(), arg);
  2186 + m_sequential.emplace_back(value->essential_name(), arg);
2180 2187 }
2181 2188  
2182 2189 inline
... ...
test/options.cpp
... ... @@ -116,6 +116,11 @@ TEST_CASE("Short options", "[options]")
116 116 CHECK(result.count("a") == 1);
117 117 CHECK(result["a"].as<std::string>() == "value");
118 118  
  119 + auto& arguments = result.arguments();
  120 + REQUIRE(arguments.size() == 1);
  121 + CHECK(arguments[0].key() == "a");
  122 + CHECK(arguments[0].value() == "value");
  123 +
119 124 REQUIRE_THROWS_AS(options.add_options()("", "nothing option"),
120 125 cxxopts::invalid_option_format_error&);
121 126 }
... ... @@ -832,3 +837,54 @@ TEST_CASE(&quot;Parameter follow option&quot;, &quot;[parameter]&quot;) {
832 837 CHECK(job_values[2] == 10);
833 838 CHECK(job_values[3] == 5);
834 839 }
  840 +
  841 +TEST_CASE("Iterator", "[iterator]") {
  842 + cxxopts::Options options("tester", " - test iterating over parse result");
  843 +
  844 + options.add_options()
  845 + ("long", "a long option")
  846 + ("s,short", "a short option")
  847 + ("a", "a short-only option")
  848 + ("value", "an option with a value", cxxopts::value<std::string>())
  849 + ("default", "an option with default value", cxxopts::value<int>()->default_value("42"))
  850 + ("nothing", "won't exist", cxxopts::value<std::string>())
  851 + ;
  852 +
  853 + Argv argv({
  854 + "tester",
  855 + "--long",
  856 + "-s",
  857 + "-a",
  858 + "--value",
  859 + "value",
  860 + });
  861 +
  862 + auto** actual_argv = argv.argv();
  863 + auto argc = argv.argc();
  864 +
  865 + auto result = options.parse(argc, actual_argv);
  866 +
  867 + auto iter = result.begin();
  868 +
  869 + REQUIRE(iter != result.end());
  870 + CHECK(iter->key() == "long");
  871 + CHECK(iter->value() == "true");
  872 +
  873 + REQUIRE(++iter != result.end());
  874 + CHECK(iter->key() == "short");
  875 + CHECK(iter->value() == "true");
  876 +
  877 + REQUIRE(++iter != result.end());
  878 + CHECK(iter->key() == "a");
  879 + CHECK(iter->value() == "true");
  880 +
  881 + REQUIRE(++iter != result.end());
  882 + CHECK(iter->key() == "value");
  883 + CHECK(iter->value() == "value");
  884 +
  885 + REQUIRE(++iter != result.end());
  886 + CHECK(iter->key() == "default");
  887 + CHECK(iter->value() == "42");
  888 +
  889 + REQUIRE(++iter == result.end());
  890 +}
... ...