From b143e604d71a202dafe57a6600a9991b883bffea Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 5 Nov 2020 15:57:22 -0500 Subject: [PATCH] LibCore: Add an ArgsParser::add_option() overload for doubles --- Libraries/LibCore/ArgsParser.cpp | 41 +++++++++++++++++++++++++------- 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 #include +static constexpr bool isnan(double __x) { return __builtin_isnan(__x); } + +static Optional 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);