tfirst commit - 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 b9a184f61f01aca16e52978b132f09edef80f40b
 (HTM) Author: z3bra <willy@mailoo.org>
       Date:   Tue,  4 Nov 2014 00:17:47 +0100
       
       first commit
       
       Diffstat:
         A LICENSE                             |      14 ++++++++++++++
         A Makefile                            |      37 +++++++++++++++++++++++++++++++
         A README                              |      25 +++++++++++++++++++++++++
         A human.1                             |      42 +++++++++++++++++++++++++++++++
         A human.c                             |     125 +++++++++++++++++++++++++++++++
       
       5 files changed, 243 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/LICENSE b/LICENSE
       t@@ -0,0 +1,14 @@
       +            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 long
       + 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.
       +
 (DIR) diff --git a/Makefile b/Makefile
       t@@ -0,0 +1,37 @@
       +PREFIX:=/usr
       +MANPREFIX:=${PREFIX}/share/man
       +
       +CC = cc
       +LD= ${CC}
       +RM = rm
       +GZ = gzip
       +CFLAGS = -Wall -pedantic
       +LDFLAGS =
       +
       +.SUFFIXES: .c .o .gz
       +.PHONY : all clean install uninstall
       +
       +.c.o:
       +        @echo -e "CC $<"
       +        @${CC} -c ${CFLAGS} $< -o $@
       +
       +human: human.o
       +        @echo -e "LD human"
       +        @${LD} $^ -o $@ ${LDFLAGS}
       +
       +human.1.gz: human.1
       +        @echo "GZ $<"
       +        @${GZ} -c $< > $@
       +
       +all : human human.1.gz
       +
       +clean :
       +        ${RM} -f human *.o *.gz *~
       +
       +install: human human.1.gz
       +        install -D -m 0755 human ${DESTDIR}${PREFIX}/bin/human
       +        install -D -m 0644 human.1.gz ${DESTDIR}${MANPREFIX}/man1/human.1.gz
       +
       +uninstall:
       +        ${RM} ${DESTDIR}${PREFIX}/bin/human
       +        ${RM} ${DESTDIR}${MANPREFIX}/man1/human.1.gz
 (DIR) diff --git a/README b/README
       t@@ -0,0 +1,25 @@
       +╻ ╻╻ ╻┏┳┓┏━┓┏┓╻
       +┣━┫┃ ┃┃┃┃┣━┫┃┗┫
       +╹ ╹┗━┛╹ ╹╹ ╹╹ ╹
       +             -- by z3bra
       +========================
       +
       +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.
       +
       +    # convert 123456 to the best human factorisation
       +    human 123456
       +    120M
       +
       +    # output 2 decimals
       +    SCALE=2 human 123456
       +    120.56K
       +
       +    SCALE=3 human -m 123456
       +    0.118M
       +
       +Well, that's it (and that's enough !)
 (DIR) diff --git a/human.1 b/human.1
       t@@ -0,0 +1,42 @@
       +.TH human 1 2014-09-03 "v3.0" "Human nanual"
       +.SH NAME
       +human \- output a number in human-readable format
       +.SH SYNOPSIS
       +.B human
       +.RI [ \-hkmgt ] <number>
       +.SH DESCRIPTION
       +.PP
       +.B human
       +takes the number given as an argument, and output it in a human readable format.
       +.TP
       +.B \-h
       +Displays a help text
       +.TP
       +.B \-k, -m, -g, -t
       +Force output in, respectively, 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.
       +.SH EXAMPLES
       +.TP
       +\(buOutput a number in its best factorization form:
       +.EX
       +\fBhuman \fR12345
       +\fR12K
       +.EE
       +.TP
       +\(buOutput a number with \fI3\fR numbers after the decimal point:
       +.EX
       +\fRSCALE=\-3 \fBhuman \fR12345
       +\fR12.056K
       +.EE
       +.TP
       +\(buOutput a number in MiB, no matter what.
       +.EX
       +\fBhuman \fR-m 1234567890
       +1177M
       +.EE
       +.SH REPORTING BUGS
       +If you encounter any bugs, feel free to report them at \fIwilly@mailoo.org\fR
       +.SH AUTHORS / CONTRIBUTORS
       +Willy Goiffon is the main author.
 (DIR) diff --git a/human.c b/human.c
       t@@ -0,0 +1,125 @@
       +/*
       + *            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
       +
       +/* 
       + * calculate a power of number
       + * disclaimers: return no more than a "long" so use wisely...
       + * 
       + */
       +long power (long number, int pow)
       +{
       +    return pow > 0 ? power(number * 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':
       +                printf("usage: %s [-hkmgt] <number>\n", 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;
       +}