diff options
author | Eyal Rozenberg <eyalroz@technion.ac.il> | 2020-07-23 10:27:04 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-23 10:27:04 +0300 |
commit | 5f43f4cbfee5d92560ece7811a2a44c763f9fb73 (patch) | |
tree | 594e3458dfb13d3b81073217538a5992d97e73a7 | |
parent | 1b660d56801283905b0f0fdd43e7e7ba3c5c396e (diff) |
Fixes #245: Mention the option name when throwing on "no value" (#246)
* Fixes #245:
* Added a new exception type: `option_has_no_value_exception`; throwing it when an option has no value we can cast with `as()`, instead of an `std::domain_error`.
* The `OptionValue` type now holds a pointer to the long option name (in its corresponding key within ParseResults's `m_results` field.
-rw-r--r-- | include/cxxopts.hpp | 20 | ||||
-rw-r--r-- | test/options.cpp | 2 |
2 files changed, 20 insertions, 2 deletions
diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 97381a9..dade761 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -443,6 +443,18 @@ namespace cxxopts } }; + class option_has_no_value_exception : public OptionException + { + public: + explicit option_has_no_value_exception(const std::string& option) + : OptionException( + option.empty() ? + ("Option " + LQUOTE + option + RQUOTE + " has no value") : + "Option has no value") + { + } + }; + class argument_incorrect_type : public OptionParseException { public: @@ -1077,6 +1089,7 @@ namespace cxxopts ensure_value(details); ++m_count; m_value->parse(text); + m_long_name = &details->long_name(); } void @@ -1084,6 +1097,7 @@ namespace cxxopts { ensure_value(details); m_default = true; + m_long_name = &details->long_name(); m_value->parse(); } @@ -1105,7 +1119,8 @@ namespace cxxopts as() const { if (m_value == nullptr) { - throw_or_mimic<std::domain_error>("No value"); + throw_or_mimic<option_has_no_value_exception>( + m_long_name == nullptr ? "" : *m_long_name); } #ifdef CXXOPTS_NO_RTTI @@ -1125,6 +1140,9 @@ namespace cxxopts } } + const std::string* m_long_name = nullptr; + // Holding this pointer is safe, since OptionValue's only exist in key-value pairs, + // where the key has the string we point to. std::shared_ptr<Value> m_value; size_t m_count = 0; bool m_default = false; diff --git a/test/options.cpp b/test/options.cpp index d3d3c7a..5026ea0 100644 --- a/test/options.cpp +++ b/test/options.cpp @@ -94,7 +94,7 @@ TEST_CASE("Basic options", "[options]") CHECK(arguments[2].key() == "value"); CHECK(arguments[3].key() == "av"); - CHECK_THROWS_AS(result["nothing"].as<std::string>(), std::domain_error&); + CHECK_THROWS_AS(result["nothing"].as<std::string>(), cxxopts::option_has_no_value_exception&); } TEST_CASE("Short options", "[options]") |