commit: 83e4725713546b8b662811d5051011bf0a73c105
parent 8b3ca2ff9a235e980663cbd3cd6d30598f3745e2
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Mon, 5 Jun 2023 12:02:53 +0200
cmd/humanize: Add -t to manage durations
Diffstat:
3 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/cmd/humanize.1 b/cmd/humanize.1
@@ -1,7 +1,7 @@
.\" Collection of Unix tools, comparable to coreutils
-.\" Copyright 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+.\" Copyright 2017-2023 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
.\" SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
-.Dd 2022-05-08
+.Dd 2023-06-05
.Dt HUMANIZE 1
.Os
.Sh NAME
@@ -9,7 +9,7 @@
.Nd format numbers into human readable form
.Sh SYNOPSIS
.Nm
-.Op Fl db
+.Op Fl dbt
.Ar number ...
.Sh DESCRIPTION
Takes each
@@ -21,6 +21,9 @@ It supports the following options:
Divide by 1024, typically used for bytes.
.It Fl d
Divide by 1000, this is the default but made explicit in case of changes without breaking scripts.
+.It Fl t
+.Ar number
+represents time duration in seconds.
.El
.Sh EXIT STATUS
.Ex -std
diff --git a/cmd/humanize.c b/cmd/humanize.c
@@ -3,11 +3,12 @@
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
#define _POSIX_C_SOURCE 200809L
+
#include <err.h> // errx
#include <errno.h> // EINVAL, ERANGE
#include <limits.h> // LLONG_MIN, LLONG_MAX
#include <stdbool.h> // bool
-#include <stdio.h> // fprintf, perror
+#include <stdio.h> // fprintf, perror, sscanf
#include <stdlib.h> // strtonum
#include <unistd.h> // opt*, getopt
@@ -36,17 +37,17 @@ dtosi(double num, char *buf, size_t bufsize, bool iec)
static void
usage()
{
- fprintf(stderr, "Usage: humanize [-bd] number\n");
+ fprintf(stderr, "Usage: humanize [-bdt] number\n");
}
int
main(int argc, char *argv[])
{
// default to -d
- bool iec = false;
+ bool iec = false, time = false;
int c = -1;
- while((c = getopt(argc, argv, ":bd")) != -1)
+ while((c = getopt(argc, argv, ":bdt")) != -1)
{
switch(c)
{
@@ -56,6 +57,9 @@ main(int argc, char *argv[])
case 'd':
iec = false;
break;
+ case 't':
+ time = true;
+ break;
case ':':
fprintf(stderr, "humanize: Error: Missing operand for option: '-%c'\n", optopt);
usage();
@@ -81,6 +85,41 @@ main(int argc, char *argv[])
const char *errstr = NULL;
char buf[32] = "";
+ if(time)
+ {
+ int year = 0, month = 0, mday = 0, hour = 0, min = 0, sec = 0;
+ long int epoch = 0;
+
+ if(sscanf(argv[argi], "%ld", &epoch) < 1)
+ {
+ perror("humanize: sscanf");
+ return 1;
+ }
+
+ year = epoch / 31556926; // round(year)
+ epoch %= 31556926;
+ month = epoch / 2629743; // year/12
+ epoch %= 2629743;
+ mday = epoch / 86400;
+ epoch %= 86400;
+
+ hour = epoch / 3600;
+ epoch %= 3600;
+ min = epoch / 60;
+ epoch %= 60;
+ sec = epoch;
+
+ if(year > 0) printf("%d年 ", year);
+ if(month > 0) printf("%d月 ", month);
+ if(mday > 0) printf("%d日 ", mday);
+ if(hour > 0) printf("%dh ", hour);
+ if(min > 0) printf("%dm ", min);
+ if(sec > 0) printf("%ds", sec);
+ printf("\n");
+
+ continue;
+ }
+
errno = 0;
long long n = strtoll(argv[argi], NULL, 10);
if(n == LLONG_MIN)
diff --git a/test-cmd/humanize b/test-cmd/humanize
@@ -57,13 +57,24 @@ seven_body() {
atf_test_case noarg
noarg_body() {
- atf_check -s exit:1 -e 'inline:Usage: humanize [-bd] number\n' ../cmd/humanize
+ atf_check -s exit:1 -e 'inline:Usage: humanize [-bdt] number\n' ../cmd/humanize
}
atf_test_case badflag
badflag_body() {
- atf_check -s exit:1 -e "inline:humanize: Error: Unrecognised option: '-f'\n"'Usage: humanize [-bd] number\n' ../cmd/humanize -f
- atf_check -s exit:1 -e "inline:humanize: Error: Unrecognised option: '-f'\n"'Usage: humanize [-bd] number\n' ../cmd/humanize -f 123
+ atf_check -s exit:1 -e "inline:humanize: Error: Unrecognised option: '-f'\n"'Usage: humanize [-bdt] number\n' ../cmd/humanize -f
+ atf_check -s exit:1 -e "inline:humanize: Error: Unrecognised option: '-f'\n"'Usage: humanize [-bdt] number\n' ../cmd/humanize -f 123
+}
+
+atf_test_case duration
+duration_body() {
+ atf_check -o "inline:1s\n" ../cmd/humanize -t 1
+ atf_check -o "inline:1m \n" ../cmd/humanize -t 60
+ atf_check -o "inline:1h \n" ../cmd/humanize -t 3600
+ atf_check -o "inline:1日 \n" ../cmd/humanize -t 86400
+ atf_check -o "inline:1月 \n" ../cmd/humanize -t 2629743
+ atf_check -o "inline:1年 \n" ../cmd/humanize -t 31556926
+ atf_check -o "inline:1年 1月 1日 1h 1m 1s\n" ../cmd/humanize -t 34276730
}
atf_test_case limits
@@ -91,4 +102,6 @@ atf_init_test_cases() {
atf_add_test_case five
atf_add_test_case six
atf_add_test_case seven
+
+ atf_add_test_case duration
}