allow print_size to print large numbers on 32-bit systems
authorTimur Tabi <timur@freescale.com>
Tue, 13 Apr 2010 18:16:03 +0000 (13:16 -0500)
committerWolfgang Denk <wd@denx.de>
Wed, 5 May 2010 20:17:34 +0000 (22:17 +0200)
Modify print_size() so that it can accept numbers larger than 4GB on 32-bit
systems.

Add support for display terabyte, petabyte, and exabyte sizes.  Change the
output to use International Electrotechnical Commission binary prefix standard.

Signed-off-by: Timur Tabi <timur@freescale.com>
include/common.h
lib/display_options.c

index df956bbb410652b32ee33ddb9a1a2590f35b292b..5591e1d04b0a51ae7f78830c0946dcbb54bd0d5c 100644 (file)
@@ -218,7 +218,7 @@ void        hang            (void) __attribute__ ((noreturn));
 /* */
 phys_size_t initdram (int);
 int    display_options (void);
-void   print_size (phys_size_t, const char *);
+void   print_size(unsigned long long, const char *);
 int    print_buffer (ulong addr, void* data, uint width, uint count, uint linelen);
 
 /* common/main.c */
index 08a7914a1d0bef542fd2314e3f8850a2a3e93c47..86df05d9e5dde65fd4e7a0f427c5f5acda031543 100644 (file)
@@ -39,25 +39,30 @@ int display_options (void)
 }
 
 /*
- * print sizes as "xxx kB", "xxx.y kB", "xxx MB", "xxx.y MB",
- * xxx GB, or xxx.y GB as needed; allow for optional trailing string
+ * print sizes as "xxx KiB", "xxx.y KiB", "xxx MiB", "xxx.y MiB",
+ * xxx GiB, xxx.y GiB, etc as needed; allow for optional trailing string
  * (like "\n")
  */
-void print_size (phys_size_t size, const char *s)
+void print_size(unsigned long long size, const char *s)
 {
        unsigned long m = 0, n;
-       unsigned long long d = 1 << 30;         /* 1 GB */
-       char  c = 'G';
-
-       if (size < d) {                 /* try MB */
-               c = 'M';
-               d = 1 << 20;
-               if (size < d) {         /* print in kB */
-                       c = 'k';
-                       d = 1 << 10;
+       static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'};
+       unsigned long long d = 1ULL << (10 * ARRAY_SIZE(names));
+       char c = 0;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(names); i++, d >>= 10) {
+               if (size >= d) {
+                       c = names[i];
+                       break;
                }
        }
 
+       if (!c) {
+               printf("%llu Bytes%s", size, s);
+               return;
+       }
+
        n = size / d;
 
        /* If there's a remainder, deal with it */
@@ -70,11 +75,11 @@ void print_size (phys_size_t size, const char *s)
                }
        }
 
-       printf ("%2ld", n);
+       printf ("%lu", n);
        if (m) {
                printf (".%ld", m);
        }
-       printf (" %cB%s", c, s);
+       printf (" %ciB%s", c, s);
 }
 
 /*