From c4ecaf21d59671ac7ec0bd26bd2c346c98c7771c Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Thu, 9 Dec 2010 21:54:17 +0100 Subject: partx: complete rewrite Co-Author: Karel Zak Signed-off-by: Davidlohr Bueso Signed-off-by: Karel Zak --- lib/strutils.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'lib/strutils.c') diff --git a/lib/strutils.c b/lib/strutils.c index dcae9f2d3..e8e868653 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -3,12 +3,15 @@ * Copyright (C) 2010 Davidlohr Bueso */ +#include #include #include #include #include #include #include +#include +#include static int do_scale_by_power (uintmax_t *x, int base, int power) { @@ -224,3 +227,49 @@ void strmode(mode_t mode, char *str) : (mode & S_IXOTH ? 'x' : '-')); str[10] = '\0'; } + +/* + * returns exponent (2^x=n) in range KiB..PiB + */ +static int get_exp(uint64_t n) +{ + int shft; + + for (shft = 10; shft <= 60; shft += 10) { + if (n < (1ULL << shft)) + break; + } + return shft - 10; +} + +char *size_to_human_string(uint64_t bytes) +{ + char buf[32]; + int dec, frac, exp; + const char *letters = "BKMGTP"; + char c; + + exp = get_exp(bytes); + c = *(letters + (exp ? exp / 10 : 0)); + dec = exp ? bytes / (1ULL << exp) : bytes; + frac = exp ? bytes % (1ULL << exp) : 0; + + if (frac) { + /* round */ + frac = (frac / (1ULL << (exp - 10)) + 50) / 100; + if (frac == 10) + dec++, frac = 0; + } + + if (frac) { + struct lconv const *l = localeconv(); + char *dp = l ? l->decimal_point : NULL; + + if (!dp || !*dp) + dp = "."; + snprintf(buf, sizeof(buf), "%d%s%d%c", dec, dp, frac, c); + } else + snprintf(buf, sizeof(buf), "%d%c", dec, c); + + return strdup(buf); +} -- cgit v1.2.3-55-g7522