summaryrefslogtreecommitdiff
path: root/Libraries/LibCore
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2020-11-05 15:57:22 -0500
committerAndreas Kling <kling@serenityos.org>2020-11-07 18:28:35 +0100
commitb143e604d71a202dafe57a6600a9991b883bffea (patch)
treeab5cdf7b786638df681eb585b395d591c63e75e8 /Libraries/LibCore
parente673abb93ff4d634d56b6df291d30409fbefa51a (diff)
downloadserenity-b143e604d71a202dafe57a6600a9991b883bffea.zip
LibCore: Add an ArgsParser::add_option() overload for doubles
Diffstat (limited to 'Libraries/LibCore')
-rw-r--r--Libraries/LibCore/ArgsParser.cpp41
-rw-r--r--Libraries/LibCore/ArgsParser.h1
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);