diff options
author | Davidlohr Bueso | 2010-12-09 21:54:17 +0100 |
---|---|---|
committer | Karel Zak | 2010-12-09 21:54:17 +0100 |
commit | c4ecaf21d59671ac7ec0bd26bd2c346c98c7771c (patch) | |
tree | cd89a4e8048653d693b7d9f4a1507479d1ad7314 /lib/strutils.c | |
parent | mount: be more explicit about --move in mount.8 (diff) | |
download | kernel-qcow2-util-linux-c4ecaf21d59671ac7ec0bd26bd2c346c98c7771c.tar.gz kernel-qcow2-util-linux-c4ecaf21d59671ac7ec0bd26bd2c346c98c7771c.tar.xz kernel-qcow2-util-linux-c4ecaf21d59671ac7ec0bd26bd2c346c98c7771c.zip |
partx: complete rewrite
Co-Author: Karel Zak <kzak@redhat.com>
Signed-off-by: Davidlohr Bueso <dave@gnu.org>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib/strutils.c')
-rw-r--r-- | lib/strutils.c | 49 |
1 files changed, 49 insertions, 0 deletions
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 <dave@gnu.org> */ +#include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include <ctype.h> #include <errno.h> #include <err.h> #include <sys/stat.h> +#include <locale.h> +#include <string.h> 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); +} |