Skip to content

Commit

Permalink
Solve arguments() showing empty keys when only short-only option exis…
Browse files Browse the repository at this point in the history
…ts (#318)

* Solve `arguments()` showing empty keys when there is only a short option.
  • Loading branch information
ldeng-ustc committed May 11, 2022
1 parent f0f465b commit c59e0c1
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
11 changes: 9 additions & 2 deletions include/cxxopts.hpp
Expand Up @@ -1287,6 +1287,13 @@ namespace cxxopts
return m_long;
}

CXXOPTS_NODISCARD
const std::string&
essential_name() const
{
return m_long.empty() ? m_short : m_long;
}

size_t
hash() const
{
Expand Down Expand Up @@ -2152,7 +2159,7 @@ OptionParser::parse_default(const std::shared_ptr<OptionDetails>& details)
// TODO: remove the duplicate code here
auto& store = m_parsed[details->hash()];
store.parse_default(details);
m_defaults.emplace_back(details->long_name(), details->value().get_default_value());
m_defaults.emplace_back(details->essential_name(), details->value().get_default_value());
}

inline
Expand All @@ -2176,7 +2183,7 @@ OptionParser::parse_option
auto& result = m_parsed[hash];
result.parse(value, arg);

m_sequential.emplace_back(value->long_name(), arg);
m_sequential.emplace_back(value->essential_name(), arg);
}

inline
Expand Down
56 changes: 56 additions & 0 deletions test/options.cpp
Expand Up @@ -116,6 +116,11 @@ TEST_CASE("Short options", "[options]")
CHECK(result.count("a") == 1);
CHECK(result["a"].as<std::string>() == "value");

auto& arguments = result.arguments();
REQUIRE(arguments.size() == 1);
CHECK(arguments[0].key() == "a");
CHECK(arguments[0].value() == "value");

REQUIRE_THROWS_AS(options.add_options()("", "nothing option"),
cxxopts::invalid_option_format_error&);
}
Expand Down Expand Up @@ -832,3 +837,54 @@ TEST_CASE("Parameter follow option", "[parameter]") {
CHECK(job_values[2] == 10);
CHECK(job_values[3] == 5);
}

TEST_CASE("Iterator", "[iterator]") {
cxxopts::Options options("tester", " - test iterating over parse result");

options.add_options()
("long", "a long option")
("s,short", "a short option")
("a", "a short-only option")
("value", "an option with a value", cxxopts::value<std::string>())
("default", "an option with default value", cxxopts::value<int>()->default_value("42"))
("nothing", "won't exist", cxxopts::value<std::string>())
;

Argv argv({
"tester",
"--long",
"-s",
"-a",
"--value",
"value",
});

auto** actual_argv = argv.argv();
auto argc = argv.argc();

auto result = options.parse(argc, actual_argv);

auto iter = result.begin();

REQUIRE(iter != result.end());
CHECK(iter->key() == "long");
CHECK(iter->value() == "true");

REQUIRE(++iter != result.end());
CHECK(iter->key() == "short");
CHECK(iter->value() == "true");

REQUIRE(++iter != result.end());
CHECK(iter->key() == "a");
CHECK(iter->value() == "true");

REQUIRE(++iter != result.end());
CHECK(iter->key() == "value");
CHECK(iter->value() == "value");

REQUIRE(++iter != result.end());
CHECK(iter->key() == "default");
CHECK(iter->value() == "42");

REQUIRE(++iter == result.end());
}

0 comments on commit c59e0c1

Please sign in to comment.