diff options
| author | Ada Christine <adachristine18@gmail.com> | 2022-02-06 16:31:19 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2022-02-06 16:31:19 +0000 |
| commit | 2067ca185220348b70b35c96e175dfb87cc05592 (patch) | |
| tree | 860578e275ec43cef12f4bfb355d258b918ea135 | |
| parent | 7b91c46a8ebf38b2c1c80c1f1e63c4d4dfd10640 (diff) | |
we have kprintf()
| -rw-r--r-- | api/kc/lib.h | 1 | ||||
| -rw-r--r-- | kc/core/Makefile | 2 | ||||
| -rw-r--r-- | kc/core/kprint.c | 131 | ||||
| -rw-r--r-- | kc/core/kprint.h | 4 | ||||
| -rw-r--r-- | lib/string.c | 11 |
5 files changed, 147 insertions, 2 deletions
diff --git a/api/kc/lib.h b/api/kc/lib.h index 5467fc0..3bf0eca 100644 --- a/api/kc/lib.h +++ b/api/kc/lib.h @@ -6,4 +6,5 @@ void *memcpy(void *dest, const void *src, size_t size); void *memmove(void *dest, const void *src, size_t size); void *memset(void *dest, int val, size_t size); int memcmp(const void *str1, const void *str2, size_t count); +size_t strlen(const char *s); diff --git a/kc/core/Makefile b/kc/core/Makefile index b0f4035..6874179 100644 --- a/kc/core/Makefile +++ b/kc/core/Makefile @@ -13,7 +13,7 @@ SOBJS := GOBJS := entry_x86_64.o reloc_x86_64.o kprint.o serial.o port.o \ kc_main.o 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 \ - kcc_memory.o + kcc_memory.o string.o IOBJS := # __attribute__((interrupt)) requires -mgeneral-regs-only diff --git a/kc/core/kprint.c b/kc/core/kprint.c index 2f4da01..596d110 100644 --- a/kc/core/kprint.c +++ b/kc/core/kprint.c @@ -1,7 +1,9 @@ #include "kprint.h" #include "serial.h" -#include <stdarg.h> +#include <kc/lib.h> + +#include <stdint.h> __attribute__((optimize("O3"))) int kputchar(int c) @@ -20,3 +22,130 @@ int kputs(const char *s) return 0; } +static char *convert_scalar( + uint64_t value, + unsigned base, + char *buffer, + size_t bufsz) +{ + static const char *stringdigits = "0123456789abcdef"; + + // the string will be built from the lower-to-higher value, and the + // result pointer will point to the first character of the string in + // the supplied buffer + + // gotta zero the buffer + memset(buffer, 0, bufsz); + + // the string is being built backwards, so the pointer needs to be + // at the last byte of the string + char *result = buffer + bufsz - 1; + + // result >= buffer condition ensures we don't overflow + + while (value > 0 && result >= buffer) + { + *--result = stringdigits[value % base]; + value /= base; + } + + return result; +} + +int kvprintf(const char *restrict format, va_list arguments) +{ + int count = 0; + + while (*format) + { + if (*format != '%') + { + kputchar(*format++); + count++; + continue; + } + + switch (*++format) + { + case 0: + return count; + case '%': + count++; + kputchar('%'); + break; + case 's': + { + const char *s = va_arg(arguments, const char *); + count += strlen(s); + kputs(s); + break; + } + + case 'x': + { + char buffer[65]; + char *s = convert_scalar( + va_arg(arguments, uint64_t), + 16, + buffer, + sizeof(buffer)); + count += strlen(s); + kputs(s); + break; + } + case 'd': + { + char buffer[65]; + char *s = convert_scalar( + va_arg(arguments, uint64_t), + 10, + buffer, + sizeof(buffer)); + count += strlen(s); + kputs(s); + break; + } + case 'o': + { + char buffer[65]; + char *s = convert_scalar( + va_arg(arguments, uint64_t), + 8, + buffer, + sizeof(buffer)); + count += strlen(s); + kputs(s); + break; + } + case 'b': + { + char buffer[65]; + char *s = convert_scalar( + va_arg(arguments, uint64_t), + 2, + buffer, + sizeof(buffer)); + count += strlen(s); + kputs(s); + break; + } + + default: + break; + } + + format++; + } + + va_end(arguments); + return count; +} + +int kprintf(const char *restrict format, ...) +{ + va_list arguments; + va_start (arguments, format); + + return kvprintf(format, arguments); +} + diff --git a/kc/core/kprint.h b/kc/core/kprint.h index 5b307a2..0c547ea 100644 --- a/kc/core/kprint.h +++ b/kc/core/kprint.h @@ -1,5 +1,9 @@ #pragma once +#include <stdarg.h> + int kputchar(int c); int kputs(const char *s); +int kprintf(const char *restrict format, ...); +int kvprintf(const char *restrict format, va_list arguments); diff --git a/lib/string.c b/lib/string.c new file mode 100644 index 0000000..968467e --- /dev/null +++ b/lib/string.c @@ -0,0 +1,11 @@ +#include <kc/lib.h> + +size_t strlen(const char *s) +{ + size_t l = 0; + + while (*s++) l++; + + return l; +} + |
