return result;
}
-uint64_t
-parse_cache_size(const std::string& value)
-{
- uint64_t result;
- if (!parse_size_with_suffix(value.c_str(), &result)) {
- throw Error(fmt::format("invalid size: \"{}\"", value));
- }
- return result;
-}
-
std::string
format_cache_size(uint64_t value)
{
break;
case ConfigItem::max_size:
- m_max_size = parse_cache_size(value);
+ m_max_size = Util::parse_size(value);
break;
case ConfigItem::path:
return result;
}
+uint64_t
+parse_size(const std::string& value)
+{
+ errno = 0;
+
+ char* p;
+ double result = strtod(value.c_str(), &p);
+ if (errno != 0 || result < 0 || p == value.c_str() || value.empty()) {
+ throw Error(fmt::format("invalid size: \"{}\"", value));
+ }
+
+ while (isspace(*p)) {
+ ++p;
+ }
+
+ if (*p != '\0') {
+ unsigned multiplier = *(p + 1) == 'i' ? 1024 : 1000;
+ switch (*p) {
+ case 'T':
+ result *= multiplier;
+ // Fallthrough.
+ case 'G':
+ result *= multiplier;
+ // Fallthrough.
+ case 'M':
+ result *= multiplier;
+ // Fallthrough.
+ case 'K':
+ case 'k':
+ result *= multiplier;
+ break;
+ default:
+ throw Error(fmt::format("invalid size: \"{}\"", value));
+ }
+ } else {
+ // Default suffix: G.
+ result *= 1000 * 1000 * 1000;
+ }
+ return static_cast<uint64_t>(result);
+}
+
uint32_t
parse_uint32(const std::string& value)
{
// Throws `Error` on error.
int parse_int(const std::string& value);
+// Parse a "size value", i.e. a string that can end in k, M, G, T (10-based
+// suffixes) or Ki, Mi, Gi, Ti (2-based suffixes). For backward compatibility, K
+// is also recognized as a synonym of k. Throws `Error` on parse error.
+uint64_t parse_size(const std::string& value);
+
// Parse a string into an unsigned 32-bit integer.
//
// Throws `Error` on error.
}
case 'M': { // --max-size
- uint64_t size;
- if (!parse_size_with_suffix(optarg, &size)) {
- fatal("invalid size: %s", optarg);
- }
+ uint64_t size = Util::parse_size(optarg);
Config::set_value_in_file(
ctx.config.primary_config_path(), "max_size", optarg);
if (size == 0) {
}
}
-// Parse a "size value", i.e. a string that can end in k, M, G, T (10-based
-// suffixes) or Ki, Mi, Gi, Ti (2-based suffixes). For backward compatibility,
-// K is also recognized as a synonym of k.
-bool
-parse_size_with_suffix(const char* str, uint64_t* size)
-{
- errno = 0;
-
- char* p;
- double x = strtod(str, &p);
- if (errno != 0 || x < 0 || p == str || *str == '\0') {
- return false;
- }
-
- while (isspace(*p)) {
- ++p;
- }
-
- if (*p != '\0') {
- unsigned multiplier = *(p + 1) == 'i' ? 1024 : 1000;
- switch (*p) {
- case 'T':
- x *= multiplier;
- // Fallthrough.
- case 'G':
- x *= multiplier;
- // Fallthrough.
- case 'M':
- x *= multiplier;
- // Fallthrough.
- case 'K':
- case 'k':
- x *= multiplier;
- break;
- default:
- return false;
- }
- } else {
- // Default suffix: G.
- x *= 1000 * 1000 * 1000;
- }
- *size = (uint64_t)x;
- return true;
-}
-
#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R)
// localtime_r replacement. (Mingw-w64 has an inline localtime_r which is not
// detected by AC_CHECK_FUNCS.)
char* x_strndup(const char* s, size_t n);
void x_setenv(const char* name, const char* value);
void x_unsetenv(const char* name);
-bool parse_size_with_suffix(const char* str, uint64_t* size);
#ifndef HAVE_LOCALTIME_R
struct tm* localtime_r(const time_t* timep, struct tm* result);
#endif
test_argprocessing.cpp
test_compopt.cpp
test_hashutil.cpp
- test_legacy_util.cpp
test_logging.cpp)
if(INODE_CACHE_SUPPORTED)
}
}
+TEST_CASE("Util::parse_size")
+{
+ CHECK(Util::parse_size("0") == 0);
+ CHECK(Util::parse_size("42") // Default suffix: G
+ == static_cast<uint64_t>(42) * 1000 * 1000 * 1000);
+ CHECK(Util::parse_size("78k") == 78 * 1000);
+ CHECK(Util::parse_size("78K") == 78 * 1000);
+ CHECK(Util::parse_size("1.1 M") == (int64_t(1.1 * 1000 * 1000)));
+ CHECK(Util::parse_size("438.55M") == (int64_t(438.55 * 1000 * 1000)));
+ CHECK(Util::parse_size("1 G") == 1 * 1000 * 1000 * 1000);
+ CHECK(Util::parse_size("2T")
+ == static_cast<uint64_t>(2) * 1000 * 1000 * 1000 * 1000);
+ CHECK(Util::parse_size("78 Ki") == 78 * 1024);
+ CHECK(Util::parse_size("1.1Mi") == (int64_t(1.1 * 1024 * 1024)));
+ CHECK(Util::parse_size("438.55 Mi") == (int64_t(438.55 * 1024 * 1024)));
+ CHECK(Util::parse_size("1Gi") == 1 * 1024 * 1024 * 1024);
+ CHECK(Util::parse_size("2 Ti")
+ == static_cast<uint64_t>(2) * 1024 * 1024 * 1024 * 1024);
+
+ CHECK_THROWS_WITH(Util::parse_size(""), "invalid size: \"\"");
+ CHECK_THROWS_WITH(Util::parse_size("x"), "invalid size: \"x\"");
+ CHECK_THROWS_WITH(Util::parse_size("10x"), "invalid size: \"10x\"");
+}
+
TEST_CASE("Util::parse_uint32")
{
CHECK(Util::parse_uint32("0") == 0);
+++ /dev/null
-// Copyright (C) 2010-2020 Joel Rosdahl and other contributors
-//
-// See doc/AUTHORS.adoc for a complete list of contributors.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// this program; if not, write to the Free Software Foundation, Inc., 51
-// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-#include "../src/legacy_util.hpp"
-
-#include "third_party/doctest.h"
-
-#define CHECK_STR_EQ_FREE2(a, b) \
- do { \
- CHECK(strcmp((a), (b)) == 0); \
- free(b); \
- } while (false)
-
-TEST_SUITE_BEGIN("legacy_util");
-
-TEST_CASE("parse_size_with_suffix")
-{
- uint64_t size;
- size_t i;
- struct
- {
- const char* size;
- int64_t expected;
- } sizes[] = {
- {"0", 0},
- {"42", (int64_t)42 * 1000 * 1000 * 1000}, // Default suffix: G
-
- {"78k", 78 * 1000},
- {"78K", 78 * 1000},
- {"1.1 M", (int64_t)(1.1 * 1000 * 1000)},
- {"438.55M", (int64_t)(438.55 * 1000 * 1000)},
- {"1 G", 1 * 1000 * 1000 * 1000},
- {"2T", (int64_t)2 * 1000 * 1000 * 1000 * 1000},
-
- {"78 Ki", 78 * 1024},
- {"1.1Mi", (int64_t)(1.1 * 1024 * 1024)},
- {"438.55 Mi", (int64_t)(438.55 * 1024 * 1024)},
- {"1Gi", 1 * 1024 * 1024 * 1024},
- {"2 Ti", (int64_t)2 * 1024 * 1024 * 1024 * 1024},
- };
-
- for (i = 0; i < ARRAY_SIZE(sizes); ++i) {
- CHECK(parse_size_with_suffix(sizes[i].size, &size));
- CHECK(size == sizes[i].expected);
- }
-}
-
-TEST_SUITE_END();