tHuman is now written in C: http://git.z3bra.org/cgit.cgi/human - scripts - various script and utils
 (HTM) git clone git://z3bra.org/scripts
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit 2619b1941d1a1f2dd473982732023d1af9836c56
 (DIR) parent b5d37ef55899d306eeccaee0411d57c685ee93ce
 (HTM) Author: z3bra <willy@mailoo.org>
       Date:   Fri,  7 Nov 2014 16:30:14 +0100
       
       Human is now written in C: http://git.z3bra.org/cgit.cgi/human
       
       Diffstat:
         A human                               |     130 +++++++++++++++++++++++++++++++
       
       1 file changed, 130 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/human b/human
       t@@ -0,0 +1,130 @@
       +#!/usr/bin/tcc -run
       +/*
       + *            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
       + *                    Version 2, December 2004
       + *
       + * Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
       + *
       + * Everyone is permitted to copy and distribute verbatim or modified
       + * copies of this license document, and changing it is allowed as double
       + * as the name is changed.
       + *
       + *            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
       + *   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
       + *
       + *  0. You just DO WHAT THE FUCK YOU WANT TO.
       + *
       + */
       +
       +#include <err.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <getopt.h>
       +#include <limits.h>
       +
       +#define TERA 1099511627776
       +#define GIGA 1073741824
       +#define MEGA 1048576
       +#define KILO 1024
       +
       +#define DEFAULT_SCALE 0
       +
       +/* dumb user is dumb.. */
       +void usage (char *progname)
       +{
       +    printf("usage: %s [-hkmgt] <number>\n", progname);
       +    return; /* void */
       +}
       +
       +/* 
       + * calculate a power of number
       + * disclaimers: return no more than a "long" so use wisely...
       + * 
       + */
       +long power (long number, int pow)
       +{
       +    return pow > 0 ? number * power(number, pow - 1) : number;
       +}
       +
       +/*
       + * read the environment varaible "SCALE" and returns its value.
       + * returns DEFAULT_SCALE if it does not return a number.
       + *
       + */
       +int getscale()
       +{
       +    /* would you rather use getenv() twice ? or allocate a pointer ? */
       +    char *scale = NULL;
       +    scale = getenv("SCALE");
       +
       +    /* in atoi, we trust. maybe. */
       +    return scale ? atoi(scale) : DEFAULT_SCALE;
       +}
       +
       +/*
       + * calculate the best factorization for a number, depending on its value.
       + * actual max factorisation is 1024^3 (TiB)
       + *
       + */
       +char factorize (double number)
       +{
       +    return number >= TERA ? 'T' : 
       +           number >= GIGA ? 'G' :
       +           number >= MEGA ? 'M' :
       +           number >= KILO ? 'K' :
       +           0;
       +}
       +
       +/*
       + * calculate a human-readable version of the given number, depending of the
       + * factorisation level given.
       + *
       + */
       +double humanize (double number, char factor)
       +{
       +    int pow = 0;
       +
       +    /* cascading switch. note a lack of "break" statements */
       +    switch (factor) {
       +        case 'T' : pow++;
       +        case 'G' : pow++;
       +        case 'M' : pow++;
       +        case 'K' : break;
       +        default  : return number;
       +    }    
       +
       +    /* return the number divided by the correct factorization level */
       +    return number /= power(1024, pow);
       +}
       +
       +int main (int argc, char **argv)
       +{
       +    char ch, fac = 0;
       +    double number = 0;
       +
       +    /* only switches are use to force factorization */
       +    while ((ch = getopt(argc, argv, "hkmgt")) != -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;
       +        }
       +    }
       +
       +    /* get the number. if there is not, strtold will return 0 */
       +    number = strtold(argv[argc - 1], NULL);
       +
       +    if (number <= 0) {
       +        errx(EXIT_FAILURE, "I ain't gonna do it. 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);
       +
       +    return 0;
       +}