diff options
author | Anton Kling <anton@kling.gg> | 2023-10-30 22:12:14 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-10-31 00:18:38 +0100 |
commit | 8a9208612eec8ddae4c418485d848ecfa0613699 (patch) | |
tree | 2f4b29200c2f0c19ae52f45bdb9b38a41b356e30 /kernel/libc/stdio | |
parent | ca76600acc8bf7a02346efa5bd8f17072210ec01 (diff) |
Meta: Move kernel and userland to their own folders.
This is to allow both the kernel and the userland to share certain
header files and to make the folder structure a bit more clear.
Diffstat (limited to 'kernel/libc/stdio')
-rw-r--r-- | kernel/libc/stdio/print.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/kernel/libc/stdio/print.c b/kernel/libc/stdio/print.c new file mode 100644 index 0000000..8174983 --- /dev/null +++ b/kernel/libc/stdio/print.c @@ -0,0 +1,97 @@ +#include "../../drivers/serial.h" +#include "../include/assert.h" +#include "../include/stdio.h" +#include <stdarg.h> + +#define TAB_SIZE 8 + +const char HEX_SET[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +inline void putc(const char c) { write_serial(c); } + +int kprint_hex(uint64_t num) { + int c = 2; + + if (num == 0) { + putc('0'); + c++; + return c; + } + + char str[16] = {0}; + int i = 0; + for (; num != 0 && i < 16; i++, num /= 16) + str[i] = HEX_SET[(num % 16)]; + + c += i; + for (i--; i >= 0; i--) + putc(str[i]); + + return c; +} + +int kprint_int(int num) { + int c = 0; + if (0 == num) { + putc('0'); + c++; + return c; + } + char str[10]; + int i = 0; + for (; num != 0 && i < 10; i++, num /= 10) + str[i] = (num % 10) + '0'; + + c += i; + for (i--; i >= 0; i--) + putc(str[i]); + return c; +} + +int kprintf(const char *format, ...) { + int c = 0; + va_list list; + va_start(list, format); + + const char *s = format; + for (; *s; s++) { + if ('%' != *s) { + putc(*s); + c++; + continue; + } + + char flag = *(s + 1); + if ('\0' == flag) + break; + + switch (flag) { + case 'c': + putc((char)va_arg(list, int)); + c++; + break; + case 'd': + c += kprint_int(va_arg(list, int)); + break; + case 's': + for (char *string = va_arg(list, char *); *string; putc(*string++), c++) + ; + break; + case 'x': + c += kprint_hex(va_arg(list, const uint32_t)); + break; + case '%': + putc('%'); + c++; + break; + default: + ASSERT_NOT_REACHED; + break; + } + s++; + } + return c; +} + +int puts(char *str) { return kprintf("%s\n", str); } |