diff options
author | Jakob Gruber <jakob.gruber@gmail.com> | 2011-02-20 19:38:32 +0100 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2011-04-20 17:29:32 -0500 |
commit | 3c8a448a2ff6b433059b1beb3a35cfd67c148d0c (patch) | |
tree | d97cf667508787562f35f0125f31396d63bee495 /src/pacman/util.c | |
parent | dcb6fb224dd3ac91c08369e9fbff12349b96e545 (diff) |
Add a utility function to humanize sizes
Converts the given size in bytes in two possible ways:
1) target_unit is specified (!= 0): size is converted to target unit.
2) target_unit is not specified (== '\0'): size is converted to the first
unit which will bring size to below 2048.
If specified, label will point to the long label ('MB') if long_labels is
set or the short label ('M') if it is not.
Dan: use '\0' rather than 0 for the special value as a matter of coding
style for char variables.
Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'src/pacman/util.c')
-rw-r--r-- | src/pacman/util.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/src/pacman/util.c b/src/pacman/util.c index cf33dabf..7080b2b7 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -522,9 +522,10 @@ void list_display_linebreak(const char *title, const alpm_list_t *list) void display_targets(const alpm_list_t *pkgs, int install) { char *str; + const char *label; + double size; const alpm_list_t *i; off_t isize = 0, dlsize = 0; - double mbisize = 0.0, mbdlsize = 0.0; alpm_list_t *targets = NULL; if(!pkgs) { @@ -545,19 +546,17 @@ void display_targets(const alpm_list_t *pkgs, int install) targets = alpm_list_add(targets, str); } - /* Convert byte sizes to MB */ - mbdlsize = (double)dlsize / (1024.0 * 1024.0); - mbisize = (double)isize / (1024.0 * 1024.0); - if(install) { pm_asprintf(&str, _("Targets (%d):"), alpm_list_count(targets)); list_display(str, targets); free(str); printf("\n"); - printf(_("Total Download Size: %.2f MB\n"), mbdlsize); + size = humanize_size(dlsize, 'M', 1, &label); + printf(_("Total Download Size: %.2f %s\n"), size, label); if(!(config->flags & PM_TRANS_FLAG_DOWNLOADONLY)) { - printf(_("Total Installed Size: %.2f MB\n"), mbisize); + size = humanize_size(isize, 'M', 1, &label); + printf(_("Total Installed Size: %.2f %s\n"), size, label); } } else { pm_asprintf(&str, _("Remove (%d):"), alpm_list_count(targets)); @@ -565,7 +564,8 @@ void display_targets(const alpm_list_t *pkgs, int install) free(str); printf("\n"); - printf(_("Total Removed Size: %.2f MB\n"), mbisize); + size = humanize_size(isize, 'M', 1, &label); + printf(_("Total Removed Size: %.2f %s\n"), size, label); } FREELIST(targets); @@ -606,6 +606,44 @@ static char *pkg_get_location(pmpkg_t *pkg) } } +/** Converts sizes in bytes into human readable units. + * + * @param bytes the size in bytes + * @param target_unit '\0' or a short label. If equal to one of the short unit + * labels ('B', 'K', ...) bytes is converted to target_unit; if '\0', the first + * unit which will bring the value to below a threshold of 2048 will be chosen. + * @param long_labels whether to use short ("K") or long ("KB") unit labels + * @param label will be set to the appropriate unit label + * + * @return the size in the appropriate unit + */ +double humanize_size(off_t bytes, const char target_unit, int long_labels, + const char **label) +{ + static const char *shortlabels[] = {"B", "K", "M", "G", "T", "P"}; + static const char *longlabels[] = {"B", "KB", "MB", "GB", "TB", "PB"}; + static const int unitcount = sizeof(shortlabels) / sizeof(shortlabels[0]); + + const char **labels = long_labels ? longlabels : shortlabels; + double val = (double)bytes; + int index; + + for(index = 0; index < unitcount - 1; index++) { + if(target_unit != '\0' && shortlabels[index][0] == target_unit) { + break; + } else if(target_unit == '\0' && val <= 2048.0) { + break; + } + val /= 1024.0; + } + + if(label) { + *label = labels[index]; + } + + return(val); +} + void print_packages(const alpm_list_t *packages) { const alpm_list_t *i; |