add 64-bit formatting support
This commit is contained in:
parent
fa4ff5facf
commit
cbd427b14b
129
src/hos_printf.c
129
src/hos_printf.c
@ -3,7 +3,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
static size_t format_dec(char * buffer, int v)
|
static size_t format_dec(char * buffer, int32_t v)
|
||||||
{
|
{
|
||||||
size_t sz = 0u;
|
size_t sz = 0u;
|
||||||
bool printing = false;
|
bool printing = false;
|
||||||
@ -12,9 +12,9 @@ static size_t format_dec(char * buffer, int v)
|
|||||||
buffer[sz++] = '-';
|
buffer[sz++] = '-';
|
||||||
v = -v;
|
v = -v;
|
||||||
}
|
}
|
||||||
for (int div = 1000000000; div >= 1; div /= 10)
|
for (int32_t div = 1000000000; div >= 1; div /= 10)
|
||||||
{
|
{
|
||||||
int digit = v / div;
|
int32_t digit = v / div;
|
||||||
v %= div;
|
v %= div;
|
||||||
if ((digit != 0) || (div == 1))
|
if ((digit != 0) || (div == 1))
|
||||||
{
|
{
|
||||||
@ -28,12 +28,37 @@ static size_t format_dec(char * buffer, int v)
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t format_udec(char * buffer, unsigned int v)
|
static size_t format_dec64(char * buffer, int64_t v)
|
||||||
{
|
{
|
||||||
size_t sz = 0u;
|
size_t sz = 0u;
|
||||||
for (unsigned int div = 1000000000u; div >= 1u; div /= 10u)
|
bool printing = false;
|
||||||
|
if (v < 0)
|
||||||
{
|
{
|
||||||
unsigned int digit = v / div;
|
buffer[sz++] = '-';
|
||||||
|
v = -v;
|
||||||
|
}
|
||||||
|
for (int64_t div = 1000000000000000000; div >= 1; div /= 10)
|
||||||
|
{
|
||||||
|
int64_t digit = v / div;
|
||||||
|
v %= div;
|
||||||
|
if ((digit != 0) || (div == 1))
|
||||||
|
{
|
||||||
|
printing = true;
|
||||||
|
}
|
||||||
|
if (printing)
|
||||||
|
{
|
||||||
|
buffer[sz++] = digit + '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t format_udec(char * buffer, int32_t v)
|
||||||
|
{
|
||||||
|
size_t sz = 0u;
|
||||||
|
for (int32_t div = 1000000000u; div >= 1u; div /= 10u)
|
||||||
|
{
|
||||||
|
int32_t digit = v / div;
|
||||||
v %= div;
|
v %= div;
|
||||||
if ((digit != 0) || (sz > 0u) || (div == 1))
|
if ((digit != 0) || (sz > 0u) || (div == 1))
|
||||||
{
|
{
|
||||||
@ -43,7 +68,22 @@ static size_t format_udec(char * buffer, unsigned int v)
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t format_hex(char * buffer, int v, bool upper)
|
static size_t format_udec64(char * buffer, uint64_t v)
|
||||||
|
{
|
||||||
|
size_t sz = 0u;
|
||||||
|
for (uint64_t div = 10000000000000000000u; div >= 1u; div /= 10u)
|
||||||
|
{
|
||||||
|
uint64_t digit = v / div;
|
||||||
|
v %= div;
|
||||||
|
if ((digit != 0) || (sz > 0u) || (div == 1))
|
||||||
|
{
|
||||||
|
buffer[sz++] = digit + '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t format_hex(char * buffer, uint32_t v, bool upper)
|
||||||
{
|
{
|
||||||
const char upper_hex[] = "0123456789ABCDEF";
|
const char upper_hex[] = "0123456789ABCDEF";
|
||||||
const char lower_hex[] = "0123456789abcdef";
|
const char lower_hex[] = "0123456789abcdef";
|
||||||
@ -60,6 +100,23 @@ static size_t format_hex(char * buffer, int v, bool upper)
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t format_hex64(char * buffer, uint64_t v, bool upper)
|
||||||
|
{
|
||||||
|
const char upper_hex[] = "0123456789ABCDEF";
|
||||||
|
const char lower_hex[] = "0123456789abcdef";
|
||||||
|
size_t sz = 0u;
|
||||||
|
for (int i = 60; i >= 0; i -= 4)
|
||||||
|
{
|
||||||
|
uint8_t n = (v >> i) & 0xFu;
|
||||||
|
if ((sz > 0u) || (n != 0u) || (i == 0))
|
||||||
|
{
|
||||||
|
buffer[sz] = upper ? upper_hex[n] : lower_hex[n];
|
||||||
|
sz++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
static void pad_write(const stream_t * stream, const char * data, size_t length, bool leading_zero, bool left_just, size_t width)
|
static void pad_write(const stream_t * stream, const char * data, size_t length, bool leading_zero, bool left_just, size_t width)
|
||||||
{
|
{
|
||||||
if (left_just)
|
if (left_just)
|
||||||
@ -88,10 +145,12 @@ void hos_vprintf(const stream_t * stream, const char * fmt, va_list va)
|
|||||||
{
|
{
|
||||||
bool in_conv = false;
|
bool in_conv = false;
|
||||||
char c;
|
char c;
|
||||||
char buffer[12];
|
char buffer[22];
|
||||||
size_t width;
|
size_t width;
|
||||||
bool leading_zero;
|
bool leading_zero;
|
||||||
bool left_just;
|
bool left_just;
|
||||||
|
bool long_flag;
|
||||||
|
size_t length;
|
||||||
while ((c = *fmt))
|
while ((c = *fmt))
|
||||||
{
|
{
|
||||||
if (in_conv)
|
if (in_conv)
|
||||||
@ -103,8 +162,16 @@ void hos_vprintf(const stream_t * stream, const char * fmt, va_list va)
|
|||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
{
|
{
|
||||||
unsigned int v = va_arg(va, unsigned int);
|
if (long_flag)
|
||||||
size_t length = format_hex(buffer, v, true);
|
{
|
||||||
|
uint64_t v = va_arg(va, uint64_t);
|
||||||
|
length = format_hex(buffer, v, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t v = va_arg(va, uint32_t);
|
||||||
|
length = format_hex(buffer, v, true);
|
||||||
|
}
|
||||||
pad_write(stream, buffer, length, leading_zero, left_just, width);
|
pad_write(stream, buffer, length, leading_zero, left_just, width);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -116,8 +183,16 @@ void hos_vprintf(const stream_t * stream, const char * fmt, va_list va)
|
|||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
int v = va_arg(va, int);
|
if (long_flag)
|
||||||
size_t length = format_dec(buffer, v);
|
{
|
||||||
|
int64_t v = va_arg(va, int64_t);
|
||||||
|
length = format_dec64(buffer, v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32_t v = va_arg(va, int32_t);
|
||||||
|
length = format_dec(buffer, v);
|
||||||
|
}
|
||||||
pad_write(stream, buffer, length, leading_zero, left_just, width);
|
pad_write(stream, buffer, length, leading_zero, left_just, width);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -129,15 +204,31 @@ void hos_vprintf(const stream_t * stream, const char * fmt, va_list va)
|
|||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
{
|
{
|
||||||
unsigned int v = va_arg(va, unsigned int);
|
if (long_flag)
|
||||||
size_t length = format_udec(buffer, v);
|
{
|
||||||
|
uint64_t v = va_arg(va, uint64_t);
|
||||||
|
length = format_udec64(buffer, v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t v = va_arg(va, uint32_t);
|
||||||
|
length = format_udec(buffer, v);
|
||||||
|
}
|
||||||
pad_write(stream, buffer, length, leading_zero, left_just, width);
|
pad_write(stream, buffer, length, leading_zero, left_just, width);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
{
|
{
|
||||||
unsigned int v = va_arg(va, unsigned int);
|
if (long_flag)
|
||||||
size_t length = format_hex(buffer, v, false);
|
{
|
||||||
|
uint64_t v = va_arg(va, uint64_t);
|
||||||
|
length = format_hex64(buffer, v, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t v = va_arg(va, uint32_t);
|
||||||
|
length = format_hex(buffer, v, false);
|
||||||
|
}
|
||||||
pad_write(stream, buffer, length, leading_zero, left_just, width);
|
pad_write(stream, buffer, length, leading_zero, left_just, width);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -150,6 +241,7 @@ void hos_vprintf(const stream_t * stream, const char * fmt, va_list va)
|
|||||||
width = 0u;
|
width = 0u;
|
||||||
leading_zero = false;
|
leading_zero = false;
|
||||||
left_just = false;
|
left_just = false;
|
||||||
|
long_flag = false;
|
||||||
if (fmt[1] == '-')
|
if (fmt[1] == '-')
|
||||||
{
|
{
|
||||||
left_just = true;
|
left_just = true;
|
||||||
@ -166,6 +258,11 @@ void hos_vprintf(const stream_t * stream, const char * fmt, va_list va)
|
|||||||
width += (fmt[1] - '0');
|
width += (fmt[1] - '0');
|
||||||
fmt++;
|
fmt++;
|
||||||
}
|
}
|
||||||
|
if (fmt[1] == 'l')
|
||||||
|
{
|
||||||
|
long_flag = true;
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user