1*cf5a6c84SAndroid Build Coastguard Worker /* ts.c - timestamp input lines
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2023 Oliver Webb <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * No standard.
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Worker USE_TS(NEWTOY(ts, "ims", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LINEBUF))
8*cf5a6c84SAndroid Build Coastguard Worker
9*cf5a6c84SAndroid Build Coastguard Worker config TS
10*cf5a6c84SAndroid Build Coastguard Worker bool "ts"
11*cf5a6c84SAndroid Build Coastguard Worker default y
12*cf5a6c84SAndroid Build Coastguard Worker help
13*cf5a6c84SAndroid Build Coastguard Worker usage: ts [-is] [FORMAT]
14*cf5a6c84SAndroid Build Coastguard Worker
15*cf5a6c84SAndroid Build Coastguard Worker Add timestamps to each line in pipeline. Default format without options
16*cf5a6c84SAndroid Build Coastguard Worker "%b %d %H:%M:%S", with -i or -s "%H:%M:%S".
17*cf5a6c84SAndroid Build Coastguard Worker
18*cf5a6c84SAndroid Build Coastguard Worker -i Incremental (since previous line)
19*cf5a6c84SAndroid Build Coastguard Worker -m Add milliseconds
20*cf5a6c84SAndroid Build Coastguard Worker -s Since start
21*cf5a6c84SAndroid Build Coastguard Worker */
22*cf5a6c84SAndroid Build Coastguard Worker
23*cf5a6c84SAndroid Build Coastguard Worker #define FOR_ts
24*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
25*cf5a6c84SAndroid Build Coastguard Worker
26*cf5a6c84SAndroid Build Coastguard Worker // because millitime() is monotonic, which returns uptime.
millinow(void)27*cf5a6c84SAndroid Build Coastguard Worker static long long millinow(void)
28*cf5a6c84SAndroid Build Coastguard Worker {
29*cf5a6c84SAndroid Build Coastguard Worker struct timespec ts;
30*cf5a6c84SAndroid Build Coastguard Worker
31*cf5a6c84SAndroid Build Coastguard Worker clock_gettime(CLOCK_REALTIME, &ts);
32*cf5a6c84SAndroid Build Coastguard Worker
33*cf5a6c84SAndroid Build Coastguard Worker return ts.tv_sec*1000+ts.tv_nsec/1000000;
34*cf5a6c84SAndroid Build Coastguard Worker }
35*cf5a6c84SAndroid Build Coastguard Worker
ts_main(void)36*cf5a6c84SAndroid Build Coastguard Worker void ts_main(void)
37*cf5a6c84SAndroid Build Coastguard Worker {
38*cf5a6c84SAndroid Build Coastguard Worker char *line, *mm = toybuf+sizeof(toybuf)-8,
39*cf5a6c84SAndroid Build Coastguard Worker *format = toys.optflags ? "%T" : "%b %d %T";
40*cf5a6c84SAndroid Build Coastguard Worker long long start = millinow(), now, diff, rel = FLAG(i) || FLAG(s);
41*cf5a6c84SAndroid Build Coastguard Worker struct tm *tm;
42*cf5a6c84SAndroid Build Coastguard Worker time_t tt;
43*cf5a6c84SAndroid Build Coastguard Worker
44*cf5a6c84SAndroid Build Coastguard Worker for (; (line = xgetline(stdin)); free(line)) {
45*cf5a6c84SAndroid Build Coastguard Worker now = millinow();
46*cf5a6c84SAndroid Build Coastguard Worker diff = now - start*rel;
47*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(m)) sprintf(mm, ".%03lld", diff%1000);
48*cf5a6c84SAndroid Build Coastguard Worker tt = diff/1000;
49*cf5a6c84SAndroid Build Coastguard Worker tm = rel ? gmtime(&tt) : localtime(&tt);
50*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(i)) start = now;
51*cf5a6c84SAndroid Build Coastguard Worker strftime(toybuf, sizeof(toybuf)-16, *toys.optargs ? : format, tm);
52*cf5a6c84SAndroid Build Coastguard Worker xprintf("%s%s %s\n", toybuf, mm, line);
53*cf5a6c84SAndroid Build Coastguard Worker }
54*cf5a6c84SAndroid Build Coastguard Worker }
55