Commit c59e0c132cd955a11d77a83e4929f094a0bcd833
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.
Showing
2 changed files
with
65 additions
and
2 deletions
include/cxxopts.hpp
| @@ -1287,6 +1287,13 @@ namespace cxxopts | @@ -1287,6 +1287,13 @@ namespace cxxopts | ||
| 1287 | return m_long; | 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 | size_t | 1297 | size_t |
| 1291 | hash() const | 1298 | hash() const |
| 1292 | { | 1299 | { |
| @@ -2152,7 +2159,7 @@ OptionParser::parse_default(const std::shared_ptr<OptionDetails>& details) | @@ -2152,7 +2159,7 @@ OptionParser::parse_default(const std::shared_ptr<OptionDetails>& details) | ||
| 2152 | // TODO: remove the duplicate code here | 2159 | // TODO: remove the duplicate code here |
| 2153 | auto& store = m_parsed[details->hash()]; | 2160 | auto& store = m_parsed[details->hash()]; |
| 2154 | store.parse_default(details); | 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 | inline | 2165 | inline |
| @@ -2176,7 +2183,7 @@ OptionParser::parse_option | @@ -2176,7 +2183,7 @@ OptionParser::parse_option | ||
| 2176 | auto& result = m_parsed[hash]; | 2183 | auto& result = m_parsed[hash]; |
| 2177 | result.parse(value, arg); | 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 | inline | 2189 | inline |
test/options.cpp
| @@ -116,6 +116,11 @@ TEST_CASE("Short options", "[options]") | @@ -116,6 +116,11 @@ TEST_CASE("Short options", "[options]") | ||
| 116 | CHECK(result.count("a") == 1); | 116 | CHECK(result.count("a") == 1); |
| 117 | CHECK(result["a"].as<std::string>() == "value"); | 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 | REQUIRE_THROWS_AS(options.add_options()("", "nothing option"), | 124 | REQUIRE_THROWS_AS(options.add_options()("", "nothing option"), |
| 120 | cxxopts::invalid_option_format_error&); | 125 | cxxopts::invalid_option_format_error&); |
| 121 | } | 126 | } |
| @@ -832,3 +837,54 @@ TEST_CASE("Parameter follow option", "[parameter]") { | @@ -832,3 +837,54 @@ TEST_CASE("Parameter follow option", "[parameter]") { | ||
| 832 | CHECK(job_values[2] == 10); | 837 | CHECK(job_values[2] == 10); |
| 833 | CHECK(job_values[3] == 5); | 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 | +} |