From: Brad Hubbard Date: Wed, 27 Jan 2016 01:18:16 +0000 (+1000) Subject: common: Allow config set with negative value X-Git-Tag: v10.0.4~3^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8b777a0c346bc70fd10d07e89368b3785b58f10e;p=ceph.git common: Allow config set with negative value A recent commit disabled negative values but they are required for variables such as filestore_merge_threshold. Fixes: #13829 Signed-off-by: Kefu Chai Signed-off-by: Brad Hubbard --- diff --git a/src/common/strtol.cc b/src/common/strtol.cc index ea39ba0b0f47..fdab2cfe9afe 100644 --- a/src/common/strtol.cc +++ b/src/common/strtol.cc @@ -14,10 +14,10 @@ #include "strtol.h" -#include -#include +#include +#include +#include #include -#include using std::ostringstream; @@ -129,14 +129,15 @@ float strict_strtof(const char *str, std::string *err) return ret; } -uint64_t strict_sistrtoll(const char *str, std::string *err) +template +T strict_si_cast(const char *str, std::string *err) { std::string s(str); if (s.empty()) { *err = "strict_sistrtoll: value not specified"; return 0; } - const char &u = s.at(s.size()-1); //str[std::strlen(str)-1]; + const char &u = s.back(); int m = 0; if (u == 'B') m = 0; @@ -155,30 +156,35 @@ uint64_t strict_sistrtoll(const char *str, std::string *err) else m = -1; - const char *v = NULL; if (m >= 0) - s = std::string(str, s.size()-1); - v = s.c_str(); - - long long r_ll = strict_strtoll(v, 10, err); + s.pop_back(); + else + m = 0; - if (r_ll < 0) { + long long ll = strict_strtoll(s.c_str(), 10, err); + if (ll < 0 && !std::numeric_limits::is_signed) { *err = "strict_sistrtoll: value should not be negative"; return 0; } + if (ll < (long long)std::numeric_limits::min() >> m) { + *err = "strict_sistrtoll: value seems to be too small"; + return 0; + } + if (ll > std::numeric_limits::max() >> m) { + *err = "strict_sistrtoll: value seems to be too large"; + return 0; - uint64_t r = r_ll; - if (err->empty() && m > 0) { - if (r > (std::numeric_limits::max() >> m)) { - *err = "strict_sistrtoll: value seems to be too large"; - return 0; - } - r <<= m; } - return r; + return (ll << m); } -template <> -uint64_t strict_si_cast(const char *str, std::string *err) { - return strict_sistrtoll(str, err); +template int strict_si_cast(const char *str, std::string *err); + +template long long strict_si_cast(const char *str, std::string *err); + +template uint64_t strict_si_cast(const char *str, std::string *err); + +uint64_t strict_sistrtoll(const char *str, std::string *err) +{ + return strict_si_cast(str, err); } diff --git a/src/common/strtol.h b/src/common/strtol.h index 5575ed7b390b..ed8656847ee7 100644 --- a/src/common/strtol.h +++ b/src/common/strtol.h @@ -31,21 +31,7 @@ float strict_strtof(const char *str, std::string *err); uint64_t strict_sistrtoll(const char *str, std::string *err); -template -Target strict_si_cast(const char *str, std::string *err) { - uint64_t ret = strict_sistrtoll(str, err); - if (!err->empty()) - return ret; - if (ret > (uint64_t)std::numeric_limits::max()) { - err->append("The option value '"); - err->append(str); - err->append("' seems to be too large"); - return 0; - } - return ret; -} - -template <> -uint64_t strict_si_cast(const char *str, std::string *err); +template +T strict_si_cast(const char *str, std::string *err); #endif