humanize.c (2025B)
- // Collection of Unix tools, comparable to coreutils
- // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
- #define _DEFAULT_SOURCE
- // strtonum
- #define _OPENBSD_SOURCE
- // On non-BSDs use libbsd
- #include <err.h> // errx
- #include <errno.h> // EINVAL, ERANGE
- #include <limits.h> // LLONG_MIN, LLONG_MAX
- #include <stdbool.h> // bool
- #include <stdio.h> // fprintf
- #include <stdlib.h> // strtonum
- #include <string.h> // strerror
- #include <unistd.h> // opt*, getopt
- void
- dtosi(double num, char *buf, size_t bufsize, bool iec)
- {
- char *si_prefixes[9] = {"", "k", "M", "G", "T", "P", "E", "Z", "Y"};
- char *iec_prefixes[9] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"};
- int div = iec ? 1024 : 1000;
- char **prefixes = iec ? iec_prefixes : si_prefixes;
- unsigned quotient = 0;
- while(num > div && quotient < 9)
- {
- num /= div;
- quotient += 1;
- }
- snprintf(buf, bufsize, "%g %s", num, prefixes[quotient]);
- }
- static void
- usage()
- {
- fprintf(stderr, "Usage: humanize [-bd] number\n");
- }
- int
- main(int argc, char *argv[])
- {
- // default to -d
- bool iec = false;
- int c = -1;
- while((c = getopt(argc, argv, ":bd")) != -1)
- {
- switch(c)
- {
- case 'b':
- iec = true;
- break;
- case 'd':
- iec = false;
- break;
- case ':':
- fprintf(stderr, "Error: Missing operand for option: '-%c'\n", optopt);
- usage();
- return 1;
- case '?':
- fprintf(stderr, "Error: Unrecognised option: '-%c'\n", optopt);
- usage();
- return 1;
- }
- }
- argc -= optind;
- argv += optind;
- if(argc < 1)
- {
- usage();
- return 1;
- }
- for(int argi = 0; argi < argc; argi++)
- {
- const char *errstr = NULL;
- char buf[32] = "";
- // 1024^(6+1) goes higher than long long; don't ask for the moon
- long long n = strtonum(argv[argi], LLONG_MIN, LLONG_MAX, &errstr);
- if(errstr)
- {
- errx(1, "strtonum: %s is %s", argv[argi], errstr);
- }
- dtosi(n, buf, 32, iec);
- printf("%s\n", buf);
- }
- return 0;
- }