#include #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); }