diff options
author | charlydelta <46491912+charlydelta@users.noreply.github.com> | 2019-08-08 01:25:34 +0300 |
---|---|---|
committer | jarro2783 <jarro.2783@gmail.com> | 2019-08-08 01:25:34 +0300 |
commit | 34784b01f7bdb989e56f268b632091a8a8738906 (patch) | |
tree | 3825c128c2b3ca40142f44987152b10d48773a0d | |
parent | fce82fb0350c5c334c9593800dd55a6c2c797f9e (diff) |
Fix: Make CXXOPTS_NO_EXCEPTIONS compilable and print messages (#196)
Fix CXXOPTS_NO_EXCEPTIONS so that it doesn't warn about unused parameters, and print out error messages.
-rw-r--r-- | include/cxxopts.hpp | 189 |
1 files changed, 63 insertions, 126 deletions
diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 0e1aa40..9cde72d 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -467,6 +467,26 @@ namespace cxxopts } }; + template <typename T> + void throw_or_mimic(const std::string& text) + { + static_assert(std::is_base_of<std::exception, T>::value, + "throw_or_mimic only works on std::exception and " + "deriving classes"); + +#ifndef CXXOPTS_NO_EXCEPTIONS + // If CXXOPTS_NO_EXCEPTIONS is not defined, just throw + throw T{text}; +#else + // Otherwise manually instantiate the exception, print what() to stderr, + // and abort + T exception{text}; + std::cerr << exception.what() << std::endl; + std::cerr << "Aborting (exceptions disabled)..." << std::endl; + std::abort(); +#endif + } + namespace values { namespace @@ -495,22 +515,14 @@ namespace cxxopts { if (u > static_cast<U>((std::numeric_limits<T>::min)())) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic<argument_incorrect_type>(text); } } else { if (u > static_cast<U>((std::numeric_limits<T>::max)())) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic<argument_incorrect_type>(text); } } } @@ -544,13 +556,10 @@ namespace cxxopts template <typename R, typename T> T - checked_negate(T&&, const std::string& text, std::false_type) + checked_negate(T&& t, const std::string& text, std::false_type) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic<argument_incorrect_type>(text); + return t; } template <typename T> @@ -562,11 +571,7 @@ namespace cxxopts if (match.length() == 0) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic<argument_incorrect_type>(text); } if (match.length(4) > 0) @@ -603,21 +608,13 @@ namespace cxxopts } else { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic<argument_incorrect_type>(text); } US next = result * base + digit; if (result > next) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic<argument_incorrect_type>(text); } result = next; @@ -643,11 +640,7 @@ namespace cxxopts std::stringstream in(text); in >> value; if (!in) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic<argument_incorrect_type>(text); } } @@ -727,11 +720,7 @@ namespace cxxopts return; } -#ifndef CXXOPTS_NO_EXCEPTIONS - throw argument_incorrect_type(text); -#else - std::abort(); -#endif + throw_or_mimic<argument_incorrect_type>(text); } inline @@ -1108,11 +1097,7 @@ namespace cxxopts as() const { if (m_value == nullptr) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw std::domain_error("No value"); -#else - std::abort(); -#endif + throw_or_mimic<std::domain_error>("No value"); } #ifdef CXXOPTS_NO_RTTI @@ -1207,11 +1192,7 @@ namespace cxxopts if (iter == m_options->end()) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw option_not_present_exception(option); -#else - std::abort(); -#endif + throw_or_mimic<option_not_present_exception>(option); } auto riter = m_results.find(iter->second); @@ -1269,8 +1250,8 @@ namespace cxxopts std::vector<KeyValue> m_sequential; }; - - struct Option + + struct Option { Option ( @@ -1290,7 +1271,7 @@ namespace cxxopts std::string desc_; std::shared_ptr<const Value> value_; std::string arg_help_; - }; + }; class Options { @@ -1343,20 +1324,20 @@ namespace cxxopts OptionAdder add_options(std::string group = ""); - - void + + void add_options - ( - const std::string& group, - std::initializer_list<Option> options - ); - - void - add_option - ( - const std::string& group, - const Option& option - ); + ( + const std::string& group, + std::initializer_list<Option> options + ); + + void + add_option + ( + const std::string& group, + const Option& option + ); void add_option @@ -1597,15 +1578,15 @@ ParseResult::ParseResult } inline -void +void Options::add_options ( const std::string &group, std::initializer_list<Option> options -) +) { OptionAdder option_adder(*this, group); - for (const auto &option: options) + for (const auto &option: options) { option_adder(option.opts_, option.desc_, option.value_, option.arg_help_); } @@ -1633,11 +1614,7 @@ OptionAdder::operator() if (result.empty()) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw invalid_option_format_error(opts); -#else - std::abort(); -#endif + throw_or_mimic<invalid_option_format_error>(opts); } const auto& short_match = result[2]; @@ -1645,18 +1622,10 @@ OptionAdder::operator() if (!short_match.length() && !long_match.length()) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw invalid_option_format_error(opts); -#else - std::abort(); -#endif + throw_or_mimic<invalid_option_format_error>(opts); } else if (long_match.length() == 1 && short_match.length()) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw invalid_option_format_error(opts); -#else - std::abort(); -#endif + throw_or_mimic<invalid_option_format_error>(opts); } auto option_names = [] @@ -1729,11 +1698,7 @@ ParseResult::checked_parse_arg } else { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw missing_argument_exception(name); -#else - std::abort(); -#endif + throw_or_mimic<missing_argument_exception>(name); } } else @@ -1758,11 +1723,7 @@ ParseResult::add_to_option(const std::string& option, const std::string& arg) if (iter == m_options->end()) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw option_not_exists_exception(option); -#else - std::abort(); -#endif + throw_or_mimic<option_not_exists_exception>(option); } parse_option(iter->second, option, arg); @@ -1800,11 +1761,7 @@ ParseResult::consume_positional(std::string a) } else { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw option_not_exists_exception(*m_next_positional); -#else - std::abort(); -#endif + throw_or_mimic<option_not_exists_exception>(*m_next_positional); } } @@ -1872,11 +1829,7 @@ ParseResult::parse(int& argc, char**& argv) // but if it starts with a `-`, then it's an error if (argv[current][0] == '-' && argv[current][1] != '\0') { if (!m_allow_unrecognised) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw option_syntax_exception(argv[current]); -#else - std::abort(); -#endif + throw_or_mimic<option_syntax_exception>(argv[current]); } } @@ -1913,11 +1866,7 @@ ParseResult::parse(int& argc, char**& argv) else { //error -#ifndef CXXOPTS_NO_EXCEPTIONS - throw option_not_exists_exception(name); -#else - std::abort(); -#endif + throw_or_mimic<option_not_exists_exception>(name); } } @@ -1935,11 +1884,7 @@ ParseResult::parse(int& argc, char**& argv) else { //error -#ifndef CXXOPTS_NO_EXCEPTIONS - throw option_requires_argument_exception(name); -#else - std::abort(); -#endif + throw_or_mimic<option_requires_argument_exception>(name); } } } @@ -1962,11 +1907,7 @@ ParseResult::parse(int& argc, char**& argv) else { //error -#ifndef CXXOPTS_NO_EXCEPTIONS - throw option_not_exists_exception(name); -#else - std::abort(); -#endif + throw_or_mimic<option_not_exists_exception>(name); } } @@ -2033,7 +1974,7 @@ Options::add_option const Option& option ) { - add_options(group, {option}); + add_options(group, {option}); } inline @@ -2084,11 +2025,7 @@ Options::add_one_option if (!in.second) { -#ifndef CXXOPTS_NO_EXCEPTIONS - throw option_exists_error(option); -#else - std::abort(); -#endif + throw_or_mimic<option_exists_error>(option); } } |