1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include <unistd.h>
#include "buffer.h"
#include "exit.h"
#include "fmt.h"
#include "getln.h"
#include "open.h"
#include "scan.h"
#include "stralloc.h"
#define TAI64NLEN 24
/**
@file tai64nfrac
@brief Read a TAI64N external format timestamp from stdin and
write fractional seconds since epoch (TAI, not UTC) to stdout.
Return the characters after the timestamp.
*/
char outbuf[64];
buffer bo = BUFFER_INIT(write, 1, outbuf, sizeof(outbuf));
static void outs(char *s)
{
if (buffer_puts(&bo, s) == -1) _exit(1);
if (buffer_flush(&bo) == -1) _exit(1);
}
static void outi(int i)
{
char num[FMT_ULONG];
if (buffer_put(&bo, num, fmt_ulong(num, (unsigned long)i)) == -1) _exit(1);
if (buffer_flush(&bo) == -1) _exit(1);
}
char inbuf[1024];
buffer bi = BUFFER_INIT(read, 0, inbuf, sizeof(inbuf));
int main(void)
{
int c;
int i;
int match;
unsigned long u;
unsigned long seconds;
unsigned long nanoseconds;
stralloc line = {0};
/* Read from stdin */
buffer_init(&bi, read, 0, inbuf, sizeof(inbuf));
for (;;) {
if (getln(&bi, &line, &match, '\n') != 0) _exit(1);
if (!match) break;
if (!stralloc_0(&line)) _exit(1);
seconds = 0;
nanoseconds = 0;
if (line.s[0] == '@') { /* tai64 timestamp */
for (i = 1; i <= TAI64NLEN; i++) {
c = (int)line.s[i];
u = c - '0';
if (u >= 10) {
u = c - 'a';
if (u >= 6) break;
u += 10;
}
seconds <<= 4;
seconds += nanoseconds >> 28;
nanoseconds &= 0xfffffff;
nanoseconds <<= 4;
nanoseconds += u;
}
seconds -= 4611686018427387914ULL;
seconds = seconds > 0 ? seconds : 0;
outi(seconds);
outs(".");
outi(nanoseconds);
outs(line.s + i);
outs("\n");
} else {
outs("tai64nfrac: fatal: Wrong TAI64N input format.");
outs("\n");
_exit(1);
}
}
_exit(0);
}
|