From ab318200dbc6f594e3c6169c7ee8d8249d75dbe4 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 8 Oct 2020 20:13:57 +0200 Subject: [PATCH] config/{Data,Block}: use With() in GetUnsigned(), GetPositive() --- src/config/Block.cxx | 19 ++----------------- src/config/Data.cxx | 42 ++++++++++-------------------------------- src/config/Parser.cxx | 33 +++++++++++++++++++++++++++++++++ src/config/Parser.hxx | 18 ++++++++++++++++++ 4 files changed, 63 insertions(+), 49 deletions(-) diff --git a/src/config/Block.cxx b/src/config/Block.cxx index 82cca9d80..2c3da5ace 100644 --- a/src/config/Block.cxx +++ b/src/config/Block.cxx @@ -47,28 +47,13 @@ BlockParam::GetIntValue() const unsigned BlockParam::GetUnsignedValue() const { - const char *const s = value.c_str(); - char *endptr; - unsigned long value2 = strtoul(s, &endptr, 0); - if (endptr == s || *endptr != 0) - throw FormatRuntimeError("Not a valid number in line %i", line); - - return (unsigned)value2; + return With(ParseUnsigned); } unsigned BlockParam::GetPositiveValue() const { - const char *const s = value.c_str(); - char *endptr; - unsigned long value2 = strtoul(s, &endptr, 0); - if (endptr == s || *endptr != 0) - throw FormatRuntimeError("Not a valid number in line %i", line); - - if (value2 <= 0) - throw FormatRuntimeError("Number in line %i must be positive", line); - - return (unsigned)value2; + return With(ParsePositive); } bool diff --git a/src/config/Data.cxx b/src/config/Data.cxx index 479b8fa6b..143ef5612 100644 --- a/src/config/Data.cxx +++ b/src/config/Data.cxx @@ -84,43 +84,21 @@ ConfigData::GetPath(ConfigOption option) const unsigned ConfigData::GetUnsigned(ConfigOption option, unsigned default_value) const { - const auto *param = GetParam(option); - long value; - char *endptr; - - if (param == nullptr) - return default_value; - - const char *const s = param->value.c_str(); - value = strtol(s, &endptr, 0); - if (endptr == s || *endptr != 0 || value < 0) - throw FormatRuntimeError("Not a valid non-negative number in line %i", - param->line); - - return (unsigned)value; + return With(option, [default_value](const char *s){ + return s != nullptr + ? ParseUnsigned(s) + : default_value; + }); } unsigned ConfigData::GetPositive(ConfigOption option, unsigned default_value) const { - const auto *param = GetParam(option); - long value; - char *endptr; - - if (param == nullptr) - return default_value; - - const char *const s = param->value.c_str(); - value = strtol(s, &endptr, 0); - if (endptr == s || *endptr != 0) - throw FormatRuntimeError("Not a valid number in line %i", - param->line); - - if (value <= 0) - throw FormatRuntimeError("Not a positive number in line %i", - param->line); - - return (unsigned)value; + return With(option, [default_value](const char *s){ + return s != nullptr + ? ParsePositive(s) + : default_value; + }); } bool diff --git a/src/config/Parser.cxx b/src/config/Parser.cxx index 1d79dca8e..89c3458c1 100644 --- a/src/config/Parser.cxx +++ b/src/config/Parser.cxx @@ -22,6 +22,8 @@ #include "util/StringStrip.hxx" #include "util/StringUtil.hxx" +#include + bool ParseBool(const char *value) { @@ -37,6 +39,37 @@ ParseBool(const char *value) throw FormatRuntimeError(R"(Not a valid boolean ("yes" or "no"): "%s")", value); } +long +ParseLong(const char *s) +{ + char *endptr; + long value = strtol(s, &endptr, 10); + if (endptr == s || *endptr != 0) + throw std::runtime_error("Failed to parse number"); + + return value; +} + +unsigned +ParseUnsigned(const char *s) +{ + auto value = ParseLong(s); + if (value < 0) + throw std::runtime_error("Value must not be negative"); + + return (unsigned)value; +} + +unsigned +ParsePositive(const char *s) +{ + auto value = ParseLong(s); + if (value <= 0) + throw std::runtime_error("Value must be positive"); + + return (unsigned)value; +} + template static size_t Multiply(size_t value) diff --git a/src/config/Parser.hxx b/src/config/Parser.hxx index 93fccaa53..b448709cd 100644 --- a/src/config/Parser.hxx +++ b/src/config/Parser.hxx @@ -28,6 +28,24 @@ bool ParseBool(const char *value); +/** + * Throws on error. + */ +long +ParseLong(const char *s); + +/** + * Throws on error. + */ +unsigned +ParseUnsigned(const char *s); + +/** + * Throws on error. + */ +unsigned +ParsePositive(const char *s); + /** * Parse a string as a byte size. *