diff options
author | Nico Weber <thakis@chromium.org> | 2020-11-05 15:57:22 -0500 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-11-07 18:28:35 +0100 |
commit | b143e604d71a202dafe57a6600a9991b883bffea (patch) | |
tree | ab5cdf7b786638df681eb585b395d591c63e75e8 /Libraries/LibCore | |
parent | e673abb93ff4d634d56b6df291d30409fbefa51a (diff) | |
download | serenity-b143e604d71a202dafe57a6600a9991b883bffea.zip |
LibCore: Add an ArgsParser::add_option() overload for doubles
Diffstat (limited to 'Libraries/LibCore')
-rw-r--r-- | Libraries/LibCore/ArgsParser.cpp | 41 | ||||
-rw-r--r-- | Libraries/LibCore/ArgsParser.h | 1 |
2 files changed, 33 insertions, 9 deletions
diff --git a/Libraries/LibCore/ArgsParser.cpp b/Libraries/LibCore/ArgsParser.cpp index 9a66e70195..c47cd88d4f 100644 --- a/Libraries/LibCore/ArgsParser.cpp +++ b/Libraries/LibCore/ArgsParser.cpp @@ -32,6 +32,17 @@ #include <stdio.h> #include <string.h> +static constexpr bool isnan(double __x) { return __builtin_isnan(__x); } + +static Optional<double> convert_to_double(const char* s) +{ + char* p; + double v = strtod(s, &p); + if (isnan(v) || p == s) + return {}; + return v; +} + namespace Core { ArgsParser::ArgsParser() @@ -289,6 +300,24 @@ void ArgsParser::add_option(int& value, const char* help_string, const char* lon add_option(move(option)); } +void ArgsParser::add_option(double& value, const char* help_string, const char* long_name, char short_name, const char* value_name) +{ + Option option { + true, + help_string, + long_name, + short_name, + value_name, + [&value](const char* s) { + auto opt = convert_to_double(s); + value = opt.value_or(0.0); + return opt.has_value(); + } + }; + add_option(move(option)); +} + + void ArgsParser::add_positional_argument(Arg&& arg) { m_positional_args.append(move(arg)); @@ -325,8 +354,6 @@ void ArgsParser::add_positional_argument(int& value, const char* help_string, co add_positional_argument(move(arg)); } -static constexpr bool isnan(double __x) { return __builtin_isnan(__x); } - void ArgsParser::add_positional_argument(double& value, const char* help_string, const char* name, Required required) { Arg arg { @@ -335,13 +362,9 @@ void ArgsParser::add_positional_argument(double& value, const char* help_string, required == Required::Yes ? 1 : 0, 1, [&value](const char* s) { - char* p; - double v = strtod(s, &p); - bool valid_value = !isnan(v) && p != s; - if (valid_value) { - value = v; - } - return valid_value; + auto opt = convert_to_double(s); + value = opt.value_or(0.0); + return opt.has_value(); } }; add_positional_argument(move(arg)); diff --git a/Libraries/LibCore/ArgsParser.h b/Libraries/LibCore/ArgsParser.h index 007310c7fe..59362cc013 100644 --- a/Libraries/LibCore/ArgsParser.h +++ b/Libraries/LibCore/ArgsParser.h @@ -73,6 +73,7 @@ public: void add_option(bool& value, const char* help_string, const char* long_name, char short_name); void add_option(const char*& value, const char* help_string, const char* long_name, char short_name, const char* value_name); void add_option(int& value, const char* help_string, const char* long_name, char short_name, const char* value_name); + void add_option(double& value, const char* help_string, const char* long_name, char short_name, const char* value_name); void add_positional_argument(Arg&&); void add_positional_argument(const char*& value, const char* help_string, const char* name, Required required = Required::Yes); |