diff options
-rw-r--r-- | doc/manual/nix-store.xml | 8 | ||||
-rw-r--r-- | src/libmain/shared.hh | 21 | ||||
-rw-r--r-- | src/nix-store/nix-store.cc | 2 |
3 files changed, 25 insertions, 6 deletions
diff --git a/doc/manual/nix-store.xml b/doc/manual/nix-store.xml index 63ddef28e1b9..416438a0bd45 100644 --- a/doc/manual/nix-store.xml +++ b/doc/manual/nix-store.xml @@ -296,8 +296,12 @@ options control what gets deleted and in what order: <varlistentry><term><option>--max-freed</option> <replaceable>bytes</replaceable></term> <listitem><para>Keep deleting paths until at least - <replaceable>bytes</replaceable> bytes have been - deleted, then stop.</para></listitem> + <replaceable>bytes</replaceable> bytes have been deleted, then + stop. The argument <replaceable>bytes</replaceable> can be + followed by the multiplicative suffix <literal>K</literal>, + <literal>M</literal>, <literal>G</literal> or + <literal>T</literal>, denoting KiB, MiB, GiB or TiB + units.</para></listitem> </varlistentry> diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh index ff89e86389c2..b29b08bb597e 100644 --- a/src/libmain/shared.hh +++ b/src/libmain/shared.hh @@ -4,6 +4,8 @@ #include <signal.h> +#include <locale> + /* These are not implemented here, but must be implemented by a program linking against libmain. */ @@ -35,14 +37,27 @@ void printMissing(const PathSet & willBuild, unsigned long long downloadSize, unsigned long long narSize); template<class N> N getIntArg(const string & opt, - Strings::iterator & i, const Strings::iterator & end) + Strings::iterator & i, const Strings::iterator & end, bool allowUnit) { ++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(*i, n)) + if (!string2Int(s, n)) throw UsageError(format("`%1%' requires an integer argument") % opt); - return n; + return n * multiplier; } /* Show the manual page for the specified program. */ diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 365ffa19a0d8..e969a3b71e33 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -619,7 +619,7 @@ static void opGC(Strings opFlags, Strings opArgs) else if (*i == "--print-dead") options.action = GCOptions::gcReturnDead; else if (*i == "--delete") options.action = GCOptions::gcDeleteDead; else if (*i == "--max-freed") { - long long maxFreed = getIntArg<long long>(*i, i, opFlags.end()); + long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true); options.maxFreed = maxFreed >= 0 ? maxFreed : 0; } else throw UsageError(format("bad sub-operation `%1%' in GC") % *i); |