Skip to content

Commit 2374ae0

Browse files
committed
Import format_timespan() from systemd
We also introduce a new couple of files: time-util.{c,h}. For now this is a verbatim copy from systemd c20db3887569e0c0d9c0e2845c5286e7edf0133a Signed-off-by: Arnaud Rebillout <[email protected]>
1 parent ab8de7c commit 2374ae0

File tree

3 files changed

+155
-0
lines changed

3 files changed

+155
-0
lines changed

src/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
util_sources = files('''
44
log.c
55
log.h
6+
time-util.c
7+
time-util.h
68
util.c
79
util.h
810
'''.split())

src/time-util.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/* SPDX-License-Identifier: LGPL-2.1+ */
2+
3+
#include "util.h"
4+
#include "time-util.h"
5+
6+
char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
7+
static const struct {
8+
const char *suffix;
9+
usec_t usec;
10+
} table[] = {
11+
{ "y", USEC_PER_YEAR },
12+
{ "month", USEC_PER_MONTH },
13+
{ "w", USEC_PER_WEEK },
14+
{ "d", USEC_PER_DAY },
15+
{ "h", USEC_PER_HOUR },
16+
{ "min", USEC_PER_MINUTE },
17+
{ "s", USEC_PER_SEC },
18+
{ "ms", USEC_PER_MSEC },
19+
{ "us", 1 },
20+
};
21+
22+
size_t i;
23+
char *p = buf;
24+
bool something = false;
25+
26+
assert(buf);
27+
assert(l > 0);
28+
29+
if (t == USEC_INFINITY) {
30+
strncpy(p, "infinity", l-1);
31+
p[l-1] = 0;
32+
return p;
33+
}
34+
35+
if (t <= 0) {
36+
strncpy(p, "0", l-1);
37+
p[l-1] = 0;
38+
return p;
39+
}
40+
41+
/* The result of this function can be parsed with parse_sec */
42+
43+
for (i = 0; i < ELEMENTSOF(table); i++) {
44+
int k = 0;
45+
size_t n;
46+
bool done = false;
47+
usec_t a, b;
48+
49+
if (t <= 0)
50+
break;
51+
52+
if (t < accuracy && something)
53+
break;
54+
55+
if (t < table[i].usec)
56+
continue;
57+
58+
if (l <= 1)
59+
break;
60+
61+
a = t / table[i].usec;
62+
b = t % table[i].usec;
63+
64+
/* Let's see if we should shows this in dot notation */
65+
if (t < USEC_PER_MINUTE && b > 0) {
66+
usec_t cc;
67+
signed char j;
68+
69+
j = 0;
70+
for (cc = table[i].usec; cc > 1; cc /= 10)
71+
j++;
72+
73+
for (cc = accuracy; cc > 1; cc /= 10) {
74+
b /= 10;
75+
j--;
76+
}
77+
78+
if (j > 0) {
79+
k = snprintf(p, l,
80+
"%s"USEC_FMT".%0*"PRI_USEC"%s",
81+
p > buf ? " " : "",
82+
a,
83+
j,
84+
b,
85+
table[i].suffix);
86+
87+
t = 0;
88+
done = true;
89+
}
90+
}
91+
92+
/* No? Then let's show it normally */
93+
if (!done) {
94+
k = snprintf(p, l,
95+
"%s"USEC_FMT"%s",
96+
p > buf ? " " : "",
97+
a,
98+
table[i].suffix);
99+
100+
t = b;
101+
}
102+
103+
n = MIN((size_t) k, l);
104+
105+
l -= n;
106+
p += n;
107+
108+
something = true;
109+
}
110+
111+
*p = 0;
112+
113+
return buf;
114+
}

src/time-util.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* SPDX-License-Identifier: LGPL-2.1+ */
2+
3+
#ifndef footimeutilfoo
4+
#define footimeutilfoo
5+
6+
typedef uint64_t usec_t;
7+
typedef uint64_t nsec_t;
8+
9+
#define PRI_NSEC PRIu64
10+
#define PRI_USEC PRIu64
11+
#define NSEC_FMT "%" PRI_NSEC
12+
#define USEC_FMT "%" PRI_USEC
13+
14+
#define USEC_INFINITY ((usec_t) -1)
15+
#define NSEC_INFINITY ((nsec_t) -1)
16+
17+
#define MSEC_PER_SEC 1000ULL
18+
#define USEC_PER_SEC ((usec_t) 1000000ULL)
19+
#define USEC_PER_MSEC ((usec_t) 1000ULL)
20+
//#define NSEC_PER_SEC ((nsec_t) 1000000000ULL) already defined in util.h
21+
#define NSEC_PER_MSEC ((nsec_t) 1000000ULL)
22+
#define NSEC_PER_USEC ((nsec_t) 1000ULL)
23+
24+
#define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC))
25+
#define NSEC_PER_MINUTE ((nsec_t) (60ULL*NSEC_PER_SEC))
26+
#define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE))
27+
#define NSEC_PER_HOUR ((nsec_t) (60ULL*NSEC_PER_MINUTE))
28+
#define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR))
29+
#define NSEC_PER_DAY ((nsec_t) (24ULL*NSEC_PER_HOUR))
30+
#define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY))
31+
#define NSEC_PER_WEEK ((nsec_t) (7ULL*NSEC_PER_DAY))
32+
#define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC))
33+
#define NSEC_PER_MONTH ((nsec_t) (2629800ULL*NSEC_PER_SEC))
34+
#define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC))
35+
#define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC))
36+
37+
char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy);
38+
39+
#endif

0 commit comments

Comments
 (0)