diff --git a/luna/Format.h b/luna/Format.h index f3c38144..10f43c30 100644 --- a/luna/Format.h +++ b/luna/Format.h @@ -10,7 +10,7 @@ typedef int (*callback_t)(char, void*); extern "C" usize strlen(const char*); -typedef usize flags_t; +typedef int flags_t; #define FLAG_ZERO_PAD 1 << 0 #define FLAG_LEFT_ALIGN 1 << 1 #define FLAG_BLANK_SIGNED 1 << 2 @@ -224,6 +224,7 @@ static int output_integer(char specifier, conv_state& vstate, format_state& stat switch (specifier) { + case 'p': case 'x': case 'X': base = 16; break; case 'o': base = 8; break; @@ -291,6 +292,8 @@ static int va_output_integer(char specifier, conv_state& vstate, format_state& s if (specifier == 'd' || specifier == 'i') is_signed = true; + if (!is_signed) vstate.flags &= ~(FLAG_SIGN | FLAG_BLANK_SIGNED); + if (vstate.flags & FLAG_CHAR) { if (is_signed) @@ -404,6 +407,12 @@ isize cstyle_format(const char* format, callback_t callback, void* arg, va_list format++; + if (*format == '%') + { + TRY_PUTCHAR('%', state); + continue; + } + // %[flags][width][.precision][length]conversion flags_t flags = parse_flags(&format); @@ -419,6 +428,22 @@ isize cstyle_format(const char* format, callback_t callback, void* arg, va_list if (is_integer_format_specifier(specifier)) { if (va_output_integer(specifier, vstate, state, ap)) return -1; + continue; + } + else if (specifier == 'p') + { + void* ptr = va_arg(ap, void*); + if (ptr == nullptr) + { + TRY_START_PAD(vstate, state, 5); + TRY_PUTS("(nil)", state); + TRY_END_PAD(vstate, state, 5); + continue; + } + vstate.width = (sizeof(void*) * 2) + 2; + vstate.flags |= (FLAG_ZERO_PAD | FLAG_ALTERNATE); + if (output_integer('p', vstate, state, (usize)ptr, false)) return -1; + continue; } else if (specifier == 'c') {