#include <sys_defs.h>
#include <msg.h>
#include <format_tv.h>
#define MILLION 1000000
VSTRING *format_tv(VSTRING *buf, int sec, int usec,
int sig_dig, int max_dig)
{
static int pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000};
int n;
int rem;
int wid;
int ures;
if (max_dig < 0 || max_dig > 6)
msg_panic("format_tv: bad maximum decimal count %d", max_dig);
if (sec < 0 || usec < 0 || usec > MILLION)
msg_panic("format_tv: bad time %ds %dus", sec, usec);
if (sig_dig < 1 || sig_dig > 6)
msg_panic("format_tv: bad significant decimal count %d", sig_dig);
ures = MILLION / pow10[max_dig];
wid = pow10[sig_dig];
if (ures < MILLION) {
if (sec > 0) {
for (n = 1; sec >= n && n <= wid / 10; n *= 10)
;
ures = (MILLION / wid) * n;
} else {
while (usec >= wid * ures)
ures *= 10;
}
}
if (ures > 1) {
usec += ures / 2;
if (usec >= MILLION) {
sec += 1;
usec -= MILLION;
}
}
vstring_sprintf_append(buf, "%d", sec);
if (usec >= ures) {
VSTRING_ADDCH(buf, '.');
for (rem = usec, n = MILLION / 10; rem >= ures && n > 0; n /= 10) {
VSTRING_ADDCH(buf, "0123456789"[rem / n]);
rem %= n;
}
}
VSTRING_TERMINATE(buf);
return (buf);
}
#ifdef TEST
#include <stdio.h>
#include <stdlib.h>
#include <vstring_vstream.h>
int main(int argc, char **argv)
{
VSTRING *in = vstring_alloc(10);
VSTRING *out = vstring_alloc(10);
double tval;
int sec;
int usec;
int sig_dig;
int max_dig;
while (vstring_get_nonl(in, VSTREAM_IN) > 0) {
vstream_printf(">> %s\n", vstring_str(in));
if (vstring_str(in)[0] == 0 || vstring_str(in)[0] == '#')
continue;
if (sscanf(vstring_str(in), "%lf %d %d", &tval, &sig_dig, &max_dig) != 3)
msg_fatal("bad input: %s", vstring_str(in));
sec = (int) tval;
usec = (tval - sec) * MILLION;
VSTRING_RESET(out);
format_tv(out, sec, usec, sig_dig, max_dig);
vstream_printf("%s\n", vstring_str(out));
vstream_fflush(VSTREAM_OUT);
}
vstring_free(in);
vstring_free(out);
return (0);
}
#endif