Support printing some integers in output_integer
This commit is contained in:
parent
603ff46d8c
commit
4ebf244d3b
@ -26,6 +26,8 @@ extern "C" [[noreturn]] void _start()
|
|||||||
|
|
||||||
const u64 address = 0xfffffffff8000000;
|
const u64 address = 0xfffffffff8000000;
|
||||||
|
|
||||||
|
Serial::printf("Mapping address 0x%lx\n", address);
|
||||||
|
|
||||||
u64 physical = MemoryManager::alloc_physical_page().release_value();
|
u64 physical = MemoryManager::alloc_physical_page().release_value();
|
||||||
|
|
||||||
auto rc = MMU::map(address, physical, MMU::ReadWrite);
|
auto rc = MMU::map(address, physical, MMU::ReadWrite);
|
||||||
|
147
luna/Format.h
147
luna/Format.h
@ -200,9 +200,152 @@ static bool is_integer_format_specifier(char c)
|
|||||||
return (c == 'd') || (c == 'i') || (c == 'u') || (c == 'x') || (c == 'X') || (c == 'o') || (c == 'b');
|
return (c == 'd') || (c == 'i') || (c == 'u') || (c == 'x') || (c == 'X') || (c == 'o') || (c == 'b');
|
||||||
}
|
}
|
||||||
|
|
||||||
static int output_integer(char, const conv_state&, format_state&, va_list)
|
template <typename T> static usize to_string(T value, T base, char* buf, usize max, bool uppercase)
|
||||||
{
|
{
|
||||||
return -1; // FIXME: Implement this.
|
usize i = 0;
|
||||||
|
if (!value && max)
|
||||||
|
{
|
||||||
|
buf[i] = '0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
int digit = (int)(value % base);
|
||||||
|
char c = (char)(digit < 10 ? '0' + digit : ((uppercase ? 'A' : 'a') + (digit - 10)));
|
||||||
|
buf[i++] = c;
|
||||||
|
value /= base;
|
||||||
|
} while (value && i < max);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int output_integer(char specifier, const conv_state& vstate, format_state& state, va_list ap)
|
||||||
|
{
|
||||||
|
usize base = 10;
|
||||||
|
bool is_signed = false;
|
||||||
|
bool uppercase = false;
|
||||||
|
bool negative = false;
|
||||||
|
|
||||||
|
if (specifier == 'd' || specifier == 'i') is_signed = true;
|
||||||
|
switch (specifier)
|
||||||
|
{
|
||||||
|
case 'x':
|
||||||
|
case 'X': base = 16; break;
|
||||||
|
case 'o': base = 8; break;
|
||||||
|
case 'b': base = 2; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (specifier == 'X') uppercase = true;
|
||||||
|
|
||||||
|
char buf[1024];
|
||||||
|
usize buflen;
|
||||||
|
if (vstate.flags & FLAG_CHAR)
|
||||||
|
{
|
||||||
|
if (is_signed)
|
||||||
|
{
|
||||||
|
char v = (char)va_arg(ap, int);
|
||||||
|
if (v < 0)
|
||||||
|
{
|
||||||
|
v = -v;
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
buflen = to_string(v, (char)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char v = (unsigned char)va_arg(ap, unsigned int);
|
||||||
|
buflen = to_string(v, (unsigned char)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vstate.flags & FLAG_SHORT)
|
||||||
|
{
|
||||||
|
if (is_signed)
|
||||||
|
{
|
||||||
|
short v = (short)va_arg(ap, int);
|
||||||
|
if (v < 0)
|
||||||
|
{
|
||||||
|
v = -v;
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
buflen = to_string(v, (short)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned short v = (unsigned short)va_arg(ap, unsigned int);
|
||||||
|
buflen = to_string(v, (unsigned short)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vstate.flags & FLAG_LONG_LONG)
|
||||||
|
{
|
||||||
|
if (is_signed)
|
||||||
|
{
|
||||||
|
long long v = va_arg(ap, long long);
|
||||||
|
if (v < 0)
|
||||||
|
{
|
||||||
|
v = -v;
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
buflen = to_string(v, (long long)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned long long v = va_arg(ap, unsigned long long);
|
||||||
|
buflen = to_string(v, (unsigned long long)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vstate.flags & FLAG_LONG)
|
||||||
|
{
|
||||||
|
if (is_signed)
|
||||||
|
{
|
||||||
|
long v = va_arg(ap, long);
|
||||||
|
if (v < 0)
|
||||||
|
{
|
||||||
|
v = -v;
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
buflen = to_string(v, (long)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned long v = va_arg(ap, unsigned long);
|
||||||
|
buflen = to_string(v, (unsigned long)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (is_signed)
|
||||||
|
{
|
||||||
|
int v = va_arg(ap, int);
|
||||||
|
if (v < 0)
|
||||||
|
{
|
||||||
|
v = -v;
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
buflen = to_string(v, (int)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int v = va_arg(ap, unsigned int);
|
||||||
|
buflen = to_string(v, (unsigned int)base, buf, sizeof(buf), uppercase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Start padding and alternate forms.
|
||||||
|
|
||||||
|
if (buflen < sizeof(buf))
|
||||||
|
{
|
||||||
|
if (negative) buf[buflen++] = '-';
|
||||||
|
else if (vstate.flags & FLAG_SIGN)
|
||||||
|
buf[buflen++] = '+';
|
||||||
|
else if (vstate.flags & FLAG_BLANK_SIGNED)
|
||||||
|
buf[buflen++] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
usize i = buflen;
|
||||||
|
|
||||||
|
while (i--) TRY_PUTCHAR(buf[i], state);
|
||||||
|
|
||||||
|
TRY_END_PAD(vstate, state, buflen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user