diff options
| author | Ada Christine <adachristine18@gmail.com> | 2022-03-14 21:02:34 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2022-03-14 21:03:32 +0000 |
| commit | b2ac5414eb418fa3cd34c0c73863661df7b2f984 (patch) | |
| tree | 8c0e2c68f27ae3dc4b2ba38f87c4b0b024a8934f /kc/core | |
| parent | 73e5768d3a159b2e9b554fa5396a759f3d283c6c (diff) | |
kprintf() can do zero padded integers now
Squash me
Diffstat (limited to 'kc/core')
| -rw-r--r-- | kc/core/Makefile | 2 | ||||
| -rw-r--r-- | kc/core/kprint.c | 91 |
2 files changed, 87 insertions, 6 deletions
diff --git a/kc/core/Makefile b/kc/core/Makefile index 9b8983a..2c7303e 100644 --- a/kc/core/Makefile +++ b/kc/core/Makefile @@ -14,7 +14,7 @@ GOBJS := entry_x86_64.o reloc_x86_64.o kprint.o serial.o port.o mmu.o \ kc_main.o memory.o memset.o memcpy.o memmove.o memcmp.o cpu.o \ vm_tree.o exceptions.o panic.o msr.o task.o cpu_task.o irq.o \ kcc_memory.o string.o pic8259.o pic8259_isr.o pit8253.o \ - page_early.o page_stack.o + page_early.o page_stack.o strtoull.o IOBJS := # __attribute__((interrupt)) requires -mgeneral-regs-only diff --git a/kc/core/kprint.c b/kc/core/kprint.c index 762f99f..4acbddd 100644 --- a/kc/core/kprint.c +++ b/kc/core/kprint.c @@ -82,7 +82,6 @@ struct specifier static struct specifier parse_specifier(const char *format, va_list *arguments) { - (void)arguments; struct specifier result = { INVALID_PRINT, @@ -150,6 +149,76 @@ static struct specifier parse_specifier(const char *format, va_list *arguments) * b. if is numeric character, parse field precision via strtoul, add * length of numeric string to begin. */ + bool field_width_parsed = false; + bool field_precision_parsed = false; + + while (!field_width_parsed || !field_precision_parsed) + { + switch (*begin) + { + case '.': + if (!field_width_parsed) + { + result.field_width = 0; + field_width_parsed = true; + begin++; + } + else + { + // the specifier is invalid! + result.type = INVALID_PRINT; + } + break; + case '*': + { + int w = *va_arg(*arguments, int *); + if (!field_width_parsed) + { + result.field_width = w; + field_width_parsed = true; + } + else + { + result.field_precision = w; + field_precision_parsed = true; + } + begin++; + } + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '0': + { + char *next; + unsigned long long w = strtoull(begin, &next, 10); + if (!field_width_parsed) + { + result.field_width = (int)w; + field_width_parsed = true; + } + else if (!field_precision_parsed) + { + result.field_precision = (int)w; + field_precision_parsed = true; + } + if (next > begin) + { + begin = next; + } + } + break; + default: + field_width_parsed = true; + field_precision_parsed = true; + } + } // step 3: check for type width arguments switch (*begin) @@ -245,7 +314,7 @@ static struct specifier parse_specifier(const char *format, va_list *arguments) // TODO: use UINTPTR_T_WIDTH here? // pointer type overrides all flags // i can do what i want it says "implementation-defined" in the spec - result.field_precision = 8; + result.field_precision = 16; result.type = INTEGER_PRINT; result.integer_base = HEX_BASE; result.integer_width = LONG_WIDTH; @@ -277,8 +346,9 @@ static struct specifier parse_specifier(const char *format, va_list *arguments) static char *convert_integer( uint64_t value, - unsigned base, - char *buffer, + unsigned base, + int zpadding, + char *buffer, size_t bufsz) { static const char *stringdigits = "0123456789abcdef"; @@ -304,10 +374,16 @@ static char *convert_integer( do { *--result = stringdigits[value % base]; + zpadding--; value /= base; } while (value > 0 && result >= buffer); + while (zpadding-- > 0 && result >= buffer) + { + *--result = '0'; + } + return result; } @@ -361,6 +437,7 @@ static int print_integer( bool negative = false; uint64_t value = 0; int r = 0; + unsigned zpad = 0; switch (spec->integer_width) { @@ -429,7 +506,11 @@ static int print_integer( break; } - s = convert_integer(value, spec->integer_base, buffer, sizeof(buffer)); + if (spec->flags & ZERO_PAD_FLAG) + { + zpad = spec->field_precision; + } + s = convert_integer(value, spec->integer_base, zpad, buffer, sizeof(buffer)); if (s) { |
