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;
+}