diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh index 8e4861232..ab36b7c05 100644 --- a/src/libmain/shared.hh +++ b/src/libmain/shared.hh @@ -52,23 +52,7 @@ template N getIntArg(const string & opt, { ++i; if (i == end) throw UsageError(format("'%1%' requires an argument") % opt); - string s = *i; - N multiplier = 1; - if (allowUnit && !s.empty()) { - char u = std::toupper(*s.rbegin()); - if (std::isalpha(u)) { - if (u == 'K') multiplier = 1ULL << 10; - else if (u == 'M') multiplier = 1ULL << 20; - else if (u == 'G') multiplier = 1ULL << 30; - else if (u == 'T') multiplier = 1ULL << 40; - else throw UsageError(format("invalid unit specifier '%1%'") % u); - s.resize(s.size() - 1); - } - } - N n; - if (!string2Int(s, n)) - throw UsageError(format("'%1%' requires an integer argument") % opt); - return n * multiplier; + return parseSize(*i, allowUnit); } diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 9f239bff3..fd09f8f2b 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -359,7 +359,7 @@ bool statusOk(int status); /* Parse a string into an integer. */ -template bool string2Int(const string & s, N & n) +template bool string2Int(const string & s, N & n) { if (string(s, 0, 1) == "-" && !std::numeric_limits::is_signed) return false; @@ -368,6 +368,27 @@ template bool string2Int(const string & s, N & n) return str && str.get() == EOF; } +template +N parseSize(std::string s, bool allowUnit = true) +{ + N multiplier = 1; + if (allowUnit && !s.empty()) { + char u = std::toupper(*s.rbegin()); + if (std::isalpha(u)) { + if (u == 'K') multiplier = 1ULL << 10; + else if (u == 'M') multiplier = 1ULL << 20; + else if (u == 'G') multiplier = 1ULL << 30; + else if (u == 'T') multiplier = 1ULL << 40; + else throw Error("invalid unit specifier '%1%'", u); + s.resize(s.size() - 1); + } + } + N n; + if (!string2Int(s, n)) + throw Error("'%s' is not an integer", s); + return n * multiplier; +} + /* Parse a string into a float. */ template bool string2Float(const string & s, N & n) {