]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
refactor: Move Util::parse_size to util
authorJoel Rosdahl <joel@rosdahl.net>
Tue, 21 Feb 2023 20:34:18 +0000 (21:34 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 4 Mar 2023 09:10:20 +0000 (10:10 +0100)
src/Config.cpp
src/Util.cpp
src/Util.hpp
src/core/mainoptions.cpp
src/util/string.cpp
src/util/string.hpp
unittest/test_Util.cpp
unittest/test_util_string.cpp

index 1e55477372e6604469c24511642f4a530dfbdeb2..bf79acea8f0efc12028a05447e2ee1c7a0f1df4b 100644 (file)
@@ -1037,7 +1037,7 @@ Config::set_item(const std::string& key,
     break;
 
   case ConfigItem::max_size:
-    m_max_size = Util::parse_size(value);
+    m_max_size = util::value_or_throw<core::Error>(util::parse_size(value));
     break;
 
   case ConfigItem::msvc_dep_prefix:
index c9cf3cbb6624cf8f53ce944e344962b8662903a8..6ba1b3431d090df0764a38fd95f54a5d94863fd7 100644 (file)
@@ -980,47 +980,6 @@ parse_duration(std::string_view duration)
   }
 }
 
-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 core::Error(FMT("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 core::Error(FMT("invalid size: \"{}\"", value));
-    }
-  } else {
-    // Default suffix: G.
-    result *= 1000 * 1000 * 1000;
-  }
-  return static_cast<uint64_t>(result);
-}
-
 #ifndef _WIN32
 std::string
 read_link(const std::string& path)
index 7f7be73e2a57976ecd05fbbdeebfc464ec566d3c..d1a4796fc6422b394c03efb399f9928b1b743ae2 100644 (file)
@@ -277,11 +277,6 @@ std::string normalize_concrete_absolute_path(const std::string& path);
 // into seconds. Throws `core::Error` on error.
 uint64_t parse_duration(std::string_view duration);
 
-// 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 `core::Error` on parse error.
-uint64_t parse_size(const std::string& value);
-
 #ifndef _WIN32
 // Like readlink(2) but returns the string (or the empty string on failure).
 std::string read_link(const std::string& path);
index 40db41dccd69e8ea0be0dcd22785cf73ca354060..1fba40db792c1ffa1db2e78a0ea36f367c6bd45e 100644 (file)
@@ -485,7 +485,7 @@ process_main_options(int argc, const char* const* argv)
       break;
 
     case TRIM_MAX_SIZE:
-      trim_max_size = Util::parse_size(arg);
+      trim_max_size = util::value_or_throw<Error>(util::parse_size(arg));
       break;
 
     case TRIM_METHOD:
@@ -657,7 +657,7 @@ process_main_options(int argc, const char* const* argv)
     }
 
     case 'M': { // --max-size
-      uint64_t size = Util::parse_size(arg);
+      uint64_t size = util::value_or_throw<Error>(util::parse_size(arg));
       config.set_value_in_file(config.config_path(), "max_size", arg);
       if (size == 0) {
         PRINT_RAW(stdout, "Unset cache size limit\n");
index 914f1f7406ba50be03b19df015405d2a426bdad7..4ad3decda0d1f5d038ac2b56e15f4e1715b6fd35 100644 (file)
@@ -114,6 +114,48 @@ parse_signed(std::string_view value,
   }
 }
 
+nonstd::expected<uint64_t, std::string>
+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()) {
+    return nonstd::make_unexpected(FMT("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:
+      return nonstd::make_unexpected(FMT("invalid size: \"{}\"", value));
+    }
+  } else {
+    // Default suffix: G.
+    result *= 1000 * 1000 * 1000;
+  }
+
+  return static_cast<uint64_t>(result);
+}
+
 nonstd::expected<mode_t, std::string>
 parse_umask(std::string_view value)
 {
index 5154915dfd4361783acbfc4471468cc81468d746..7df40aada4f13d4b55768b32398511b0c964a5de 100644 (file)
@@ -77,6 +77,11 @@ parse_signed(std::string_view value,
              std::optional<int64_t> max_value = std::nullopt,
              std::string_view description = "integer");
 
+// 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.
+nonstd::expected<uint64_t, std::string> parse_size(const std::string& value);
+
 // Parse `value` (an octal integer).
 nonstd::expected<mode_t, std::string> parse_umask(std::string_view value);
 
index 9c54e0b4c6295dc72554d60efe9666b6ff025bbd..fd02076b756fb7eecfd58fed54e0c3902d191d33 100644 (file)
@@ -601,33 +601,6 @@ TEST_CASE("Util::parse_duration")
     "invalid suffix (supported: d (day) and s (second)): \"2\"");
 }
 
-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(Util::parse_size("9MB") == 9 * 1000 * 1000);
-  CHECK(Util::parse_size("9MiB") == 9 * 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::remove_extension")
 {
   CHECK(Util::remove_extension("") == "");
index 26fcab246ea6125add616c138b706ad30f8689e0..12746d080768e42ad9eb47b41801955a21f0eb90 100644 (file)
@@ -183,6 +183,33 @@ TEST_CASE("util::parse_signed")
         == "banana must be between 1 and 2");
 }
 
+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(*util::parse_size("9MB") == 9 * 1000 * 1000);
+  CHECK(*util::parse_size("9MiB") == 9 * 1024 * 1024);
+
+  CHECK(util::parse_size("").error() == "invalid size: \"\"");
+  CHECK(util::parse_size("x").error() == "invalid size: \"x\"");
+  CHECK(util::parse_size("10x").error() == "invalid size: \"10x\"");
+}
+
 TEST_CASE("util::parse_umask")
 {
   CHECK(util::parse_umask("1") == 1U);