summaryrefslogtreecommitdiff
path: root/src/pacman/util.c
diff options
context:
space:
mode:
authorJakob Gruber <jakob.gruber@gmail.com>2011-02-20 19:38:32 +0100
committerDan McGee <dan@archlinux.org>2011-04-20 17:29:32 -0500
commit3c8a448a2ff6b433059b1beb3a35cfd67c148d0c (patch)
treed97cf667508787562f35f0125f31396d63bee495 /src/pacman/util.c
parentdcb6fb224dd3ac91c08369e9fbff12349b96e545 (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.c54
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;