tAdd two-way conversion and -b flag - human - print numbers in human-readable format
 (HTM) git clone git://z3bra.org/human
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 875338685d3d412069ae68583114a97e2b7d4c52
 (DIR) parent e4cf962033ae7483d8db97e14c07e41b78a65110
 (HTM) Author: z3bra <willyatmailoodotorg>
       Date:   Fri, 23 Oct 2015 12:56:06 +0200
       
       Add two-way conversion and -b flag
       
       The utility can now convert down to bytes, and understand number
       suffixes as B, K, M, G and T, to convert number from these factorization
       levels. For example:
       
           human -b 123M
           128974848
       
       Diffstat:
         M README                              |       7 +++++--
         M human.1                             |      12 +++++++++---
         M human.c                             |      46 +++++++++++++++++++++----------
       
       3 files changed, 45 insertions(+), 20 deletions(-)
       ---
 (DIR) diff --git a/README b/README
       t@@ -8,8 +8,7 @@ Human is a small program which translate numbers into a human readable format.
        By default, it tries to detect the best factorisation, but you can force its
        output.
        
       -You can adjust the number of decimals by tweaking the environment variable
       -$SCALE.
       +You can adjust the number of decimals by with the `SCALE` environment variable.
        
            # convert 123456 to the best human factorisation
            human 123456
       t@@ -22,4 +21,8 @@ $SCALE.
            SCALE=3 human -m 123456
            0.118M
        
       +    # convert from a different factorization level
       +    SCALE=6 human -g 123M
       +    0.120117G
       +
        Well, that's it (and that's enough !)
 (DIR) diff --git a/human.1 b/human.1
       t@@ -3,7 +3,7 @@
        human \- output a number in human-readable format
        .SH SYNOPSIS
        .B human
       -.RI [ \-hkmgt ] <number>
       +.RI [ \-hbkmgt ] <number>
        .SH DESCRIPTION
        .PP
        .B human
       t@@ -12,8 +12,8 @@ takes the number given as an argument, and output it in a human readable format.
        .B \-h
        Displays a help text
        .TP
       -.B \-k, -m, -g, -t
       -Force output in, respectively, KiB, MiB, GiB or TiB.
       +.B \-b, -k, -m, -g, -t
       +Force output in, respectively, Bytes, KiB, MiB, GiB or TiB.
        .SH ENVIRONMENT
        .B SCALE
        The special variable SCALE will allow you to choose how many numbers you want after the decimal point.
       t@@ -36,6 +36,12 @@ The special variable SCALE will allow you to choose how many numbers you want af
        \fBhuman \fR-m 1234567890
        1177M
        .EE
       +.TP
       +\(buConvert a number from Mib to bytes
       +.EX
       +\fBhuman \fR-b 128M
       +134217728
       +.EE
        .SH REPORTING BUGS
        If you encounter any bugs, feel free to report them at \fIwilly@mailoo.org\fR
        .SH AUTHORS / CONTRIBUTORS
 (DIR) diff --git a/human.c b/human.c
       t@@ -20,6 +20,7 @@
        #include <stdlib.h>
        #include <getopt.h>
        #include <limits.h>
       +#include <string.h>
        
        #define TERA 1099511627776
        #define GIGA 1073741824
       t@@ -28,11 +29,16 @@
        
        #define DEFAULT_SCALE 0
        
       -/* dumb user is dumb.. */
       +/*
       + * Help, I need somebody 
       + * Help, not just anybody 
       + * Help, you know I need someone 
       + * Help!
       + *
       + */
        void usage (char *progname)
        {
       -    printf("usage: %s [-hkmgt] <number>\n", progname);
       -    return; /* void */
       +    printf("usage: %s [-hbkmgt] <number>\n", progname);
        }
        
        /* 
       t@@ -42,7 +48,7 @@ void usage (char *progname)
         */
        long power (long number, int pow)
        {
       -    return pow > 0 ? number * power(number, pow - 1) : number;
       +    return pow > 0 ? number * power(number, pow - 1) : 1;
        }
        
        /*
       t@@ -83,12 +89,12 @@ double humanize (double number, char factor)
        {
            int pow = 0;
        
       -    /* cascading switch. note a lack of "break" statements */
       +    /* cascading switch. note the lack of "break" statements */
            switch (factor) {
                case 'T' : pow++;
                case 'G' : pow++;
                case 'M' : pow++;
       -        case 'K' : break;
       +        case 'K' : pow++; break;
                default  : return number;
            }    
        
       t@@ -98,32 +104,42 @@ double humanize (double number, char factor)
        
        int main (int argc, char **argv)
        {
       -    char ch, fac = 0;
       +    char ch, pow = 0, fac = 0;
            double number = 0;
        
            /* only switches are use to force factorization */
       -    while ((ch = getopt(argc, argv, "hkmgt")) != -1) {
       +    while ((ch = getopt(argc, argv, "hbkmgt")) != -1) {
                switch (ch) {
                    case 'h': usage(argv[0]); exit(0); break;
       -            case 't': fac ='T'; break;
       -            case 'g': fac ='G'; break;
       -            case 'm': fac ='M'; break;
       -            case 'k': fac ='K'; break;
       +            case 't': fac = 'T'; break;
       +            case 'g': fac = 'G'; break;
       +            case 'm': fac = 'M'; break;
       +            case 'k': fac = 'K'; break;
       +            case 'b': fac = 'B'; break;
                }
            }
        
       -    /* get the number. if there is not, strtold will return 0 */
       +    switch (argv[argc - 1][strnlen(argv[argc - 1],32) - 1]) {
       +        case 'T': pow++;
       +        case 'G': pow++;
       +        case 'M': pow++;
       +        case 'K': pow++;
       +        case 'B': argv[argc - 1][strnlen(argv[argc - 1],32) - 1] = 0;
       +    }
       +
       +    /* get the number and convert it to bytes. If there is none, strtold will return 0 */
            number = strtold(argv[argc - 1], NULL);
       +    number *= power(1024, pow);
        
            if (number <= 0) {
       -        errx(EXIT_FAILURE, "I ain't gonna do it. Deal with it.");
       +        errx(EXIT_FAILURE, "I ain't gonna do that. Deal with it.");
            }
        
            /* use explicit factorization. otherwise, guess the best one */
            fac = fac > 0 ? fac : factorize(number);
        
            /* actually print the result, isn't that what we're here for after all ? */
       -    printf("%.*f%c\n", getscale(), humanize(number, fac), fac);
       +    printf("%.*f%c\n", getscale(), humanize(number, fac), fac == 'B' ? 0 : fac);
        
            return 0;
        }