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:
}
}
-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)
// 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);
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:
}
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");
}
}
+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)
{
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);
"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("") == "");
== "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);