Printf: Add support for microsecond times

Use '%t' in bsnprintf() for microsecond times (in btime) with variable
sub-second precision.
This commit is contained in:
Ondrej Zajicek (work) 2017-06-13 15:41:49 +02:00
parent f047271cb9
commit 49fc021337
2 changed files with 60 additions and 4 deletions

View file

@ -125,9 +125,10 @@ static char * number(char * str, long num, int base, int size, int precision,
* or |%I6| can be used for explicit ip4_addr / ip6_addr arguments, |%N| for
* generic network addresses (net_addr *), |%R| for Router / Network ID (u32
* value printed as IPv4 address), |%lR| for 64bit Router / Network ID (u64
* value printed as eight :-separated octets) and |%m| resp. |%M| for error
* messages (uses strerror() to translate @errno code to message text). On the
* other hand, it doesn't support floating point numbers.
* value printed as eight :-separated octets), |%t| for time values (btime) with
* specified subsecond precision, and |%m| resp. |%M| for error messages (uses
* strerror() to translate @errno code to message text). On the other hand, it
* doesn't support floating point numbers.
*
* Result: number of characters of the output string or -1 if
* the buffer space was insufficient.
@ -139,6 +140,8 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
int i, base;
u32 x;
u64 X;
btime t;
s64 t1, t2;
char *str, *start;
const char *s;
char ipbuf[NET_MAX_TEXT_LENGTH+1];
@ -279,7 +282,6 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
return -1;
continue;
case 'n':
if (qualifier == 'l') {
long * ip = va_arg(args, long *);
@ -360,6 +362,50 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
s = ipbuf;
goto str;
case 't':
t = va_arg(args, btime);
t1 = t TO_S;
t2 = t - t1 S;
if (precision < 0)
precision = 3;
if (precision > 6)
precision = 6;
/* Compute field_width for second part */
if ((precision > 0) && (field_width > 0))
field_width -= (1 + precision);
if (field_width < 0)
field_width = 0;
/* Print seconds */
flags |= SIGN;
str = number(str, t1, 10, field_width, 0, flags, size);
if (!str)
return -1;
if (precision > 0)
{
size -= (str-start);
start = str;
if ((1 + precision) > size)
return -1;
/* Convert microseconds to requested precision */
for (i = precision; i < 6; i++)
t2 /= 10;
/* Print sub-seconds */
*str++ = '.';
str = number(str, t2, 10, precision, 0, ZEROPAD, size - 1);
if (!str)
return -1;
}
goto done;
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
@ -401,6 +447,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
str = number(str, num, base, field_width, precision, flags, size);
if (!str)
return -1;
done: ;
}
if (!size)
return -1;

View file

@ -56,6 +56,15 @@ t_simple(void)
BSPRINTF(2, "-1", buf, "%d", -1);
BSPRINTF(11, "-2147483648", buf, "%d", -2147483648);
BSPRINTF(7, "123.456", buf, "%t", (btime) 123456789);
BSPRINTF(7, "123.456", buf, "%2t", (btime) 123456789);
BSPRINTF(8, " 123.456", buf, "%8t", (btime) 123456789);
BSPRINTF(4, " 123", buf, "%4.0t", (btime) 123456789);
BSPRINTF(8, "123.4567", buf, "%8.4t", (btime) 123456789);
BSPRINTF(9, "0123.4567", buf, "%09.4t", (btime) 123456789);
BSPRINTF(12, " 123.456789", buf, "%12.10t", (btime) 123456789);
BSPRINTF(8, " 123.004", buf, "%8t", (btime) 123004 MS);
return 1;
}