Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/libbb/human_readable.c

    r1765 r2725  
    2525 *      Some code to omit the decimal point and tenths digit is sketched out
    2626 *      and "#if 0"'d below.
     27 *
     28 * Licensed under GPLv2, see file LICENSE in this source tree.
    2729 */
    2830
    2931#include "libbb.h"
    3032
    31 const char *make_human_readable_str(unsigned long long size,
     33const char* FAST_FUNC make_human_readable_str(unsigned long long val,
    3234    unsigned long block_size, unsigned long display_unit)
    3335{
    34     /* The code will adjust for additional (appended) units */
    35     static const char zero_and_units[] ALIGN1 = { '0', 0, 'k', 'M', 'G', 'T' };
    36     static const char fmt[] ALIGN1 = "%llu";
    37     static const char fmt_tenths[] ALIGN1 = "%llu.%d%c";
     36    static const char unit_chars[] ALIGN1 = {
     37        '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'
     38    };
    3839
    39     static char str[21] ALIGN1;  /* Sufficient for 64 bit unsigned integers */
     40    static char *str;
    4041
    41     unsigned long long val;
    42     int frac;
     42    unsigned frac; /* 0..9 - the fractional digit */
    4343    const char *u;
    44     const char *f;
     44    const char *fmt;
    4545
    46     u = zero_and_units;
    47     f = fmt;
     46    if (val == 0)
     47        return "0";
     48
     49    fmt = "%llu";
     50    if (block_size > 1)
     51        val *= block_size;
    4852    frac = 0;
    49 
    50     val = size * block_size;
    51     if (val == 0) {
    52         return u;
    53     }
     53    u = unit_chars;
    5454
    5555    if (display_unit) {
    56         val += display_unit/2;  /* Deal with rounding */
    57         val /= display_unit;    /* Don't combine with the line above!!! */
     56        val += display_unit/2;  /* Deal with rounding */
     57        val /= display_unit;    /* Don't combine with the line above! */
     58        /* will just print it as ulonglong (below) */
    5859    } else {
    59         ++u;
    6060        while ((val >= 1024)
    61          && (u < zero_and_units + sizeof(zero_and_units) - 1)
     61         /* && (u < unit_chars + sizeof(unit_chars) - 1) - always true */
    6262        ) {
    63             f = fmt_tenths;
    64             ++u;
    65             frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024;
     63            fmt = "%llu.%u%c";
     64            u++;
     65            frac = (((unsigned)val % 1024) * 10 + 1024/2) / 1024;
    6666            val /= 1024;
    6767        }
    68         if (frac >= 10) {       /* We need to round up here. */
     68        if (frac >= 10) { /* we need to round up here */
    6969            ++val;
    7070            frac = 0;
    7171        }
    72 #if 0
    73         /* Sample code to omit decimal point and tenths digit. */
    74         if (/* no_tenths */ 1) {
     72#if 1
     73        /* If block_size is 0, dont print fractional part */
     74        if (block_size == 0) {
    7575            if (frac >= 5) {
    7676                ++val;
    7777            }
    78             f = "%llu%*c" /* fmt_no_tenths */;
     78            fmt = "%llu%*c";
    7979            frac = 1;
    8080        }
     
    8282    }
    8383
    84     /* If f==fmt then 'frac' and 'u' are ignored. */
    85     snprintf(str, sizeof(str), f, val, frac, *u);
    86 
     84    if (!str) {
     85        /* sufficient for any width of val */
     86        str = xmalloc(sizeof(val)*3 + 2 + 3);
     87    }
     88    sprintf(str, fmt, val, frac, *u);
    8789    return str;
    8890}
     91
     92
     93/* vda's implementations of the similar idea */
     94
     95/* Convert unsigned long long value into compact 5-char representation.
     96 * String is not terminated (buf[5] is untouched) */
     97void FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale)
     98{
     99    const char *fmt;
     100    char c;
     101    unsigned v, u, idx = 0;
     102
     103    if (ul > 99999) { // do not scale if 99999 or less
     104        ul *= 10;
     105        do {
     106            ul /= 1024;
     107            idx++;
     108        } while (ul >= 100000);
     109    }
     110    v = ul; // ullong divisions are expensive, avoid them
     111
     112    fmt = " 123456789";
     113    u = v / 10;
     114    v = v % 10;
     115    if (!idx) {
     116        // 99999 or less: use "12345" format
     117        // u is value/10, v is last digit
     118        c = buf[0] = " 123456789"[u/1000];
     119        if (c != ' ') fmt = "0123456789";
     120        c = buf[1] = fmt[u/100%10];
     121        if (c != ' ') fmt = "0123456789";
     122        c = buf[2] = fmt[u/10%10];
     123        if (c != ' ') fmt = "0123456789";
     124        buf[3] = fmt[u%10];
     125        buf[4] = "0123456789"[v];
     126    } else {
     127        // value has been scaled into 0..9999.9 range
     128        // u is value, v is 1/10ths (allows for 92.1M format)
     129        if (u >= 100) {
     130            // value is >= 100: use "1234M', " 123M" formats
     131            c = buf[0] = " 123456789"[u/1000];
     132            if (c != ' ') fmt = "0123456789";
     133            c = buf[1] = fmt[u/100%10];
     134            if (c != ' ') fmt = "0123456789";
     135            v = u % 10;
     136            u = u / 10;
     137            buf[2] = fmt[u%10];
     138        } else {
     139            // value is < 100: use "92.1M" format
     140            c = buf[0] = " 123456789"[u/10];
     141            if (c != ' ') fmt = "0123456789";
     142            buf[1] = fmt[u%10];
     143            buf[2] = '.';
     144        }
     145        buf[3] = "0123456789"[v];
     146        buf[4] = scale[idx]; /* typically scale = " kmgt..." */
     147    }
     148}
     149
     150/* Convert unsigned long long value into compact 4-char
     151 * representation. Examples: "1234", "1.2k", " 27M", "123T"
     152 * String is not terminated (buf[4] is untouched) */
     153void FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale)
     154{
     155    const char *fmt;
     156    char c;
     157    unsigned v, u, idx = 0;
     158
     159    if (ul > 9999) { // do not scale if 9999 or less
     160        ul *= 10;
     161        do {
     162            ul /= 1024;
     163            idx++;
     164        } while (ul >= 10000);
     165    }
     166    v = ul; // ullong divisions are expensive, avoid them
     167
     168    fmt = " 123456789";
     169    u = v / 10;
     170    v = v % 10;
     171    if (!idx) {
     172        // 9999 or less: use "1234" format
     173        // u is value/10, v is last digit
     174        c = buf[0] = " 123456789"[u/100];
     175        if (c != ' ') fmt = "0123456789";
     176        c = buf[1] = fmt[u/10%10];
     177        if (c != ' ') fmt = "0123456789";
     178        buf[2] = fmt[u%10];
     179        buf[3] = "0123456789"[v];
     180    } else {
     181        // u is value, v is 1/10ths (allows for 9.2M format)
     182        if (u >= 10) {
     183            // value is >= 10: use "123M', " 12M" formats
     184            c = buf[0] = " 123456789"[u/100];
     185            if (c != ' ') fmt = "0123456789";
     186            v = u % 10;
     187            u = u / 10;
     188            buf[1] = fmt[u%10];
     189        } else {
     190            // value is < 10: use "9.2M" format
     191            buf[0] = "0123456789"[u];
     192            buf[1] = '.';
     193        }
     194        buf[2] = "0123456789"[v];
     195        buf[3] = scale[idx]; /* typically scale = " kmgt..." */
     196    }
     197}
Note: See TracChangeset for help on using the changeset viewer.